直播云

  • Android 连麦 SDK

    最近更新时间:2018-03-23 16:33:23

    1. 概述

    PLDroidRTCStreaming 是基于 PLDroidMediaStreaming 开发的一套具有连麦功能的 SDK,既可以在不影响原有推流的基础上,使用简单易用的连麦 API,快速实现直播连麦功能。也可以抛开推流模块,使用更加灵活的连麦 API,快速实现纯视频连麦互动的功能。

    1.1 最新版下载地址

    RTC_Android_v1.2.4.zip

    1.2 最新版内容提要

    [Android] 连麦 SDK v1.2.4 发布

    PLDroidRTCStreaming 是基于 PLDroidMediaStreaming 开发的一套具有连麦功能的 SDK,既可以在不影响原有推流的基础上,使用简单易用的连麦 API,快速实现直播连麦功能。也可以抛开推流模块,使用更加灵活的连麦 API,快速实现纯视频连麦互动的功能。

    版本

    • 发布了 pldroid-rtc-streaming-1.2.4.jar
    • 新增了 libpldroid_streaming_puic.so
    • 更新了 libpldroid_rtc_streaming.so
    • 更新了 libpldroid_mmprocessing.so
    • 更新了 libpldroid_streaming_core.so

    功能

    • 新增录制时动态水印功能
    • 新增连麦远端视频数据的回调
    • 新增 QUIC 推流功能,可在 StreamingProfile 中配置开启

    缺陷

    • 修复偶现的保存本地的日志被删除的问题
    • 修复金立 M7 黑屏问题
    • 修复纯音频推流 pause 后无法 resume 问题
    • 修复弱网下 pause 小概率 ANR 问题

    优化

    • 优化连麦分辨率小于推流分辨率的情况下,推流画面变模糊的问题

    更新注意事项

    • 从 v1.2.4 版本开始,增加 libpldroid_streaming_puic.so 库
    • libpldroid_streaming_core.so 依赖于 libpldroid_streaming_puic.so,无论是否启用 QUIC 推流,都需要包含 libpldroid_streaming_puic.so 库
    • 构造函数中包含 AspectFrameLayout 参数的方法已被弃用,后续版本会删除,故不推荐使用

    2. 功能列表

    • 基本的推流和连麦对讲功能
    • 基本的视频合流和音频混音功能
    • 支持内置音视频采集,带美颜、水印、闪光灯、摄像头切换、聚焦等常见功能
    • 支持外部采集视频数据,支持的格式为:NV21 和 I420
    • 支持外部采集音频数据,支持的格式为:PCM,单通道,16bit 位宽
    • 支持外部美颜
    • 支持踢人功能
    • 支持静音功能
    • 支持连麦的帧率配置
    • 支持连麦的视频码率的配置
    • 支持连麦的视频尺寸配置
    • 支持连麦的网络重连和超时的配置
    • 支持丰富的连麦消息回调
    • 支持纯音频连麦
    • 支持连麦大小窗口切换
    • 支持推流的软硬编配置
    • 支持连麦的软硬编配置
    • 支持连麦画面的截帧
    • 支持动态镜像功能
    • 支持获取远端麦克风音量大小
    • 支持推流码率的自动调节/手动调节
    • 支持获取连麦房间统计信息(帧率、码率等)

    3. 阅读对象

    本文档为技术文档,需要阅读者:

    • 具有基本的 Android 开发能力
    • 准备接入七牛云直播

    4 开发准备

    4.1 设备以及系统要求

    • 系统要求:Android 4.1 (API 16) 及其以上

    4.2 混淆

    -keep class cn.tee3.** {*;}
    -keep class org.webrtc.** {*;}
    -keep class com.qiniu.android.dns.** {*;}
    -keep class com.qiniu.pili.droid.streaming.** {*;}
    

    5 快速开始

    5.1 开发环境

    5.2 下载和导入连麦 SDK

    SDK 主要包含 demo 代码、sdk jar 包,以及 sdk 依赖的动态库文件。

    其中,release 目录下是需要拷贝到您的 Android 工程的所有文件,列表如下:

    • 将 pldroid-rtc-x.y.z.jar 包拷贝到您的工程的 libs 目录下
    • 将动态库拷贝到您的工程对应的目录下,例如:armeabi-v7a 目录下的 so 则拷贝到工程的 jniLibs/armeabi-v7a 目录下

    具体可以参考 SDK 包含的 demo 工程,集成后的工程示例如下:

    5.3 修改 build.gradle

    双击打开您的工程目录下的 build.gradle,确保已经添加了如下依赖,如下所示:

    dependencies {
        compile 'com.qiniu:happy-dns:0.2.x'
        compile files('libs/pldroid-rtc-streaming-x.y.z.jar')
    }
    

    5.4 添加相关权限

    在 app/src/main 目录中的 AndroidManifest.xml 中增加如下 uses-permission 声明

    <!-- 访问网络状态 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    
    <!-- 系统相关 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    5.5 开发步骤

    5.5.1 初始化

    首先,进入 Activity 后,完成 SDK 的初始化操作:

    RTCMediaStreamingManager.init(getApplicationContext());
    

    5.5.2 XML 文件中添加本地预览窗口

    在 XML 文件中,配置本地 Camera 预览的视图布局,如下所示:

    <com.qiniu.pili.droid.rtcstreaming.demo.ui.CameraPreviewFrameView
        android:id="@+id/LocalPreivew"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
    

    5.5.3 XML 文件中添加远端画面显示窗口

    在 XML 文件中,配置远端画面的视图布局,如下所示:

    <FrameLayout
        android:id="@+id/RemoteWindowA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="invisible"
        android:clickable="true"
        android:onClick="onClickRemoteWindowA" >
        <android.opengl.GLSurfaceView
            android:id="@+id/RemoteGLSurfaceViewA"
            android:layout_width="120dp"
            android:layout_height="160dp"
            android:visibility="invisible"/>
    </FrameLayout>
    

    如果是多人连麦,可以添加多个窗口。

    5.5.4 创建推流&连麦核心对象

    本操作推荐在 Activity.onCreate() 函数中完成。

    CameraPreviewFrameView localCameraView = (CameraPreviewFrameView) findViewById(R.id.LocalPreivew);
    mMediaStreamingManager = new RTCMediaStreamingManager(getApplicationContext(), localCameraView, AVCodecType.SW_VIDEO_WITH_SW_AUDIO_CODEC);
    

    5.5.5 创建本地 Camera 的配置

    本操作推荐在 Activity.onCreate() 函数中完成。

    CameraStreamingSetting cameraStreamingSetting = new CameraStreamingSetting();
    cameraStreamingSetting.setCameraFacingId(mCameraFacingId)
        .setContinuousFocusModeEnabled(true)
        .setRecordingHint(false)
        .setResetTouchFocusDelayInMs(3000)
        .setFocusMode(CameraStreamingSetting.FOCUS_MODE_CONTINUOUS_PICTURE)
        .setCameraPrvSizeLevel(CameraStreamingSetting.PREVIEW_SIZE_LEVEL.MEDIUM)
        .setCameraPrvSizeRatio(CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_16_9)
        .setBuiltInFaceBeautyEnabled(true) // Using sdk built in face beauty algorithm
        .setFaceBeautySetting(new CameraStreamingSetting.FaceBeautySetting(0.8f, 0.8f, 0.6f)) // sdk built in face beauty settings
        .setVideoFilter(CameraStreamingSetting.VIDEO_FILTER_TYPE.VIDEO_FILTER_BEAUTY); // set the beauty on/off
    

    CameraStreamingSetting 的具体含义,请参考推流 SDK 的文档:摄像头参数配置

    5.5.6 配置连麦参数

    本操作推荐在 Activity.onCreate() 函数中完成。

    RTCConferenceOptions options = new RTCConferenceOptions();
    options.setVideoEncodingSizeRatio(RTCConferenceOptions.VIDEO_ENCODING_SIZE_RATIO.RATIO_16_9);
    options.setVideoEncodingSizeLevel(RTCConferenceOptions.VIDEO_ENCODING_SIZE_HEIGHT_480);
    options.setVideoEncodingOrientation(RTCConferenceOptions.VideoEncodingOrientation.PORT);
    // 主播/副主播可以配置不同的连麦码率
    options.setVideoBitrateRange(300 * 1000, 800 * 1000);
    mMediaStreamingManager.setConferenceOptions(options);
    

    5.5.7 添加远端画面的窗口

    本操作推荐在 Activity.onCreate() 函数中完成。

    • 创建远端窗口对象:
    RTCVideoWindow windowA = new RTCVideoWindow(findViewById(R.id.RemoteWindowA), (GLSurfaceView)findViewById(R.id.RemoteGLSurfaceViewA));
    RTCVideoWindow windowB = new RTCVideoWindow(findViewById(R.id.RemoteWindowB), (GLSurfaceView)findViewById(R.id.RemoteGLSurfaceViewB));
    
    • 如果是主播,则需要配置连麦合流的参数,如果是连麦观众,则跳过下面的步骤:
    windowA.setAbsoluteMixOverlayRect(options.getVideoEncodingHeight() - 240, 100, 240, 320);
    windowB.setAbsoluteMixOverlayRect(options.getVideoEncodingHeight() - 240, 420, 240, 320);
    
    • 完成窗口的添加:
    mMediaStreamingManager.addRemoteWindow(windowA);
    mMediaStreamingManager.addRemoteWindow(windowB);
    

    5.5.8 配置推流参数

    本操作推荐在 Activity.onCreate() 函数中完成。

    如果是主播,则需要配置推流参数,如果是连麦观众,则跳过下面的步骤:

    // 配置推流参数
    StreamingProfile mStreamingProfile = new StreamingProfile();
    mStreamingProfile.setVideoQuality(StreamingProfile.VIDEO_QUALITY_MEDIUM2)
        .setAudioQuality(StreamingProfile.AUDIO_QUALITY_MEDIUM1)
        .setEncoderRCMode(StreamingProfile.EncoderRCModes.QUALITY_PRIORITY)
        .setEncodingOrientation(StreamingProfile.ENCODING_ORIENTATION.PORT)
        .setQuicEnable(isQuicEnable)
        .setPreferredVideoEncodingSize(options.getVideoEncodingWidth(), options.getVideoEncodingHeight()) // 配置推流的尺寸,建议与连麦尺寸一致
        .setYuvFilterMode(StreamingProfile.YuvFilterMode.None);  // 当图像采集尺寸与推流尺寸不一致时,SDK 会对采集图像进行 resize 操作,通过 FilterMode 参数,可以对 resize 算法进行设置。
    
    // 配置水印参数
    WatermarkSetting watermarksetting = new WatermarkSetting(this);
    watermarksetting.setResourceId(R.drawable.qiniu_logo)
                    .setSize(WatermarkSetting.WATERMARK_SIZE.MEDIUM)
                    .setAlpha(100)
                    .setCustomPosition(0.5f, 0.5f);
    

    推流参数的配置,可以参考我们推流 SDK 的官方文档:推流参数设置

    5.5.9 调用 prepare() 完成配置

    本操作推荐在 Activity.onCreate() 函数中完成。

    • 如果是主播,则调用下面的函数,配置 Camera 参数的同时,配置水印和推流的参数
    mMediaStreamingManager.prepare(cameraStreamingSetting, null,  watermarksetting, mStreamingProfile);
    
    • 如果是连麦观众,则调用下面的函数,配置 Camera 参数即可
    mMediaStreamingManager.prepare(mCameraStreamingSetting, null);
    

    5.5.10 开始/停止数据采集

    无论是推流还是连麦,都需要数据的采集,因此,建议在 Activity.onResume()Activity.onPause() 的时候,开启和关闭数据的采集。

    @Override
    protected void onResume() {
         super.onResume();
         mMediaStreamingManager.startCapture();
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        mMediaStreamingManager.stopCapture();
    }
    

    5.5.11 开始/停止连麦

    上面一系列的配置结束后,就可以在合适的时机开始/停止连麦了,相应的函数原型如下:

    /**
     * 开始连麦
     *
     * 调用成功后,SDK 首先会加入“连麦房间“,然后开始推送本地音视频流到“连麦服务器”,同时拉取房间中的音视频流
     * 可以通过 `ConferenceStateChangedListener.onConferenceStateChanged(RTCConferenceState state, int extra)` 接收相关状态信息的回调,相关状态包括:
     * 1. RTCConferenceState.VIDEO_PUBLISH_FAILED
     * 2. RTCConferenceState.AUDIO_PUBLISH_FAILED
     * 3. RTCConferenceState.VIDEO_PUBLISH_SUCCESS
     * 4. RTCConferenceState.AUDIO_PUBLISH_SUCCESS
     *
     * 调用本方法之前,需从先业务服务器获取主播的"连麦房间号"和"连麦房间的密钥"
     * 必须在 `RTCConferenceState.READY` 状态之后,才允许调用本方法
     *
     * @param userId    加入连麦的用户ID,必须唯一,同一个ID加入会议会将已加入的用户踢出
     * @param roomName  主播的连麦房间名称
     * @param roomToken 主播的连麦房间的Token,由App服务器动态生成
     * @param callback  调用结果的回调
     */
    public void startConference(String userId, String roomName, String roomToken, RTCStartConferenceCallback callback);
    
    /**
     * 停止连麦
     *
     * 调用成功后,SDK 会停止推送本地音视频流到“连麦服务器”,同时停止拉取房间中的音视频流,然后退出“连麦房间”
     */
    public void stopConference();
    

    5.5.12 开始/停止推流

    主播 在配置完成后,可以在合适的时候开启推流,不过要记得先配置推流地址:

    mStreamingProfile.setPublishUrl(publishAddr);
    mMediaStreamingManager.setStreamingProfile(mStreamingProfile);
    

    配置好了推流地址以后,就可以开始/停止推流了:

    /**
     * 开始推流
     * 调用成功后,SDK 开始推送本地音视频流到"流媒体服务器"
     * 必须在 `StreamingStateChangedListener.READY` 状态之后,才允许调用本方法
     *
     * @return 本方法的调用结果
     */
    public boolean startStreaming();
    
    /**
     * 停止推流
     * 调用成功后,SDK 会停止推送本地音视频流到"流媒体服务器"
     *
     * @return 本方法的调用结果
     */
     public boolean stopStreaming();
    

    5.5.13 退出整个页面

    无论是推流还是连麦,在整个 Activity 销毁的时候,需要调用如下函数,释放资源:

    /**
     * 销毁对象,释放资源
     *
     * @return 本方法的调用结果
     */
    public void destroy();
    
    /**
     * 销毁引擎
     * 本方法调用后不能再使用该类的其它接口
     */
    public static void deinit();
    

    5.5.14 后台推流和连麦

    由于我们不支持后台推流和连麦,因此,当应用进入后台后,请停止采集、连麦和推流。

    6. SDK 接口的设计

    6.1 连麦 SDK 接口概述

    连麦 SDK 的核心接口类有 3 个,分别是 RTCMediaStreamingManagerRTCStreamingManagerRTCConferenceManager, 其中,RTCMediaStreamingManager 提供了内置音视频数据的采集和美颜等功能,RTCStreamingManager 提供了使用外部数据源做连麦和推流的接口,RTCConferenceManager 提供了更加灵活的音视频操作接口,但是该接口类不包含推流功能,仅适用于纯连麦场景。

    6.2 RTCMediaStreamingManager

    RTCMediaStreamingManager 是负责管理整个推流和连麦生命周期的核心类之一,该类提供了内置音视频采集功能,支持美颜和水印,其核心的接口描述如下:

    6.2.1 引擎的初始化/销毁

    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @param append 是否允许追加
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath, boolean append);
    
    /**
     * 销毁引擎
     * 本方法调用后不能再使用该类的其它接口
     */
    public static void deinit();
    

    6.2.2 构造函数

    注意: 构造函数中包含 AspectFrameLayout 参数的方法已被弃用,后续版本会删除,故不推荐使用

    /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于音频+视频直播和连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      * @param localView 本地 Camera 预览窗口
      */
    public RTCMediaStreamingManager(Context ctx, GLSurfaceView localView);
    
    /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于音频+视频直播和连麦
      *
      * @param ctx Android 的上下文句柄
      * @param localView 本地 Camera 预览窗口
      * @param encodingType 可选参数:HW_VIDEO_WITH_HW_AUDIO_CODEC 或者 SW_VIDEO_WITH_SW_AUDIO_CODEC
      */
    public RTCMediaStreamingManager(Context ctx, GLSurfaceView localView, AVCodecType encodingType);
    
     /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于音频+视频直播和连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      * @param layout SDK 提供的用于尺寸变换的视图类
      * @param localView 本地 Camera 预览窗口
      */
    @Deprecated
    public RTCMediaStreamingManager(Context ctx, AspectFrameLayout layout, GLSurfaceView localView);
    
     /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于音频+视频直播和连麦
      *
      * @param ctx Android 的上下文句柄
      * @param layout SDK 提供的用于尺寸变换的视图类
      * @param localView 本地 Camera 预览窗口
      * @param encodingType 可选参数:HW_VIDEO_WITH_HW_AUDIO_CODEC 或者 SW_VIDEO_WITH_SW_AUDIO_CODEC
      */
    @Deprecated
    public RTCMediaStreamingManager(Context ctx, AspectFrameLayout layout, GLSurfaceView localView, AVCodecType encodingType);
    
     /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于纯音频直播和连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      */
    public RTCMediaStreamingManager(Context ctx);
    
     /**
      * 构造 RTCMediaStreamingManager 对象
      * 用于纯音频直播和连麦
      *
      * @param ctx Android 的上下文句柄
      * @param encodingType 可选参数:HW_AUDIO_CODEC 或者 SW_AUDIO_CODEC
      */
    public RTCMediaStreamingManager(Context ctx, AVCodecType encodingType);
    

    6.2.3 添加连麦窗口

    /**
     * 添加一个连麦画面的显示窗口
     * 本方纯音频连麦的场景下,也可以添加窗口,用于显示对方的画面
     *
     * @param window 显示窗口
     */
    public void addRemoteWindow(RTCVideoWindow window);
    

    6.2.4 初始化配置

    /**
     * 初始化“摄像头“和“麦克风”配置
     * 本方法在不需要推流的场景下使用,即:"非主播端"
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting);
    
    /**
     * 初始化“摄像头“和“麦克风”配置
     * 本方法在不需要推流的场景下使用,即:"非主播端"
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @param previewAppearance Camera 的预览模式
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting, PreviewAppearance previewAppearance);
    
    /**
     * 初始化“摄像头“、“麦克风”以及“推流“配置
     * 本方法在需要“推流+连麦”的场景中调用,即:"主播端"
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @param profile 推流的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting, StreamingProfile profile);
    
    /**
     * 初始化“摄像头“、“麦克风”以及“推流“配置,同时配置水印参数
     * 本方法在需要“推流+连麦”的场景中调用,即:“主播端“
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @param wmSetting 水印的配置参数
     * @param profile 推流的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting, WatermarkSetting wmSetting, StreamingProfile profile);
    
    /**
     * 初始化“摄像头“、“麦克风”以及“推流“配置,同时配置水印参数
     * 本方法在需要“推流+连麦”的场景中调用,即:“主播端“
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @param wmSetting 水印的配置参数
     * @param profile 推流的配置参数
     * @param previewAppearance Camera 的预览模式
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting, WatermarkSetting wmSetting, StreamingProfile profile, PreviewAppearance previewAppearance);
    
    /**
     * 初始化“麦克风”配置
     * 本方法在不需要推流的场景下使用,即:"非主播端",用于纯音频连麦
     * 建议在 Activity.onCreate() 中调用
     *
     * @param microphoneSetting 麦克风的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(MicrophoneStreamingSetting microphoneSetting);
    
    /**
     * 初始化“麦克风”配置
     * 本方法在需要“推流+连麦”的场景中调用,即:“主播端“,用于纯音频推流+连麦
     * 建议在 Activity.onCreate() 中调用
     *
     * @param microphoneSetting 麦克风的配置参数
     * @param profile 推流的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(MicrophoneStreamingSetting microphoneSetting, StreamingProfile profile);
    

    6.2.5 开始音视频采集

    /**
     * 打开摄像头和麦克风采集
     * 建议在 Activity.onResume() 中调用
     * 打开成功后,会回调`READY`状态
     *
     * @return 本方法的调用结果
     */
     public boolean startCapture();
    

    6.2.6 停止音视频采集

    /**
     * 关闭摄像头和麦克风采集
     * 建议在 Activity.onPause() 中调用
     *
     * @return 本方法的调用结果
     */
     public void stopCapture();
    

    6.2.7 释放资源

    /**
     * 销毁整个对象,释放相关资源
     * 建议在 Activity.onDestroy() 中调用
     *
     * @return 本方法的调用结果
     */
     public void destroy();
    

    6.2.8 开始连麦

    /**
     * 开始连麦
     *
     * 调用成功后,SDK 首先会加入“连麦房间“,然后开始推送本地音视频流到“连麦服务器”,同时拉取房间中的音视频流
     * 可以通过 `ConferenceStateChangedListener.onConferenceStateChanged(RTCConferenceState state, int extra)` 接收相关状态信息的回调,相关状态包括:
     * 1. RTCConferenceState.VIDEO_PUBLISH_FAILED
     * 2. RTCConferenceState.AUDIO_PUBLISH_FAILED
     * 3. RTCConferenceState.VIDEO_PUBLISH_SUCCESS
     * 4. RTCConferenceState.AUDIO_PUBLISH_SUCCESS
     *
     * 调用本方法之前,需从先业务服务器获取主播的"连麦房间号"和"连麦房间的密钥"
     * 必须在 `RTCConferenceState.READY` 状态之后,才允许调用本方法
     *
     * @param userId    加入连麦的用户ID,必须唯一,同一个ID加入会议会将已加入的用户踢出
     * @param roomName  主播的连麦房间名称
     * @param roomToken 主播的连麦房间的Token,由App服务器动态生成
     * @param callback  调用结果的回调
     */
    public void startConference(String userId, String roomName, String roomToken, RTCStartConferenceCallback callback);
    

    6.2.9 停止连麦

    /**
     * 停止连麦
     *
     * 调用成功后,SDK 会停止推送本地音视频流到“连麦服务器”,同时停止拉取房间中的音视频流,然后退出“连麦房间”
     */
    public void stopConference();
    

    6.2.10 开始推流

    /**
     * 开始推流
     * 调用成功后,SDK 开始推送本地音视频流到"流媒体服务器"
     *
     * @return 本方法的调用结果
     */
    public boolean startStreaming();
    

    6.2.11 停止推流

    /**
     * 停止推流
     * 调用成功后,SDK 会停止推送本地音视频流到"流媒体服务器"
     *
     * @return 本方法的调用结果
     */
    public boolean stopStreaming();
    

    6.2.12 切换摄像头

    /**
     * 切换摄像头
     * @param facingId 支持的枚举值包括:CAMERA_FACING_BACK, CAMERA_FACING_FRONT, CAMERA_FACING_3RD;
     *
     * @return 本方法的调用结果
     */
    public boolean switchCamera(CameraStreamingSetting.CAMERA_FACING_ID facingId);
    

    6.2.13 静音功能

    /**
     * 静音,需要在连麦/推流开始后再调用
     *
     * @param isMute 是否静音
     *
     * @return 本方法的调用结果
     */
    public boolean mute(boolean isMute);
    

    6.2.14 踢人功能

    /**
     * 根据 userId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param userId 被踢的用户ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(String userId);
    
    /**
     * 根据 glSurfaceViewId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param glSurfaceViewId 显示被踢用户的窗口ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(int glSurfaceViewId);
    

    6.2.15 设置连麦参数

    /**
     * 设置连麦参数
     * 配置连麦的相关参数,包括:视频的码率、帧率等等
     */
    public void setConferenceOptions(RTCConferenceOptions options);
    

    6.2.16 更新推流参数

    /**
     * 更新推流参数
     * 可以在推流之前,更新推流参数,比如配置推流地址等
     */
    public void setStreamingProfile(StreamingProfile profile);
    

    6.2.17 设置日志级别

    /**
     * 设置日志级别
     *
     * @param enabled 是否打开调试日志
     */
    public void setDebugLoggingEnabled(boolean enabled);
    

    6.2.18 获取参与连麦的人数

    /**
     * 获取参与连麦的人数,不包括自己
     */
    public int getParticipantsCount();
    

    6.2.19 获取参与连麦的用户ID列表

    /**
     * 获取参与连麦的用户ID列表,不包括自己
     */
    public List<String> getParticipants();
    

    6.2.20 大小窗口切换

    /**
     * 大小窗口切换
     *
     * @param viewToBottom 希望切换到底层的 View
     * @param viewToUpper 希望切换到上层的 View
     */
    public void switchRenderView(GLSurfaceView viewToBottom, GLSurfaceView viewToUpper);
    

    6.2.21 截帧功能

    /**
     * 截帧功能
     * 只有主播在连麦推流的时候,可以截取合流画面,其他情况下,本功能只支持截取自己预览的画面
     *
     * @param callback 截帧的回调
     */
    public void captureFrame(RTCFrameCapturedCallback callback)
    

    6.2.22 镜像功能

    /**
     * 设置 Camera 预览是否镜像
     *
     * @param mirror 是否镜像
     */
    public boolean setPreviewMirror(boolean mirror);
    
    /**
     * 设置连麦或者推流出去的画面是否镜像
     *
     * @param mirror 是否镜像
     */
    public boolean setEncodingMirror(boolean mirror);
    

    6.2.23 设置房间内音频流的音量回调

    /**
     * 注册音频音量回调
     * @param Callback 对象
    */
    public void setAudioLevelCallback(RTCAudioLevelCallback callback);
    

    需要注意的是,开启该回调会额外占用 5% 左右的 CPU,因此在开启连麦后,需要调用 setAudioLevelMonitorEnabled(true) 之后回调才会被触发;当希望停止监听音频信息时,需要调用 setAudioLevelMonitorEnabled(false) 来关闭回调。

    6.2.24 静音房间中的其他人

    /**
     * 静音房间中的其他人,需要在连麦/推流开始后再调用
     * 设置/取消静音房间里的其他人,静音后本地将不会播放其他连麦者的声音。
     * 如果在主播端设置,推出的 rtmp 流中也不会包括这些声音。
     * @return 是否成功
     */
    public boolean muteSpeaker(boolean isMuted);
    

    6.2.25 自定义视频窗口位置

    设置合流后的视频尺寸,以及主播画面在合流图像中的位置和大小。此方法必须在 RTCMediaStreamingManager.prepare 之前调用,否则将不会生效。

    如果不调用此方法,SDK 在合流时,默认会将主播的视频窗口置于最下层并将其大小设置为最终的推流大小,副主播的窗口置于主播视频之上。

    /**
     * 设置合流后的视频尺寸,以及主播画面在合流图像中的位置和大小。
     *
     * @param localWindowPosition 主播本地的视频窗口大小与位置,Rect 参数依次为:x, y, w, h
     */
    public void setLocalWindowPosition(Rect localWindowPosition);
    
    /**
     * 设置合流后的视频尺寸,以及主播画面在合流图像中的位置和大小。
     *
     * @param localWindowPosition 主播画面在合流图像中的位置和大小,RectF 参数依次为:x, y 位置的相对值,w, h 大小的相对值
     */
    public void setLocalWindowPosition(RectF localWindowPosition);
    

    6.2.26 处理合流数据回调

    public void setMixedFrameCallback(RTCFrameMixedCallback callback);
    
    public void setMixedFrameCallbackEnabled(boolean enable);
    

    通过 setMixedFrameCallback 注册过 RTCFrameMixedCallback 对象后,可以调用 setMixedFrameCallbackEnabled 动态开启或关闭合流数据回调。

    6.2.27 获取房间统计信息

    该方法需要在加入连麦后方可调用

    /**
    * 获取房间统计信息
    * @return 统计信息的哈希表,key 是当前房间里的各个用户的 `userId`,value 是 `RTCStreamStats` 类型的统计信息
    */
    public HashMap<String, RTCStreamStats> getStreamStats();
    
    /**
    * 开启/关闭统计功能。开启该功能后会略微提高 CPU 占用,约 2%。
    */
    public void setStreamStatsEnabled(boolean enable);
    

    目前 RTCStreamStats 包含以下方法:

    /**
     * 获取房间里各路流过去 20s 内在该设备上的下行码率
     * @return 带宽数值,单位是 bps
     */
    public int getRecvBitrate();
    
    /**
     * 获取房间里各路流过去 20s 内在该设备上的上行码率
     * @return 带宽数值,单位是 bps
     */
    public int getSentBitrate();
    
    /**
     * 获取最近 20 秒的丢包率
     * @return 丢包率,0-100
     */
    public int getPacketLossPercent();
    
    /**
     * 获取当前的帧数
     */
    public int getFrameRate();
    

    6.2.28 图片推流功能

    /**
     * 在 StreamingProfile 中调用此方法设置推流图片的资源 ID
     *
     * @param resId 推流图片的资源 ID
     */
    public void setPictureStreamingResourceId(int resId);
    
    /**
      * 在 StreamingProfile 中调用此方法设置推流图片的文件路径
      *
      * @param filePath 推流图片的文件路径
      */
    public void setPictureStreamingFilePath(String filePath);
    
    /**
     * 切换图片推流模式
     */
    public boolean togglePictureStreaming();
    

    6.2.29 返听功能

    /**
     * 开启返听功能
     *
     * @return 开启成功与否
     */
    public boolean startPlayback();
    /**
     * 关闭返听功能
     */
    public void stopPlayback();
    

    6.2.30 动态水印

    /**
     * 更新水印的配置(内容、位置、大小等)
     *
     * @param watermarkSetting 新的水印配置
     */
    public void updateWatermarkSetting(WatermarkSetting watermarkSetting);
    

    6.3 RTCStreamingManager

    RTCStreamingManager 是负责管理整个推流和连麦生命周期的核心类之一,该类并不提供视频数据的采集功能,推流和连麦的音视频数据需要由外部导入,其接口描述如下:

    6.3.1 引擎的初始化/销毁

    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @param append 是否允许追加
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath, boolean append);
    
    /**
     * 销毁引擎
     * 本方法调用后不能再使用该类的其它接口
     */
    public static void deinit();
    

    6.3.2 构造函数

     /**
      * 构造 RTCStreamingManager 对象
      *
      * @param ctx Android 的上下文句柄
      */
    public RTCStreamingManager(Context ctx);
    
     /**
      * 构造 RTCStreamingManager 对象
      *
      * @param ctx Android 的上下文句柄
      * @param encodingType 推流的编码类型
      */
    public RTCStreamingManager(Context ctx, AVCodecType encodingType);
    

    6.3.3 添加连麦窗口

    /**
     * 添加一个连麦画面的显示窗口
     *
     * @param window 显示窗口
     */
    public void addRemoteWindow(RTCVideoWindow window);
    

    6.3.4 初始化推流配置

    /**
     * 初始化"推流"配置
     * 本方法在需要“推流+连麦”的场景中调用,比如"主播端"
     * 建议在 Activity.onCreate() 中调用
     *
     * @param profile 推流参数配置对象
     * @return 本方法的调用结果
     */
    public boolean prepare(StreamingProfile profile);
    

    6.3.5 开始外部采集

    /**
     * 开始接受外部数据源输入
     * 建议在 Activity.onResume() 中调用
     *
     * @return 本方法的调用结果
     */
     public boolean resume();
    

    6.3.6 停止外部采集

    /**
     * 停止接受外部数据源输入
     * 建议在 Activity.onPause() 中调用
     * 
     * @return 本方法的调用结果
     */
     public void pause();
    

    6.3.7 释放资源

    /**
     * 销毁整个对象,释放相关资源
     * 建议在 Activity.onDestroy() 中调用
     * @return 本方法的调用结果
     */
     public void destroy();
    

    6.3.8 开始连麦

    /**
     * 开始连麦
     *
     * 调用成功后,SDK 首先会加入“连麦房间“,然后开始推送本地音视频流到“连麦服务器”,同时拉取房间中的音视频流
     * 可以通过 `ConferenceStateChangedListener.onConferenceStateChanged(RTCConferenceState state, int extra)` 接收相关状态信息的回调,相关状态包括:
     * 1. RTCConferenceState.VIDEO_PUBLISH_FAILED
     * 2. RTCConferenceState.AUDIO_PUBLISH_FAILED
     * 3. RTCConferenceState.VIDEO_PUBLISH_SUCCESS
     * 4. RTCConferenceState.AUDIO_PUBLISH_SUCCESS
     *
     * 调用本方法之前,需从先业务服务器获取主播的"连麦房间号"和"连麦房间的密钥"
     * 必须在 `RTCConferenceState.READY` 状态之后,才允许调用本方法
     *
     * @param userId    加入连麦的用户ID,必须唯一,同一个ID加入会议会将已加入的用户踢出
     * @param roomName  主播的连麦房间名称
     * @param roomToken 主播的连麦房间的 Token,由 App 服务器动态生成
     * @param callback  调用结果的回调
     */
    public void startConference(String userId, String roomName, String roomToken,
    RTCStartConferenceCallback callback);
    

    6.3.9 停止连麦

    /**
     * 停止连麦
     *
     * 调用成功后,SDK 会停止推送本地音视频流到“连麦服务器”,同时停止拉取房间中的音视频流,然后退出“连麦房间”
     */
    public void stopConference();
    

    6.3.10 开始推流

    /**
     * 开始推流
     * 调用成功后,SDK 开始连接到"流媒体服务器"
     *
     * @return 本方法的调用结果
     */
    public boolean startStreaming();
    

    6.3.11 停止推流

    /**
     * 开始推流
     * 调用成功后,SDK 断开与"流媒体服务器"的连接
     *
     * @return 本方法的调用结果
     */
    public boolean stopStreaming();
    

    6.3.12 静音功能

    /**
     * 静音,需要在连麦/推流开始后再调用
     *
     * @param isMute 是否静音
     *
     * @return 本方法的调用结果
     */
    public boolean mute(boolean isMute);
    

    6.3.13 踢人功能

    /**
     * 根据 userId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param userId 被踢的用户ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(String userId);
    
    /**
     * 根据 glSurfaceViewId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param glSurfaceViewId 显示被踢用户的窗口ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(int glSurfaceViewId);
    

    6.3.14 设置连麦参数

    /**
     * 设置连麦参数
     * 配置连麦的相关参数,包括:视频的码率、帧率等等
     *
     * @return 无
     */
    public void setConferenceOptions(RTCConferenceOptions options);
    

    6.3.15 更新推流参数

    /**
     * 更新推流参数
     * 可以在推流之前,更新推流参数,配置推流地址等
     * 
     * @return 无
     */
    public void setStreamingProfile(StreamingProfile profile);
    

    6.3.16 设置日志级别

    /**
     * 设置日志级别
     *
     * @param enabled 是否打开调试日志
     *
     * @return 无
     */
    public void setDebugLoggingEnabled(boolean enabled);
    

    6.3.17 送入外部视频数据

    /**
     * 送入外部视频数据
     *
     * @param data 存放视频帧的数组
     * @param width 外部视频的宽
     * @param height 外部视频的高
     * @param rotation 外部视频的角度,0,90,180,270度
     * @param mirror 是否镜像
     * @param fmt 视频格式,只支持:PLFourCC.FOURCC_NV21,PLFourCC.FOURCC_I420
     * @param ts 视频帧的时间戳,单位:ns
     * 
     * @return 本方法的调用结果
     */
    public boolean inputVideoFrame(byte[] data, int width, int height, int rotation, boolean mirror, int fmt, long ts)
    

    6.3.18 送入外部音频数据

    /**
     * 送入外部音频数据
     *
     * @param data 存放音频帧的数组
     * @param ts 音频帧的时间戳,单位:ns
     * 
     * @return 本方法的调用结果
     */
    public boolean inputAudioFrame(byte[] data, long ts)
    

    6.3.19 获取参与连麦的人数

    /**
     * 获取参与连麦的人数,不包括自己
     */
    public int getParticipantsCount();
    

    6.3.20 获取参与连麦的用户ID列表

    /**
     * 获取参与连麦的用户ID列表,不包括自己
     */
    public List<String> getParticipants();
    

    6.3.21 设置房间内音频流的音量回调

    /**
     * 注册音频音量回调
     * @param Callback 对象
    */
    public void setAudioLevelCallback(RTCAudioLevelCallback callback);
    

    需要注意的是,开启该回调会额外占用 5% 左右的 CPU,因此在开启连麦后,需要调用 setAudioLevelMonitorEnabled(true) 之后回调才会被触发;当希望停止监听音频信息时,需要调用 setAudioLevelMonitorEnabled(false) 来关闭回调。

    6.3.22 静音房间中的其他人

    /**
      * 设置/取消静音房间里的其他人,静音后本地将不会播放其他连麦者的声音。
      * 如果在主播端设置,推出的 rtmp 流中也不会包括这些声音。
      * @return 是否成功
    */
    public boolean muteSpeaker(boolean isMuted);
    

    6.3.23 处理合流数据回调

    public void setMixedFrameCallback(RTCFrameMixedCallback callback);
    
    public void setMixedFrameCallbackEnabled(boolean enable);
    

    通过 setMixedFrameCallback 注册过 RTCFrameMixedCallback 对象后,可以调用 setMixedFrameCallbackEnabled 动态开启或关闭合流数据回调。

    6.3.24 获取房间统计信息

    该方法需要在加入连麦后方可调用

    /**
    * 获取房间统计信息
    * @return 统计信息的哈希表,key 是当前房间里的各个用户的 `userId`,value 是 `RTCStreamStats` 类型的统计信息
    */
    public HashMap<String, RTCStreamStats> getStreamStats();
    
    /**
    * 开启/关闭统计功能。开启该功能后会略微提高 CPU 占用,约 2%。
    */
    public void setStreamStatsEnabled(boolean enable);
    

    目前 RTCStreamStats 包含以下方法:

    /**
     * 获取房间里各路流过去 20s 内在该设备上的下行码率
     * @return 带宽数值,单位是 bps
     */
    public int getRecvBitrate();
    
    /**
     * 获取房间里各路流过去 20s 内在该设备上的上行码率
     * @return 带宽数值,单位是 bps
     */
    public int getSentBitrate();
    
    /**
     * 获取最近 20 秒的丢包率
     * @return 丢包率,0-100
     */
    public int getPacketLossPercent();
    
    /**
     * 获取当前的帧数
     */
    public int getFrameRate();
    

    6.4 RTCConferenceManager

    RTCConferenceManager 是负责管理纯连麦场景下连麦生命周期的核心类,该类不包含推流功能,但是提供了更加灵活可控的音视频操作的接口,其核心的接口描述如下:

    6.4.1 引擎的初始化/销毁

    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath);
    
    /**
      * 初始化引擎
      * 该类的所有其他接口必须在本方法调用成功后才能使用
      *
      * @param context the context Android 的上下文句柄
      * @param filePath 日志存储路径
      * @param append 是否允许追加
      * @return 错误码,0 代表成功,其他数值为初始化失败
      */
    public static int init(Context context, String filePath, boolean append);
    
    /**
     * 销毁引擎
     * 本方法调用后不能再使用该类的其它接口
     */
    public static void deinit();
    

    6.4.2 构造函数

    注意: 构造函数中包含 AspectFrameLayout 参数的方法已被弃用,后续版本会删除,故不推荐使用

    /**
      * 构造 RTCConferenceManager 对象
      * 用于纯音频连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      */
    public RTCConferenceManager(Context ctx);
    
    /**
      * 构造 RTCConferenceManager 对象
      * 用于纯音频连麦
      *
      * @param ctx Android 的上下文句柄
      * @param encodingType 编码方式
      */
    public RTCConferenceManager(Context ctx, AVCodecType encodingType)
    
    /**
      * 构造 RTCConferenceManager 对象
      * 用于音频+视频连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      * @param localView 本地 Camera 预览窗口
      */
    public RTCConferenceManager(Context ctx, GLSurfaceView localView);
    
    /**
      * 构造 RTCConferenceManager 对象
      * 用于音频+视频连麦
      *
      * @param ctx Android 的上下文句柄
      * @param localView 本地 Camera 预览窗口
      * @param encodingType 编码方式
      */
    public RTCConferenceManager(Context ctx, GLSurfaceView localView, AVCodecType encodingType);
    
    /**
      * 构造 RTCConferenceManager 对象
      * 用于音频+视频连麦,默认采用软编推流
      *
      * @param ctx Android 的上下文句柄
      * @param layout SDK 提供的用于尺寸变换的视图类
      * @param localView 本地 Camera 预览窗口
      */
    @Deprecated
    public RTCConferenceManager(Context ctx, AspectFrameLayout layout, GLSurfaceView localView);
    

    6.4.3 添加连麦窗口

    /**
     * 添加一个连麦画面的显示窗口
     * 本方纯音频连麦的场景下,也可以添加窗口,用于显示对方的画面
     *
     * @param window 显示窗口
     */
    public void addRemoteWindow(RTCVideoWindow window);
    

    6.4.4 初始化配置

    /**
     * 初始化“麦克风”配置
     * 本方法用于纯音频连麦
     * 建议在 Activity.onCreate() 中调用
     *
     * @param microphoneSetting 麦克风的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(MicrophoneStreamingSetting microphoneSetting);
    /**
     * 初始化“摄像头“和“麦克风”配置
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting);
    /**
     * 初始化“摄像头“、“麦克风”配置,同时配置水印参数
     * 建议在 Activity.onCreate() 中调用
     *
     * @param camSetting 摄像头的配置参数
     * @param microphoneSetting 麦克风的配置参数
     * @param wmSetting 水印的配置参数
     * @return 本方法的调用结果
     */
    public boolean prepare(CameraStreamingSetting camSetting, MicrophoneStreamingSetting microphoneSetting, WatermarkSetting wmSetting);
    

    6.4.5 开始/关闭视频数据采集

    开启和关闭视频数据的采集,建议在 Activity.onResume()Activity.onPause() 的时候调用。

    @Override
    protected void onResume() {
         super.onResume();
         mRTCStreamingManager.startVideoCapture();
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        mRTCStreamingManager.stopVideoCapture();
    }
    

    6.4.6 开始/关闭音频数据采集

    开启和关闭音频数据的采集,建议在 Activity.onResume()Activity.onPause() 的时候调用。

    @Override
    protected void onResume() {
         super.onResume();
         mRTCStreamingManager.startAudioCapture();
    
    @Override
    protected void onPause() {
        super.onPause();
        mRTCStreamingManager.stopAudioCapture();
    }
    

    6.4.7 开始/关闭视频数据的发布

    开启和关闭视频数据的发布。

    mRTCStreamingManager.publishLocalVideo();
    mRTCStreamingManager.unpublishLocalVideo();
    

    6.4.8 开始/关闭音频数据的发布

    开启和关闭音频数据的发布。

    mRTCStreamingManager.publishLocalAudio();
    mRTCStreamingManager.unpublishLocalAudio();
    

    6.4.9 释放资源

    /**
     * 销毁整个对象,释放相关资源
     * 建议在 Activity.onDestroy() 中调用
     *
     * @return 本方法的调用结果
     */
     public void destroy();
    

    6.4.10 开始连麦

    /**
     * 开始连麦
     *
     * 调用成功后,SDK 首先会加入“连麦房间“,然后开始推送本地音视频流到“连麦服务器”,同时拉取房间中的音视频流
     * 可以通过 `ConferenceStateChangedListener.onConferenceStateChanged(RTCConferenceState state, int extra)` 接收相关状态信息的回调,相关状态包括:
     * 1. RTCConferenceState.VIDEO_PUBLISH_FAILED
     * 2. RTCConferenceState.AUDIO_PUBLISH_FAILED
     * 3. RTCConferenceState.VIDEO_PUBLISH_SUCCESS
     * 4. RTCConferenceState.AUDIO_PUBLISH_SUCCESS
     *
     * 调用本方法之前,需从先业务服务器获取主播的"连麦房间号"和"连麦房间的密钥"
     * 必须在 `RTCConferenceState.READY` 状态之后,才允许调用本方法
     *
     * @param userId    加入连麦的用户ID,必须唯一,同一个ID加入会议会将已加入的用户踢出
     * @param roomName  主播的连麦房间名称
     * @param roomToken 主播的连麦房间的Token,由App服务器动态生成
     * @param callback  调用结果的回调
     */
    public void startConference(String userId, String roomName, String roomToken, RTCStartConferenceCallback callback);
    

    6.4.11 停止连麦

    /**
     * 停止连麦
     *
     * 调用成功后,SDK 会停止推送本地音视频流到“连麦服务器”,同时停止拉取房间中的音视频流,然后退出“连麦房间”
     */
    public void stopConference();
    

    6.4.12 切换摄像头

    /**
     * 切换摄像头
     * @param facingId 支持的枚举值包括:CAMERA_FACING_BACK, CAMERA_FACING_FRONT, CAMERA_FACING_3RD;
     *
     * @return 本方法的调用结果
     */
    public boolean switchCamera(CameraStreamingSetting.CAMERA_FACING_ID facingId);
    

    6.4.13 静音功能

    /**
     * 静音,需要在连麦/推流开始后再调用
     *
     * @param isMute 是否静音
     *
     * @return 本方法的调用结果
     */
    public boolean mute(boolean isMute);
    

    6.4.14 踢人功能

    /**
     * 根据 userId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param userId 被踢的用户ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(String userId);
    
    /**
     * 根据 glSurfaceViewId 踢人
     * 被踢的用户会收到 "USER_KICKOUT_BY_HOST" 的消息回调
     *
     * @param glSurfaceViewId 显示被踢用户的窗口ID
     *
     * @return 本方法的调用结果
     */
    public boolean kickoutUser(int glSurfaceViewId);
    

    6.4.15 设置连麦参数

    /**
     * 设置连麦参数
     * 配置连麦的相关参数,包括:视频的码率、帧率等等
     */
    public void setConferenceOptions(RTCConferenceOptions options);
    

    6.4.16 设置日志级别

    /**
     * 设置日志级别
     *
     * @param enabled 是否打开调试日志
     */
    public void setDebugLoggingEnabled(boolean enabled);
    

    6.4.17 获取参与连麦的人数

    /**
     * 获取参与连麦的人数,不包括自己
     */
    public int getParticipantsCount();
    

    6.4.18 获取参与连麦的用户ID列表

    /**
     * 获取参与连麦的用户ID列表,不包括自己
     */
    public List<String> getParticipants();
    

    6.4.19 大小窗口切换

    /**
     * 大小窗口切换
     *
     * @param viewToBottom 希望切换到底层的 View
     * @param viewToUpper 希望切换到上层的 View
     */
    public void switchRenderView(GLSurfaceView viewToBottom, GLSurfaceView viewToUpper);
    

    6.4.20 截帧功能

    /**
     * 截帧功能
     * 只有主播在连麦推流的时候,可以截取合流画面,其他情况下,本功能只支持截取自己预览的画面
     *
     * @param callback 截帧的回调
     */
    public void captureFrame(RTCFrameCapturedCallback callback)
    

    6.4.21 镜像功能

    /**
     * 设置 Camera 预览是否镜像
     *
     * @param mirror 是否镜像
     */
    public boolean setPreviewMirror(boolean mirror);
    
    /**
     * 设置连麦或者推流出去的画面是否镜像
     *
     * @param mirror 是否镜像
     */
    public boolean setEncodingMirror(boolean mirror);
    

    6.4.22 设置房间内音频流的音量回调

    /**
     * 注册音频音量回调
     * @param Callback 对象
    */
    public void setAudioLevelCallback(RTCAudioLevelCallback callback);
    

    需要注意的是,开启该回调会额外占用 5% 左右的 CPU,因此在开启连麦后,需要调用 setAudioLevelMonitorEnabled(true) 之后回调才会被触发;当希望停止监听音频信息时,需要调用 setAudioLevelMonitorEnabled(false) 来关闭回调。

    6.4.23 静音房间中的其他人

    /**
     * 静音房间中的其他人,需要在连麦/推流开始后再调用
     * 设置/取消静音房间里的其他人,静音后本地将不会播放其他连麦者的声音。
     * 如果在主播端设置,推出的 rtmp 流中也不会包括这些声音。
     * @return 是否成功
     */
    public boolean muteSpeaker(boolean isMuted);
    

    6.4.24 获取房间统计信息

    该方法需要在加入连麦后方可调用

    /**
    * 获取房间统计信息
    * @return 统计信息的哈希表,key 是当前房间里的各个用户的 `userId`,value 是 `RTCStreamStats` 类型的统计信息
    */
    public HashMap<String, RTCStreamStats> getStreamStats();
    
    /**
    * 开启/关闭统计功能。开启该功能后会略微提高 CPU 占用,约 2%。
    */
    public void setStreamStatsEnabled(boolean enable);
    

    目前 RTCStreamStats 包含以下方法:

    /**
     * 获取房间里各路流过去 20s 内在该设备上的下行码率
     * @return 带宽数值,单位是 bps
     */
    public int getRecvBitrate();
    
    /**
     * 获取房间里各路流过去 20s 内在该设备上的上行码率
     * @return 带宽数值,单位是 bps
     */
    public int getSentBitrate();
    
    /**
     * 获取最近 20 秒的丢包率
     * @return 丢包率,0-100
     */
    public int getPacketLossPercent();
    
    /**
     * 获取当前的帧数
     */
    public int getFrameRate();
    

    6.5 参数配置/状态获取

    6.5.1 CameraStreamingSetting

    CameraStreamingSetting 用于配置内置的 Camera 参数,包括:分辨率、对焦模式、美颜等等,详细用法可以参考我们推流SDK的官方文档:摄像头参数配置

    6.5.2 StreamingProfile

    StreamingProfile 用于配置推流参数,包括推流的地址、编码参数等等,详细用法可以参考我们推流SDK的官方文档:推流参数设置

    6.5.3 RTCConferenceOptions

    RTCConferenceOptions 用于配置连麦会话的参数,包括连麦的码率、帧率、软编硬编等,其定义如下:

    6.5.3.1 设置连接连麦服务器超时时间

    /**
      * 设置连接超时时间
      * 默认值为:5000ms
      *
      * @param milliseconds 超时时间
      * @return 本对象的指针
      */
    public RTCConferenceOptions setConnectTimeout(int milliseconds)
    

    6.5.3.2 设置与连麦服务器断线后的重连次数

    /**
      * 设置断线后的重连次数
      * 默认值为:1
      *
      * @param reconnectTimes 重连次数
      * @return 本对象的指针
      */
    public RTCConferenceOptions setReconnectTimes(int reconnectTimes)
    

    6.5.3.3 设置连麦编码器的软编硬编

    /**
      * 设置连麦编码器的软编硬编
      * 默认情况下,会在内部检测系统硬件和版本,如果适合用硬编则优先使用硬编
      *
      * @param enabled 是否启用硬编
      * @return 本对象的指针
      */
    public RTCConferenceOptions setHWCodecEnabled(boolean enabled)
    

    6.5.3.4 设置连麦编码器输出的码率

    /**
     * 设置连麦编码器输出的码率
     * 连麦的码率会根据当前的网络状况动态的调整
     *
     * @param minBitrateInBps 码率浮动的下限,默认值:100 * 1000,单位:bps
     * @param maxBitrateInBps 码率浮动的上限,默认值:300 * 1000,单位:bps
     * @note: 如果 minBitrateInBps == maxBitrateInBps,则采用固定码率
     * @return 本对象的指针
     */
    public RTCConferenceOptions setVideoBitrateRange(int minBitrateInBps, int maxBitrateInBps);
    

    6.5.3.5 设置连麦编码器输出的帧率

    /**
     * 设置连麦编码器输出的帧率
     *
     * @param fps 视频帧率
     * @return 本对象的指针
     */
    public RTCConferenceOptions setVideoEncodingFps(int fps);
    

    6.5.3.6 设置连麦编码器输出的画面比例

    /**
     * 设置连麦编码器输出的画面比例
     *
     * @param ratio 比例,可选参数:RATIO_4_3,RATIO_16_9
     * @return 本对象的指针
     */
    public RTCConferenceOptions setVideoEncodingSizeRatio(VIDEO_ENCODING_SIZE_RATIO ratio);
    

    6.5.3.7 设置连麦编码器输出的画面尺寸级别

    /**
     * 设置连麦编码器输出的画面尺寸级别
     *
     * @param ratio 比例,可选参数:
     * <li> VIDEO_ENCODING_SIZE_DEFAULT </li>
     * <li> VIDEO_ENCODING_SIZE_HEIGHT_240 </li>
     * <li> VIDEO_ENCODING_SIZE_HEIGHT_480 </li>
     * <li> VIDEO_ENCODING_SIZE_HEIGHT_544 </li>
     * <li> VIDEO_ENCODING_SIZE_HEIGHT_720 </li>
     * <li> VIDEO_ENCODING_SIZE_HEIGHT_1088 </li>
     *
     * @return 本对象的指针
     */
    public RTCConferenceOptions setVideoEncodingSizeLevel(int level);
    

    6.5.3.8 将连麦合流的基准视频数据设置为导入数据

    该方法适用于连麦分辨率和推流分辨率不相等的场景,开启之后会以导入数据为基准做相关的处理,从而避免推流画面模糊等问题。 调用该方法后,同时主播端需要调用 RTCMediaStreamingManager.setLocalWindowPosition 方法配置推流画面的大小,否则连麦窗口位置会有问题

    /**
     * 将连麦合流的基准视频数据设置为导入数据
     *
     * @param enable 是否以导入数据为基准
     * @return 本对象的指针
     */
    public RTCConferenceOptions setRenderedUseCapture(boolean enable)
    

    6.5.3.9 获取连麦编码器输出的画面尺寸

    画面比例和尺寸级别最终对应的图像宽高值的关系如下表所示:

    Level Resolution(16:9) Resolution(4:3)
    VIDEO_ENCODING_SIZE_DEFAULT 原始输入尺寸 原始输入尺寸
    VIDEO_ENCODING_HEIGHT_240 424 x 240 320 x 240
    VIDEO_ENCODING_HEIGHT_480 848 x 480 640 x 480
    VIDEO_ENCODING_HEIGHT_544 960 x 544 720 x 544
    VIDEO_ENCODING_HEIGHT_720 1280 x 720 960 x 720
    VIDEO_ENCODING_HEIGHT_1088 1920 x 1088 1440 x 1088

    可以通过 Get 方法获取最终的尺寸配置结果,如下所示:

    /**
     * 获取编码器输出的画面的宽
     *
     * @return 宽,单位:px
     */
    public int getVideoEncodingWidth();
    
    /**
     * 获取编码器输出的画面的高
     *
     * @return 高,单位:px
     */
    public int getVideoEncodingHeight();
    

    6.5.4 RTCVideoWindow

    RTCVideoWindow 是连麦画面的窗口对象,用来管理窗口对象以及配置合流参数,注:只有主播需要配置合流画面的位置和大小。

    6.5.4.1 构造函数

    /**
     * 构造函数
     *
     * @param glSurfaceView 用于渲染连麦画面的 View
     */
    public RTCVideoWindow(GLSurfaceView glSurfaceView);
    
    /**
     * 构造函数
     *
     * @param parentView 伴随连麦窗口(glSurfaceView)一起显示/隐藏的父窗口
     * @param glSurfaceView 用于渲染连麦画面的 View
     */
    public RTCVideoWindow(View parentView, GLSurfaceView glSurfaceView);
    

    6.5.4.2 配置合流参数(方法一)

    /**
     * 使用相对值来配置该窗口在合流画面中的位置和大小
     * 主窗口的原点坐标在左上角
     *
     * @param x 相对于合流主窗口的 x 方向的位置比例,取值范围:0.0 ~ 1.0
     * @param y 相对于合流主窗口的 y 方向的位置比例,取值范围:0.0 ~ 1.0
     * @param w 相对于合流主窗口的宽的比例,取值范围:0.0 ~ 1.0
     * @param h 相对于合流主窗口的高的比例,取值范围:0.0 ~ 1.0
     */
    public void setRelativeMixOverlayRect(float x, float y, float w, float h);
    

    假设主窗口是 640 x 480 的画面,连麦窗口的配置是:[0.5, 0.3, 0.5, 0.5],那么,实际的效果是:

    连麦窗口的大小是:320 x 240 连麦窗口的位置是:x 坐标位于主窗口从左到右的 1/2 处,y 坐标位于主窗口从上往下的 3/10 处。

    6.5.4.3 配置合流参数(方法二)

    /**
     * 使用绝对值来配置该窗口在合流画面中的位置和大小
     * 主窗口的原点坐标在左上角
     *
     * @param x 连麦窗口的 x 坐标
     * @param y 连麦窗口的 y 坐标
     * @param w 连麦窗口的宽,单位:像素
     * @param h 连麦窗口的高,单位:像素
     */
    public void setAbsolutetMixOverlayRect(int x, int y, int w, int h);
    

    6.5.4.4 配置窗口的上下层级

    /**
     * 设置窗口的 z order
     */
    public void setZOrderMediaOverlay(boolean isMediaOverlay);
    public void setZOrderOnTop(boolean onTop);
    

    6.5.4.5 优化合流参数的配置

    合理的配置连麦画面的尺寸和合流参数的大小,可以显著降低主播端的 CPU、内存、带宽和功耗。

    • 减小连麦者的画面尺寸

    由于连麦对象的画面是小窗口,因此,对于连麦者,可以考虑使用比主播小一些的画面尺寸,比如:VIDEO_ENCODING_HEIGHT_240 ,这样可以显著降低主播端对连麦画面的剪裁压力。

    • 主播端合流参数尽量匹配连麦画面

    主播端配置连麦合流窗口的尺寸尽量接近连麦者的画面尺寸,比如:如果连麦者输出的画面尺寸是 320 x 240 ,那么主播端配置该对象合流的尺寸就用 320 x 240 或者小于该尺寸的值,这样可以避免或者减少主播端对连麦画面进行拉伸,显著降低主播端的 CPU 和功耗。

    6.5.5 RTCConferenceStateChangedListener

    ConferenceStateChangedListener 用于监听连麦过程的相关回调消息,其定义如下:

    public interface ConferenceStateChangedListener {
        /**
         * @param state 状态枚举
         * @param extra 附加参数,比如错误码
         */
        void onConferenceStateChanged(RTCConferenceState state, int extra);
    }
    

    目前定义的 RTCConferenceState 主要包括:

    public enum RTCStreamingState {
        /**
         * 准备就绪
         * 当摄像头和麦克风都成功打开后,则进入就绪状态
         * 必须进入就绪状态后,才能开始连麦
         */
        READY
    
        /**
         * 正在连接服务器
         * 当网络断开后,会回调该状态,自动重连服务器
         */
        CONNECTING,
    
        /**
         * 已经连接上服务器
         */
        CONNECTED,
    
        /**
         * 多次尝试连接服务器均失败后,会回调该状态
         */
        CONNECT_FAIL,
    
        /**
         * 无法发布视频到连麦房间
         */
        VIDEO_PUBLISH_FAILED,
    
        /**
         * 无法发布音频到连麦房间
         */
        AUDIO_PUBLISH_FAILED,
    
        /**
         * 成功发布视频到连麦房间
         */
        VIDEO_PUBLISH_SUCCESS,
    
        /**
         * 成功发布音频到连麦房间
         */
        AUDIO_PUBLISH_SUCCESS,
    
        /**
         * 用户在其它地方登录
         */
        USER_JOINED_AGAIN,
    
        /**
         * 用户被管理员踢出房间
         */
        USER_KICKOUT_BY_HOST,
    
        /**
         * 打开摄像头失败
         */
        OPEN_CAMERA_FAIL,
    
        /**
         * 打开麦克风失败
         */
        AUDIO_RECORDING_FAIL,
    }
    

    6.5.6 RTCUserEventListener

    RTCUserEventListener 用于监听连麦事件,包括远端用户加入连麦、远端用户退出连麦等。

    /**
     * 远端用户成功加入连麦
     * @param userId 远端用户的 userId
     */
    void onUserJoinConference(String userId);
    
    /**
     * 远端用户退出连麦
     * @param userId 远端用户的 userId
     */
    void onUserLeaveConference(String userId);
    

    6.5.7 RTCRemoteWindowEventListener

    RTCRemoteWindowEventListener 用于监听远端窗口显示/隐藏事件。

    /**
     * 远端连麦视频窗口显示事件
     * @param window 显示远端用户的窗口对象
     * @param remoteUserId 远端用户的 userId
     */
    void onRemoteWindowAttached(RTCVideoWindow window, String remoteUserId);
    
    /**
     * 远端连麦视频窗口隐藏事件
     * @param window 显示远端用户的窗口对象
     * @param remoteUserId 远端用户的 userId
     */
    void onRemoteWindowDetached(RTCVideoWindow window, String remoteUserId);
    

    6.5.8 StreamStatusCallback

    StreamStatusCallback 用于监听推流统计信息回调,其定义如下:

    public interface StreamStatusCallback() {
        void notifyStreamStatusChanged(final StreamingProfile.StreamStatus status);
    }
    

    目前定义的推流统计信息主要包括:

    public static class StreamStatus {
        /**
         * 音频的实时帧率
         * */
        public int audioFps;
    
        /**
         * 视频的实时帧率
         * */
        public int videoFps;
    
        /**
         * 音视频的平均码率
         * */
        public int totalAVBitrate;  // bps
    
        /**
         * 音频的实时码率
         * */
        public int audioBitrate;  // bps
    
        /**
         * 视频的实时码率
         * */
        public int videoBitrate;  // bps
    }
    

    6.5.9 StreamingStateChangedListener

    StreamingStateChangedListener 用于监听推流的状态信息回调,其定义如下:

    public interface StreamingStateChangedListener() {
         void onStateChanged(StreamingState status, Object extra);
    }
    

    目前定义的推流状态信息主要包括:

    public enum StreamingState {
        /**
         * 未知状态
         *
         * */
        UNKNOWN,
    
        /**
         * 正在初始化
         *
         * */
        PREPARING,
    
        /**
         * 准备就绪
         * */
        READY,
    
        /**
         * 正在连接流媒体服务器
         *
         * */
        CONNECTING,
    
        /**
         * 开始推流
         *
         * */
        STREAMING,
    
        /**
         * 停止推流
         *
         * */
        SHUTDOWN,
    
        /**
         * 无法连接流媒体服务器
         * */
        IOERROR,
    
        /**
         * 发送队列数据已空
         *
         * */
        SENDING_BUFFER_EMPTY,
    
        /**
         * 发送队列数据已满
         *
         * */
        SENDING_BUFFER_FULL,
    
        /**
         * 与流媒体服务器连接断开
         *
         * */
        DISCONNECTED,
    
        /**
         * 打开摄像头失败
         */
        OPEN_CAMERA_FAIL,
    
        /**
         * 打开麦克风失败
         */
        AUDIO_RECORDING_FAIL,
    
        /**
         * 无效的推流地址
         *
         * */
        INVALID_STREAMING_URL,
    
        /**
         * 流媒体服务器连接成功
         *
         * */
        CONNECTED,
    }
    

    6.5.10 RTCAudioLevelCallback

    RTCAudioLevelCallback 用于监听当前连麦房间里所有人的音量,其定义如下:

    public interface RTCAudioLevelCallback {
        void onAudioLevelChanged(RTCAudioInfo info);
    }
    

    目前 RTCAudioInfo 对象有以下方法:

        /**
         * 获取本地麦克风采集到的音量
         * @return 音量值,从0到9依次增大
         */
        public int getLocalMicrophoneAudioLevel() {
            return mLocalMicrophoneAudioLevel;
        }
    
        /**
         * 获取本地扬声器播放的音量
         * @return 音量值,从0到9依次增大
         */
        public int getLocalSpeakerAudioLevel() {
            return mLocalSpeakerAudioLevel;
        }
    
        /**
         * 获取房间里其他人的音量
         * @return 哈希表的 key 是 userId,value 是音量值,从0到9依次增大
         */
        public Map<String, Integer> getRemoteAudioLevels() {
            return mRemoteAudioLevels;
        }
    

    6.5.11 RTCFrameMixedCallback

    当有新的视频/音频帧合流完成时,RTCFrameMixedCallback 会被触发。其定义如下:

    public interface RTCFrameMixedCallback {
        void onVideoFrameMixed(byte[] data, int width, int height, int fmt, long timestamp);
        void onAudioFrameMixed(byte[] pcm, long timestamp);
    }
    

    目前 RTCFrameMixedCallback 有如下方法:

        /**
         * 当视频帧合流完成时触发
         * @param data 视频数据
         * @param width 宽
         * @param height 高
         * @param fmt 视频数据的格式,0 for I420, 1 for NV21
         * @param timestamp 视频时间戳
         */
        void onVideoFrameMixed(byte[] data, int width, int height, int fmt, long timestamp);
    
        /**
         * 当音频帧合流完成时触发
         * @param pcm 音频的 PCM 数据
         * @param timestamp 音频时间戳
         */
        void onAudioFrameMixed(byte[] pcm, long timestamp);
    

    6.5.12 RTCRemoteAudioEventListener

    RTCRemoteAudioEventListener 用于监听远端音频的发布/取消发布的事件。因为直播连麦场景下默认会发布音频,故该 listener 仅用于纯连麦互动场景,不应用于直播连麦场景

    /**
     * 远端连麦音频发布事件
     * @param userId 远端用户的 userId
     */
    void onRemoteAudioPublished(String userId);
    
    /**
     * 远端连麦视频取消发布事件
     * @param userId 远端用户的 userId
     */
    void onRemoteAudioUnpublished(String userId);
    

    6.5.13 AudioSourceCallback

    用户可以通过 AudioSourceCallback 回调接口,获取当前音频数据,实现自定义音频数据处理。

    // 注册音频采集数据回调
    xxxStreamingManager.setAudioSourceCallback(AudioSourceCallback callback);
    
    public interface AudioSourceCallback {
      /**
       * 回调音频采集 PCM 数据
       *
       * @param srcBuffer     音频 PCM数据,该 buffer 是 direct ByteBuffer。
       * @param size          buffer的大小
       * @param tsInNanoTime  时间戳,单位:纳秒
       * @param isEof         采集结束标志
       */
      void onAudioSourceAvailable(ByteBuffer srcBuffer, int size, long tsInNanoTime, boolean isEof);
    }
    

    6.5.14 RTCRemoteVideoFrameCallback

    RTCRemoteVideoFrameCallback 用于回调连麦远端的视频数据

    // 注册连麦远端视频数据回调
    xxxStreamingManager.setRemoteVideoFrameCallback(RTCRemoteVideoFrameCallback callback);
    
    public interface RTCRemoteVideoFrameCallback {
      /**
       * 连麦远端视频数据回调
       *
       * @param userId 远端的 userId
       * @param data 视频原始数据,格式是 I420
       * @param width 视频的宽
       * @param height 视频的高
       * @param pts 视频的时间戳,单位是 ns
       */
      void onRemoteVideoFrame(String userId, byte[] data, int width, int height, long pts);
    }
    

    7. 常见问题

    7.1 连麦 SDK 需要替换以前的推流 SDK 吗 ?

    是的,连麦 SDK 是在推流 SDK 基础上增加了连麦功能,替换掉推流 SDK 后,原有的推流 SDK 的 API 均可照常使用。

    7.2 连麦窗口是否可以移动 ?

    连麦的窗口是在本地的 XML 中配置的,可以随意配置位置和拖动,但是观众端从 CDN 观看的画面是由主播合流后的画面,不能移动。

    7.3 推流是否也必须加入 "连麦房间" ?

    推流依然沿用以前的流程,不用加入 “连麦房间”,调用连麦的时候,会在 SDK 内部 “自动” 加入房间。

    7.4 如何优化带宽占用

    连麦互动相比于原有的单向推流+播放,增加了更多的带宽占用,因此需要合理的分配推流&连麦的参数,以达到最好的效果。

    • 对于主播而言,同时需要 “推流”+“连麦”,因此,主播端的上行带宽主要由两部分决定:“推流的码率” + “连麦码率”
    • 由于主播上行带宽有限,因此,连麦码率可以配置得相对低一点,从而优先保证推流的质量
    • 连麦观众的码率可以配置得相对高一点,这样可以保证在主播端合流后的画面质量
    • 推流的码率是在 StreamingProfile 中配置的,具体参考:《推流参数设置》
    • 连麦的码率是在 RTCConferenceOptions 中配置的,具体参考:《3.4.3 RTCConferenceOptions》
    • 推荐阅读:《码率、fps、分辨率对清晰度及流畅度的影响》

    7.5 如何优化功耗

    对于主播而言,同时需要 “推流”+“连麦”,因此对手机的性能提出了更高的要求,我们也可以通过合理的参数配置,来适当减轻主播端的功耗压力。

    • 合理配置连麦者的画面尺寸

      由于连麦对象的画面是小窗口,因此,对于连麦者,可以考虑使用比主播小一些的画面尺寸,这样可以显著降低主播端对连麦画面的剪裁压力。

      注:连麦画面尺寸的配置参考:《3.4.3.7 设置连麦编码器输出的画面尺寸级别》

    • 合理配置主播端的合流参数

      主播端配置连麦合流窗口的尺寸尽量接近连麦者的画面尺寸,比如:如果连麦者输出的画面尺寸是 320 x 240 ,那么主播端配置该对象合流的尺寸就用 320 x 240 或者小于该尺寸的值,这样可以避免或者减少主播端对连麦画面进行拉伸,画面拉伸需要进行插值,非常消耗 CPU 。

      注:合流参数的配置参考:《3.4.4 RTCVideoWindow》

    • 适当降低连麦帧率

      连麦对讲的时候,画面很少剧烈运动,一般 15~20 帧的帧率足够了,降低帧率,可以显著降低 CPU 的处理压力,从而优化功耗。

      注:连麦帧率的配置参考:《3.4.3.5 设置连麦编码器输出的帧率》

    7.6 如何重连

    重连分为推流断线重连和连麦断线重连,下面分别描述:

    7.6.1 推流断线如何重连

    推流的状态消息会通过 StreamingStateChangedListener 进行回调,startStreaming() 如果无法连接上服务器,则会回调 IOERROR ,如果 startStreaming() 成功,则会进入 STREAMING 状态,此状态表示正在推流,如果发生断线,则会首先回调 DISCONNECTED 消息,再进入 onRestartStreamingHandled 回调。因此,关于重连的处理,我们需要关注 IOERRORDISCONNECTED 两个消息。

    收到 DISCONNECTED 消息之后,可以提示用户 ”连接断开”,如果需要重连,则需要在 StreamingSessionListener.onRestartStreamingHandled() 函数中进行,重连的示例代码如下:

    @Override
    public boolean onRestartStreamingHandled(int code) {
        return mRTCStreamingManager.startStreaming();
    }
    

    当执行重连后,SDK 内部会进行 3 次连接尝试,如果 3 次尝试均失败,则会回调 IOERROR 状态。

    收到 IOERROR 状态后,表明无法连接流媒体服务器,建议调用 stopStreaming() 停止推流,当然,你依然可以考虑继续尝试调用 startStreaming() 重连,不过建议如果在此状态下重连之前,检测一下网络联通性以及做一些 delay 操作。

    7.6.2 连麦断线如何重连

    连麦断线后,SDK 内部会自动重连,断线和重连的状态消息会通过 RTCConferenceStateChangedListener 进行回调,CONNECTING 表示与服务器断线了,正在重连;CONNECTED 表示与服务器连接成功;CONNECT_FAIL 表示多次重连尝试均失败,不再继续重连,这个时候建议提示用户无法连接连麦服务器,退出连麦。

    可以通过 RTCConferenceOptions 进行连麦自动重连的配置,setConnectTimeout 用于配置一次连接的超时时间,setReconnectTimes 用于配置断线后尝试的自动重连次数。

    7.7 如何后台推流&连麦

    目前我们不支持在后台进行推流和连麦,这一点要注意,因此,在 Activity 进入 pause 状态后,需要关闭音视频采集、关闭推流、关闭连麦,恢复到前台后,再重新开始,进入后台的处理示例代码如下:

    @Override
    protected void onPause() {
        super.onPause();
        mRTCStreamingManager.stopCapture();
        mRTCStreamingManager.stopConference();
        mRTCStreamingManager.stopStreaming();
    }
    

    7.8 如何美颜

    7.8.1 使用内部美颜

    SDK 内部集成有美颜功能,通过如下方式开启:

    CameraStreamingSetting cameraStreamingSetting = new CameraStreamingSetting();
    // 使用内部美颜功能,自定义美颜的话记得关闭掉
    cameraStreamingSetting.setBuiltInFaceBeautyEnabled(true);
    // 设置美颜参数,三个参数分别代表:磨皮、美白、红润
    cameraStreamingSetting.setFaceBeautySetting(new  cameraStreamingSetting.FaceBeautySetting(0.8f, 0.8f, 0.6f));
    // 开启/关闭美颜效果
    cameraStreamingSetting.setVideoFilter(CameraStreamingSetting.VIDEO_FILTER_TYPE.VIDEO_FILTER_BEAUTY);
    

    7.8.2 自定义美颜

    自定义美颜需要调用 setBuiltInFaceBeautyEnabled(false) 先关闭 SDK 内部的美颜,然后分别处理预览显示的 filter 效果和编码的 filter 效果:预览显示通过实现 SurfaceTextureCallback 接口;编码通过实现 StreamingPreviewCallback 接口。两者分别实现,互不影响。

    • 编码部分
    public interface StreamingPreviewCallback {
       /**
        * 视频采集数据源回调
        *
        * @param data 采集到的 YUV 数据,格式由 fmt 决定
        * @param width 图像的宽
        * @param height 图像的高
        * @param rotation 图像的旋转角度
        * @param tsInNanoTime 时间戳   
        * @param fmt 图像的格式,参考 {@link com.qiniu.pili.droid.streaming.av.common.PLFourCC}
        * */
        boolean onPreviewFrame(byte[] data, int width, int height, int rotation, int fmt, long tsInNanoTime);
    }
    

    onPreviewFrame 会回调 NV21 格式的 YUV 数据,进行 filter 算法处理后的结果仍然保存在 bytes 数组中,SDK 会将 bytes 中的数据当作数据源进行后续的编码和封包等操作;onPreviewFrame 运行在名称为 CameraManagerHt 的子线程中;onPreviewFrame 仅在 STATE.STREAMING 状态下被回调。

    • 预览显示部分
    public interface SurfaceTextureCallback {
        void onSurfaceCreated();
        void onSurfaceChanged(int width, int height);
        void onSurfaceDestroyed();
        int onDrawFrame(int texId, int width, int height);
    }
    

    四个回调均执行在 GL rendering thread;如果 onDrawFrame 直接返回 texId,代表放弃 filter 处理,否则 onDrawFrame 应该返回一个 filter 算法处理过的纹理 id; 自定义的 Texture id,即 onDrawFrame 返回的纹理 id, 必须是 GLES20.GL_TEXTURE_2D 类型;SDK 回调的纹理 id,即 onDrawFrame 的参数 texId 类型为 GLES11Ext.GL_TEXTURE_EXTERNAL_OES。

    8. 常见的错误码

    连麦常见的错误码对照表如下:

    错误码 描述
    0 OK
    401 ERROR_UNAUTHORIZED
    404 ERROR_ROOM_NOT_FOUND
    503 ERROR_SERVICE_UNAVAILABLE
    504 ERROR_SERVER_TIMEOUT
    505 ERROR_VERSION_INVALID
    601 ERROR_ROOMID_INVALID
    602 ERROR_SERVER_AUTH_FAILED
    700 ERROR_DATABASE_ERROR
    802 ERROR_DUPLICATE_PUBLISH
    803 ERROR_ROOM_TOKEN
    804 ERROR_USER_DUPLICATE_JOIN
    1001 ERROR_FAILURE
    1002 ERROR_NOT_INITIALIZED
    1003 ERROR_ALREADY_INITIALIZED
    1006 ERROR_UNEXPECTED
    1007 ERROR_OUT_OF_MEMORY
    1008 ERROR_INVALID_ALG
    1009 ERROR_NOT_AVAILABLE
    1011 ERROR_NOT_FOUND
    1014 ERROR_TIMEOUT
    1015 ERROR_WRONG_STATUS
    1016 ERROR_NETWORK_FAILURE
    1017 ERROR_NO_TOKEN
    1018 ERROR_IMAGE_CONVERT_FAILED
    1020 ERROR_DEVICE_OCCUPIED
    2002 ERROR_NOT_JOIN_ROOM
    2003 ERROR_CAMERA_NOT_READY
    2004 ERROR_AUTH_DNSLOOKUP_FAILED
    2005 ERROR_AUTH_CONNECT_FAILED
    2006 ERROR_AUTH_HTTP_BAD_REQUEST
    2007 ERROR_AUTH_HTTP_UNAUTHORIZED
    2008 ERROR_AUTH_HTTP_NOT_FOUND
    2009 ERROR_MALFORMEDURL_EXCEPTION
    2010 ERROR_JSON_EXCEPTION
    2011 ERROR_IO_EXCEPTION

    9. 历史记录

    • 1.2.4

      • 发布了 pldroid-rtc-streaming-1.2.4.jar
      • 新增了 libpldroid_streaming_puic.so
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了 libpldroid_mmprocessing.so
      • 更新了 libpldroid_streaming_core.so
      • 新增录制时动态水印功能
      • 新增连麦远端视频数据的回调
      • 新增 QUIC 推流功能,可在 StreamingProfile 中配置开启
      • 修复偶现的保存本地的日志被删除的问题
      • 修复金立 M7 黑屏问题
      • 修复纯音频推流 pause 后无法 resume 问题
      • 修复弱网下 pause 小概率 ANR 问题
      • 优化连麦分辨率小于推流分辨率的情况下,推流画面变模糊的问题
    • 1.2.3

      • 发布了 pldroid-rtc-streaming-1.2.3.jar
      • 修复部分机型推流画面拉伸的问题
    • 1.2.2

      • 发布了 pldroid-rtc-streaming-1.2.2.jar
      • 更新了 libpldroid_mmprocessing.so
      • 新增 Camera 预览帧率设置回调接口
      • 新增 StreamingProfile 下对硬编 H.264 Profile 配置的支持
      • 新增 StreamingProfile 下 YUV resize 算法配置接口
    • 1.2.1

      • 发布了 pldroid-rtc-streaming-1.2.1.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 新增连麦多项小分辨率
      • 修复图片推流下的镜像问题
      • 修复连麦合流偶现的小窗口画面残留的问题
      • 修复图片推流下停止推流后无法重新推流的问题
      • 修复未配置码率上下限导致动态码率失控的问题
      • 修复调用 mute 之后,音量回调不生效的问题
    • 1.2.0

      • 发布了 pldroid-rtc-streaming-1.2.0.jar
      • 发布了 libpldroid_streaming_amix.so
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了 libpldroid_mmprocessing.so
      • 更新了 libpldroid_streaming_core.so
      • 新增直播连麦场景下的图片推流功能
      • 新增直播连麦场景下的返听功能
      • 新增设置音频采集源的接口
      • 新增纯连麦互动的接口
      • 修复部分场景下停止推流低概率偶现的ANR异常
      • 修复切换摄像头偶现的无法推流的问题
      • 修复开启动态码率后在部分配置下出现的马赛克问题
      • 修复超过 4.5 小时连续推流断开连接问题
      • 修复硬编 yuv 模式在某些机型颜色不正问题
      • 修复软编 1080p 推流在某些机型崩溃问题
      • 修复后台录屏推流在某些机型声音异常问题
      • 移除 CameraSourceImproved 相关接口
    • 1.1.0

      • 发布了 pldroid-rtc-streaming-1.1.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了 libpldroid_mmprocessing.so
      • 更新了 libpldroid_streaming_core.so
      • 更新了 libpldroid_streaming_aac_encoder.so
      • 更新了 libpldroid_streaming_h264_encoder.so
      • 新增流码率的自动调节/手动调节
      • 新增成功解码远端第一帧视频的事件监听回调
      • 新增获取连麦房间统计信息的接口(帧率、码率等)
      • 新增连麦合流音视频数据的回调
      • 修复软编推流 tbc 过大的问题
      • 修复停止推流/连麦低概率偶现的 ANR 的问题
      • 修复因图片的透明度导致的硬编水印异常
      • 修复极端弱网或低内存下丢关键帧导致播放花屏的问题
      • 修复连麦用户名过短导致的加会失败的问题
      • 修复开启动态码率后在部分配置下出现的马赛克问题
    • 1.0.4

      • 发布了 pldroid-rtc-streaming-1.0.4.jar
      • 更新了 libpldroid_streaming_core.so
      • 新增获取远端麦克风音量大小的回调
      • 新增关闭远端连麦者音频播放的接口
      • StreamingProfile 新增动态码率上下限配置接口
      • StreamingProfile 新增自定义动态码率相关阈值接口
      • 修复推流音频采集过程中低概率的数组越界异常
      • 修复部分场景下镜像功能不生效的问题
      • 修复部分场景下连麦失败后重连无回调消息的问题
      • 修复推流 AVCC 嵌套问题
      • 修复推流帧率配置不生效的问题
    • 1.0.3
      • 发布了 pldroid-rtc-streaming-1.0.3.jar
      • 新增检测是否支持 PK 模式连麦的接口
      • 新增部分连麦鉴权失败的错误码
      • 修复部分机型上切换摄像头后无法推流的问题
      • 修复部分机型部分场景下出现的 NPE 异常
      • 修复部分机型摄像头预览太暗的问题
      • 修复 PK 模式连麦在部分机型上出现数组越界问题
      • 修复 PK 模式连麦水印闪烁的问题
    • 1.0.2
      • 发布了 pldroid-rtc-streaming-1.0.2.jar
      • 更新 libpldroid_rtc_streaming.so
      • 更新 libpldroid_streaming_core.so
      • 更新 libpldroid_mmprocessing.so
      • 更新 libpldroid_streaming_aac_encoder.so
      • 更新 libpldroid_streaming_h264_encoder.so
      • 更新了推流 SDK 版本为 pldroid-media-streaming-2.1.2.jar
      • 在推流的 metadata 中添加了系统信息
      • 新增连麦鉴权服务器超时重连
      • 新增动态 mirror 功能
      • 修复在部分机型上预览画面太暗的问题
      • 修复在部分机型上切换摄像头画面异常和闪屏问题
      • 修复在部分机型上推流视频帧率为 0 的问题
      • 修复部分外部美颜 OpenGL 报错的问题
      • 修复硬编带来的各种稳定性问题
      • 修复弱网优化效果不明显的问题
      • 修复部分场景下停止推流产生的 crash 问题
      • 修复 onPreviewSizeSelected 不回调问题
      • 修复部分机型获取 Camera 预览帧率可能崩溃的问题
      • 修复部分机型切换连麦/推流状态导致推流花屏的问题
      • 修复部分华为机型上硬编连麦导致的崩溃问题
    • 1.0.1
      • 发布了 pldroid-rtc-streaming-1.0.1.jar
      • 更新 libpldroid_streaming_core.so
      • 更新 libpldroid_streaming_h264_encoder.so
      • 更新了推流 SDK 版本为 pldroid-media-streaming-2.1.1.jar
      • 新增截帧功能
      • 新增左右 PK 方式连麦的支持
      • 增加 AVCC 支持,解决 iOS 硬解失败问题
      • 修复弱网情况下概率性崩溃问题
      • 修复硬编模式开启 Improved 模式,导致播放端画面异常的问题
      • 修复部分机型概率性导致水印显示异常
    • 1.0.0
      • 发布了 pldroid-rtc-streaming-1.0.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了 libpldroid_streaming_h264_encoder.so
      • 更新了 libpldroid_mmprocessing.so
      • 更新了推流 SDK 版本为 PLDroidMediaStreaming v2.1.0
      • 新增纯音频连麦的支持
      • 新增推流的软硬编配置
      • 新增连麦大小窗口切换的支持
      • 新增获取连麦人数和用户列表的接口
      • 新增 RTCUserEventListener 类,通知用户加入/退出会议的消息
      • RTCVideoWindow 新增 setZOrderMediaOverlaysetZOrderOnTop 接口
      • 修复房间号前后带空格导致加入陌生房间的问题
      • 修复 WiFi 切换为 4G 后连麦小窗口画面不动的问题
      • 修复静音后退出连麦再推流没有声音的问题
      • 修复 init 初始化耗时太长的问题
      • 优化了RTCStreamingManager 的音视频数据导入接口
    • 0.6.1
      • 发布了 pldroid-rtc-streaming-0.6.1.jar
      • 修复频繁开关连麦会有资源泄漏,导致内存增长
      • 修复在某些使用姿势下出现 NULL 指针异常
    • 0.6.0
      • 发布了 pldroid-rtc-streaming-0.6.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了推流 SDK 版本为 PLDroidMediaStreaming v2.0.3
      • 新增了 ARM, ARM64v8a, X86 芯片体系架构的支持
      • 新增了横屏连麦的 demo 示例
      • 新增了断线重连的 demo 示例
      • 修复了连麦软编配置不生效的问题
      • 修复了部分情况下推流重连导致的 ANR 问题
      • 修复了部分机型上连麦音量特别小的问题
      • 修复了部分机型上拒绝摄像头权限导致的崩溃问题
    • 0.5.0
      • 发布了 pldroid-rtc-streaming-0.5.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 更新了推流 SDK 版本为 PLDroidMediaStreaming v2.0.0
      • 修复了部分场景下的连麦BUG
      • 更新 demo,调整和优化连麦参数配置
    • 0.4.0
      • 发布了 pldroid-rtc-streaming-0.4.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 支持外部音频采集
      • 支持连麦的视频图像大小的配置
      • 支持动态改变外部数据源的尺寸和角度
      • 简化了推流和连麦的接口和调用流程
    • 0.3.0
      • 发布了 pldroid-rtc-streaming-0.3.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 支持静音功能
      • 支持连麦的帧率配置
      • 支持连麦的视频码率的配置
      • 支持连麦的网络重连和超时的配置
      • 优化合流窗口的参数配置接口
      • 支持多种 Camera 的操作接口,包括:闪光灯、聚焦、水印等
      • 提供了外部美颜接口
    • 0.2.0
      • 发布了 pldroid-rtc-streaming-0.3.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 支持内部 Camera 采集,带美颜功能
      • 支持摄像头切换
      • 支持踢人功能
      • 支持修改动态库的名称
    • 0.1.0
      • 发布了 pldroid-rtc-streaming-0.3.0.jar
      • 更新了 libpldroid_rtc_streaming.so
      • 实现了基本的推流和连麦对讲功能
      • 基本的视频合流和音频混音功能
      • 支持外部 Camera 采集
      • 支持连麦状态信息回调
    以上内容是否对您有帮助?
  • 提交工单