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



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
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
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 的数值,对网络状况进行判定,在网络质量不好时进行提示。
onNetworkTypeChanged(kNetworkTypeDisconnected) 会立即触发。onConnectionStateChanged(kConnectionStateDisconnected) 回调通知连接断开。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
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 |
|---|---|
| 创建 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 |