SDK集成

如下是一个总体接入流程,详细细节请参见 RTC服务开通指南。

alt

整体实现流程
整体业务流程图

alt

核心功能实现
准备通话
时序图

alt

示例代码
 public void startCall(String appId, String bid) {
    // 创建 RTC 引擎
     mRTCVideo = RTCVideo.createRTCVideo(AppUtil.getApplicationContext(), appId, 
             mVideoEventHandler, null, null);
             
    // 采集视频:分辨率 540*960,帧率 15fps,最大码率1520kbps,最小码率300kbps
    VideoEncoderConfig config = new VideoEncoderConfig(540, 960, 15, 1520, 300);
    mRTCVideo.setVideoEncoderConfig(config);
    
    //  设置视频帧方向
    mRTCVideo.setVideoOrientation(VideoOrientation.Portrait);
    
    //  设置默认音频路由
    mRTCVideo.setDefaultAudioRoute(AudioRoute.AUDIO_ROUTE_SPEAKERPHONE); 
    
    //  设置本地视频画布
    VideoCanvas canvas = new VideoCanvas(mLocalVideoRenderView, VideoCanvas.RENDER_MODE_HIDDEN);
    mRTCVideo.setLocalVideoCanvas(StreamIndex.STREAM_INDEX_MAIN, canvas);
    
    //  设置本地视频采集,移动端默认会开启前置摄像头。
    if (userSetting.openCamera) {
        mRTCVideo.startVideoCapture();
    } else {
        mRTCVideo.stopVideoCapture();
    }
    
    // 设置本地音频采集 
    if (userSetting.openMic) {
        mRTCVideo.startAudioCapture();
    } else {
        mRTCVideo.stopAudioCapture();
    }
 }
Java
响铃
时序图

alt

示例代码
private static final int MIX_ID = 19;

public void startRinging() {
    mMixingManager = mRTCVideo == null ? null : mRTCVideo.getAudioMixingManager();
    if (mMixingManager == null || mRinging.get()) {
        return;
    }
    // 音频场景设置为媒体
    mRTCVideo.setAudioScenario(AudioScenarioType.AUDIO_SCENARIO_MEDIA);
    // 音频文件路径
    String filePathInAssets = "call_receive.mp3";
    String parentPath = AppUtil.getApplicationContext().getExternalFilesDir("assets").getAbsolutePath() + "/resource/";
    File ringMusicFile = new File(parentPath, filePathInAssets);
    if (ringMusicFile.exists()) {
        // 开始响铃
        startAudioMixing(ringMusicFile);
    } else {
        AppExecutors.networkIO().execute(() -> {
            boolean success = copyAssetFile(AppUtil.getApplicationContext(), filePathInAssets, ringMusicFile.getAbsolutePath());
            if (success) {
                startAudioMixing(ringMusicFile);
            }
        });
    }
}

public void stopRinging() {
    if (mMixingManager != null && mRinging.get()) {
        mMixingManager.stopAudioMixing(MIX_ID);
        mRinging.set(false);
    }
}

private void startAudioMixing(File ringMusicFile) {
    mMixingManager.startAudioMixing(MIX_ID, ringMusicFile.getAbsolutePath(),
            new AudioMixingConfig(AudioMixingType.AUDIO_MIXING_TYPE_PLAYOUT, -1));
    mRinging.set(true);
}
Java
进行通话
时序图

alt

示例代码
public int creteAndJoinRTCRoom(String token, String userId, String roomID, boolean autoPublish) {
    mRTCRoom = mRTCVideo.createRTCRoom(roomID);
    if (mRoomEventHandler != null) {
        mRTCRoom.setRTCRoomEventHandler(mRoomEventHandler);
    }
    RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION, autoPublish, true, true);
    return mRTCRoom.joinRoom(token, new UserInfo(userId, null), roomConfig);
}

// 远端用户加入房间后设置渲染画布。
public void onUserJoined(UserInfo userInfo, int elapsed) {
      Runnable runnable = () -> {
           setRemoteVideoCanvas(userInfo.getUid(), mLocalVideoView);
      };
      AppExecutors.execRunnableInMainThread(runnable);
}

// 切换前后置摄像头
public void switchCamera() {
    if (mRTCVideo == null) {
        return;
    }
    CameraId targetId = mCameraId == CameraId.CAMERA_ID_FRONT
            ? CameraId.CAMERA_ID_BACK
            : CameraId.CAMERA_ID_FRONT;

    mRTCVideo.setLocalVideoMirrorType(
                cameraId == CameraId.CAMERA_ID_FRONT
                        ? MirrorType.MIRROR_TYPE_RENDER_AND_ENCODER
                        : MirrorType.MIRROR_TYPE_NONE);
                                   
    mRTCVideo.switchCamera(targetId);
    
    mCameraId = targetId;
}

