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

主播与主播进行 PK
主播与观众进行连麦


public void joinRoom(String roomId, String userId, String token) {
Log.d(TAG, String.format("joinRoom: %s %s %s", roomId, userId, token));
// 初始化 RTCVideo 对象
// Initialize the RTCVideo object
mRTCVideo = RTCVideo.createRTCVideo(Utilities.getApplicationContext(), appId, mRTCVideoEventHandler, null, null);
// 初始化 RTCRoom 对象
// Initialize the RTCRoom object
mRTCRoom = mRTCVideo.createRTCRoom(roomId);
mRTCRoom.setRTCRoomEventHandler(mRTCRoomEventHandler);
mRTCRoomEventHandler.setBaseClient(mRTSClient);
// 加入 RTC 房间
// join the RTC room
UserInfo userInfo = new UserInfo(userId, null);
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION,
true, true, true);
mRTCRoom.joinRoom(token, userInfo, roomConfig);
// 设置采集分辨率
// Set the video capture config
VideoCaptureConfig captureConfig = new VideoCaptureConfig(720, 1280, 15);
mRTCVideo.setVideoCaptureConfig(captureConfig);
// 设置推流编码分辨率
// Set the video encoder config
VideoEncoderConfig config = new VideoEncoderConfig();
config.width = 720;
config.height = 1280;
config.frameRate = 15;
mRTCVideo.setVideoEncoderConfig(config);
// 开启相机和麦克风采集
// Start video and audio capture
mRTCVideo.startVideoCapture();
mRTCVideo.startAudioCapture();
}
/**
* RTC 业务房间相关事件回调
*/
private final IRTCRoomEventHandler mRTCRoomEventHandler = new IRTCRoomEventHandler() {
@Override
public void onRoomStateChanged(String roomId, String uid, int state, String extraInfo) {
super.onRoomStateChanged(roomId, uid, state, extraInfo);
Log.d(TAG, String.format("onRoomStateChanged: %s, %s, %d, %s", roomId, uid, state, extraInfo));
mRoomId = roomId;
if (isFirstJoinRoomSuccess(state, extraInfo)) {
// mSingleLiveInfo 记录了主播的直播信息
if (mSingleLiveInfo != null) {
startLiveTranscoding(roomId, uid, mSingleLiveInfo.pushUrl);
}
}
}
/**
* 判断 onRoomStateChanged 中的extraInfo,是不是首次加入房间成功
*
* @param extraInfo 额外信息
* @return true:加入房间成功
*/
protected boolean isFirstJoinRoomSuccess(int state, String extraInfo) {
int joinType = -1;
try {
JSONObject json = new JSONObject(extraInfo);
// 341后 SDK传的固定键 joinType表示加入房间的类型,0为首次进房,1为重连进房。
joinType = json.getInt("join_type");
} catch (Exception e) {
e.printStackTrace();
}
return joinType == 0 && state == 0;
}
}
/**
* 开启合流转推
* @param roomId 房间id
* @param userId 用户id
* @param liveUrl rtmp 推流地址
*/
private void startLiveTranscoding(String roomId, String userId, String liveUrl,String taskId) {
MixedStreamConfig config = MixedStreamConfig.defaultMixedStreamConfig();
config.setRoomID(roomId);
config.setUserID(userId);
config.setPushURL(liveUrl);
config.setExpectedMixingType(ByteRTCStreamMixingType.STREAM_MIXING_BY_SERVER);
//设置合流视频参数,具体参数根据情况而定
MixedStreamVideoConfig videoConfig = config.getVideoConfig();
videoConfig.setWidth(mHostConfig.width);
videoConfig.setHeight(mHostConfig.height);
videoConfig.setFps(mHostConfig.frameRate);
videoConfig.setBitrate(mHostConfig.bitRate);
config.setVideoConfig(videoConfig);
//设置合流音频参数,具体参数根据情况而定
MixedStreamAudioConfig audioConfig = config.getAudioConfig();
audioConfig.setSampleRate(44100);
audioConfig.setChannels(2);
config.setAudioConfig(audioConfig);
//设置合流视频布局参数
MixedStreamLayoutRegionConfig localRegionConfig = new MixedStreamLayoutRegionConfig();
localRegionConfig.setUserID(userId);
localRegionConfig.setIsLocalUser(true);
localRegionConfig.setRoomID(roomId);
localRegionConfig.setLocationX(0);
localRegionConfig.setLocationY(0);
localRegionConfig.setWidthProportion(1);
localRegionConfig.setHeightProportion(1);
localRegionConfig.setAlpha(1);
localRegionConfig.setZOrder(0);
localRegionConfig.setRenderMode(MixedStreamRenderMode.MIXED_STREAM_RENDER_MODE_HIDDEN);
MixedStreamLayoutRegionConfig[] regions = new MixedStreamLayoutRegionConfig[]{localRegionConfig};
MixedStreamLayoutConfig layoutConfig = new MixedStreamLayoutConfig();
layoutConfig.setRegions(regions);
JsonObject json = new JsonObject();
json.addProperty(KEY_SEI_KEY_SOURCE, KEY_SEI_VALUE_SOURCE_NONE);
//设置SEI信息
layoutConfig.setUserConfigExtraInfo(json.toString());
config.setLayout(layoutConfig);
//开始合流任务
mRTCVideo.startPushMixedStreamToCDN(taskId, config, mMixedStreamObserver);
}
Java
public void audienceOnMic(String roomId, String userId, String token) {
// 初始化 RTCVideo 对象
// Initialize the RTCVideo object
mRTCVideo = RTCVideo.createRTCVideo(Utilities.getApplicationContext(), appId, mRTCVideoEventHandler, null, null);
// 初始化 RTCRoom 对象
// Initialize the RTCRoom object
mRTCRoom = mRTCVideo.createRTCRoom(roomId);
mRTCRoom.setRTCRoomEventHandler(mRTCRoomEventHandler);
mRTCRoomEventHandler.setBaseClient(mRTSClient);
// 设置推流编码分辨率
// Set the video encoder config
VideoEncoderConfig config = new VideoEncoderConfig();
config.width = 250;
config.height = 250;
config.frameRate = 15;
mRTCVideo.setVideoEncoderConfig(config);
// 加入 RTC 房间
// join the RTC room
UserInfo userInfo = new UserInfo(userId, null);
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION,
true, true, true);
mRTCRoom.joinRoom(token, userInfo, roomConfig);
// 开启相机和麦克风采集
// Start video and audio capture
mRTCVideo.startVideoCapture();
mRTCVideo.startAudioCapture();
}
Javapublic void audienceLeaveMic() {
Log.d(TAG, "audienceLeaveMic");
if (mRTCRoom != null) {
// 离开 RTC 房间
// Leave the RTC room
mRTCRoom.leaveRoom();
// 释放 rtcRoom 对象
// destroy the rtcRoom object
mRTCRoom.destroy();
mRTCRoom = null;
}
if (mRTCVideo != null) {
// 关闭相机和麦克风采集
// Stop video and audio capture
mRTCVideo.stopVideoCapture();
mRTCVideo.stopAudioCapture();
mRTCVideo = null;
}
}
Java
public void startForwardStreamToRooms(String coHostRoomId, String coHostUserId, String token,
String selfRoomId, String selfUserId, String pushUrl) {
// 开启跨房转推
// Enable span the room retweet stream
// 使用 mCoHostInfo 记录对方主播信息
mCoHostInfo = new MixedStreamInfo(pushUrl, selfRoomId, selfUserId, coHostRoomId, coHostUserId);
ForwardStreamInfo forwardStreamInfo = new ForwardStreamInfo(coHostRoomId, token);
if (mRTCRoom != null) {
mRTCRoom.startForwardStreamToRooms(Collections.singletonList(forwardStreamInfo));
}
}
/**
* RTC 业务加房事件回调
*/
private final IRTCRoomEventHandler mRTCRoomEventHandler = new IRTCRoomEventHandler() {
@Override
public void onUserPublishStream(String uid, MediaStreamType type) {
super.onUserPublishStream(uid, type);
if (type == MediaStreamType.RTC_MEDIA_STREAM_TYPE_AUDIO) {
return;
}
// 主播连麦
if (mCoHostInfo != null && TextUtils.equals(uid, mCoHostInfo.coHostUserId)) {
updateLiveTranscodingWithHost(mCoHostInfo.pushUrl, mCoHostInfo.selfRoomId, mCoHostInfo.selfUserId,
mCoHostInfo.coHostUserId);
}
}
};
/**
* 更新合流转推布局
* @param selfRoomId 房间id
* @param selfUserId 自己的用户Id
* @param coHostRoomId 对方房间id
* @param coHostUserId 对方主播的用户Id
*/
public void updateLiveTranscodingWithHost( String liveUrl,
String selfRoomId,
String selfUserId,
String coHostUserId,
String taskId) {
if (mRTCVideo == null) {
return;
}
MixedStreamConfig config = MixedStreamConfig.defaultMixedStreamConfig();
// 设置房间id
config.setRoomID(selfRoomId);
// 设置推流的直播地址
config.setPushURL(liveUrl);
// 设置合流模式
config.setExpectedMixingType(ByteRTCStreamMixingType.STREAM_MIXING_BY_SERVER);
//设置合流视频参数,具体参数根据情况而定
MixedStreamVideoConfig videoConfig = config.getVideoConfig();
videoConfig.setWidth(mHostConfig.width);
videoConfig.setHeight(mHostConfig.height);
videoConfig.setFps(mHostConfig.frameRate);
videoConfig.setBitrate(mHostConfig.bitRate);
//设置合流音频参数,具体参数根据情况而定
MixedStreamAudioConfig audioConfig = config.getAudioConfig();
audioConfig.setSampleRate(44100);
audioConfig.setChannels(2);
MixedStreamLayoutConfig layoutConfig = new MixedStreamLayoutConfig();
//设置本地主播的UI属性
LiveTranscoding.Layout.Builder layoutBuilder = new LiveTranscoding.Layout.Builder();
MixedStreamLayoutRegionConfig localRegion = new MixedStreamLayoutRegionConfig();
localRegion.setUserID(selfUserId);
localRegion.setIsLocalUser(true);
localRegion.setRoomID(selfRoomId);
localRegion.setLocationX(0);// 设置用户视频布局的横向相对位置
localRegion.setLocationY(0.25);// 设置用户视频布局的竖向相对位置
localRegion.setWidthProportion(0.5);// 设置用户视频宽度相对大小
localRegion.setHeightProportion(0.5);// 设置用户视频高度相对大小
localRegion.setAlpha(1);// 设置透明度,取值范围[0, 1],0代表完全透明
localRegion.setZOrder(0);// 设置用户视频布局在画布中的层级,取值范围为[0 - 100]。0为底层,值越大越上层。
//设置对端主播的UI属性
MixedStreamLayoutRegionConfig hostRegion = new MixedStreamLayoutRegionConfig();
hostRegion.setUserID(coHostUserId);
hostRegion.setIsLocalUser(false);
hostRegion.setRoomID(selfRoomId);
hostRegion.setLocationX(0.5);
hostRegion.setLocationY(0.25);
hostRegion.setWidthProportion(0.5);
hostRegion.setHeightProportion(0.5);
hostRegion.setAlpha(1);
hostRegion.setZOrder(0);
JsonObject json = new JsonObject();
json.addProperty(KEY_SEI_KEY_SOURCE, KEY_SEI_VALUE_SOURCE_NONE);
//设置SEI信息
layoutConfig.setUserConfigExtraInfo(json.toString());
layoutConfig.setRegions(new MixedStreamLayoutRegionConfig[]{localRegion});
config.setLayout(layoutConfig);
mRTCVideo.updatePushMixedStreamToCDN(taskId, config);
}
Java| 功能点 | API |
|---|---|
| 创建 ByteRTCVideo 实例 | createRTCVideo |
| 创建 ByteRTCRoom 实例 | createRTCRoom |
| 设置相机采集参数 | setVideoCaptureConfig |
| 设置视频发布参数 | setVideoEncoderConfig |
| 设置镜像 | setLocalVideoMirrorType |
| 获取合流转推默认配置参数 | LiveTranscoding.getDefualtLiveTranscode |
| 加入RTC房间 | joinRoom |
| 离开RTC房间 | leaveRoom |
| 销毁房间对象 | destroy |
| 开启合流转推 | startLiveTranscoding |
| 更新合流转推参数 | updateLiveTranscoding |
| 关闭合流转推 | stopLiveTranscoding |
| 开启跨房间转推 | startForwardStreamToRooms: |
| 关闭跨房间转推 | stopForwardStreamToRooms |
| 开启相机采集 | startVideoCapture |
| 关闭相机采集 | stopVideoCapture |
| 开启麦克风采集 | startAudioCapture |
| 关闭麦克风采集 | stopAudioCapture |
| 切换前置/后置摄像头 | switchCamera |
| 暂停接收来自远端的媒体流 | pauseAllSubscribedStream |
| 恢复接收来自远端的媒体流 | resumeAllSubscribedStream |
| 功能点 | 回调 |
|---|---|
| 本地用户加入 RTC 回调 | onRoomStateChanged |
| 远端用户加入 RTC 回调 | onUserJoined |
| 收到远端用户音视频流回调 | onUserPublishStream |
| 本地流数据统计以及网络质量回调 | onLocalStreamStats |
| 远端流数据统计以及网络质量回调 | onRemoteStreamStats |