// 设置远端渲染画布
public void setRemoteVideoCanvas(String remoteUserId, TextureView view) {
    if (mRTCVideo == null || TextUtils.isEmpty(remoteUserId)) {
        return;
    }
    VideoCanvas canvas = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN);
    mRTCVideo.setRemoteVideoCanvas(new RemoteStreamKey(mRoomId, remoteUserId, StreamIndex.STREAM_INDEX_MAIN), canvas);
}
Java
网络状态提示

用户加入 RTC 房间后,onNetworkQuality 每 2 s 回调一次,返回本地用户和已订阅远端用户的上下行网络质量评分。 RTC 根据 NetworkQuality 的数值,对网络状况进行判定,在网络质量不好时进行提示。

示例代码
public void onNetworkQuality(NetworkQualityStats localQuality, NetworkQualityStats[] remoteQualities) {
    if (remoteQualities.length == 0) {
        return;
    }
    
    int localQuality = max(localQuality.txQuality, localQuality.rxQuality);
    int remoteQuality = max(remoteQuality.txQuality, remoteQuality.rxQuality);
    
    if (localQuality <= NetworkQuality.NETWORK_QUALITY_POOR &&
        remoteQuality <= NetworkQuality.NETWORK_QUALITY_POOR) {
        Runnable runnable = () -> {
            // 网络恢复,清除弱网提示。
        };
        AppExecutors.execRunnableInMainThread(runnable);
        return;
    }
    
    // 优先提示本地弱网状态
    if (localQuality > NetworkQuality.NETWORK_QUALITY_POOR) {
        Runnable runnable = () -> {
            // 提示本地弱网
            // 若 localQuality == NetworkQuality.NETWORK_QUALITY_VERY_BAD,提示建议用户关闭摄像头。
        };
        AppExecutors.execRunnableInMainThread(runnable);    
        return;
    }
    
    // 本地网络正常,对端网络异常,提示对端弱网
    if (remoteQuality > NetworkQuality.NETWORK_QUALITY_POOR) {
        Runnable runnable = () -> {
            // 提示对端弱网
            // 若 localQuality == NetworkQuality.NETWORK_QUALITY_VERY_BAD,提示建议用户关闭摄像头。
        };
        AppExecutors.execRunnableInMainThread(runnable);
        return;
    }    
}
Java
结束通话
时序图

alt

示例代码
public void onLeaveCall() {
    if (mRTCRoom != null) {
        mRTCRoom.leaveRoom();
        mRTCRoom.destroy();
        mRTCRoom = null;
    }
    if (mRTCVideo != null) {
        mRTCVideo.stopAudioCapture();
        mRTCVideo.stopVideoCapture();       
        RTCVideo.destroyRTCVideo();
        RTCVideo = null;
    }
}
Java
核心功能 API 与回调参考
API
功能点API
创建 ByteRTCVideo 实例createRTCVideo
设置视频发布参数SetVideoEncoderConfig
设置默认音频播放路由setDefaultAudioRoute
设置视频朝向setVideoOrientation
开启本地音频采集startAudioCapture
开启本地视频采集startVideoCapture
设置本地视频渲染setLocalVideoCanvas
获取混音管理接口getAudioMixingManager
开启 PCM 音频数据混音startAudioMixing
关闭PCM 混音disableAudioMixingFrame
创建 RTCRoom 实例createRTCRoom
设置房间事件处理器setRTCRoomEventHandler
加入 RTC 房间joinRoom
切换前后置摄像头switchCamera
开启镜像setLocalVideoMirrorType
关闭内部音频采集stopAudioCapture
关闭内部视频采集stopVideoCapture
设置视频渲染视图setRemoteVideoCanvas
离开房间leaveRoom
销毁引擎实例对象destroyRTCVideo
回调
功能点回调
用户开启音频采集onUserStartAudioCapture
用户停止音频采集onUserStopAudioCapture
用户开启视频采集onUserStartVideoCapture
用户停止视频采集onUserStopVideoCapture
用户停止视频采集onUserStopVideoCapture
音频混音文件播放状态改变onAudioMixingStateChanged
远端首帧解码onFirstRemoteVideoFrameDecoded
房间 token 即将失效回调onTokenWillExpire
本地进房成功回调onRoomStateChanged
远端可见用户加入房间onUserJoined