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

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


public void joinRoom(String roomId, String userId, String token) {
Log.d(TAG, String.format("joinRoom: %s %s %s", roomId, userId, token));
// 初始化 RTCVideo 对象
mRTCVideo = RTCVideo.createRTCVideo(Utilities.getApplicationContext(), appId, mRTCVideoEventHandler, null, null);
// 初始化 RTCRoom 对象
mRTCRoom = mRTCVideo.createRTCRoom(roomId);
mRTCRoom.setRTCRoomEventHandler(mRTCRoomEventHandler);
mRTCRoomEventHandler.setBaseClient(mRTSClient);
// 加入 RTC 房间
UserInfo userInfo = new UserInfo(userId, null);
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION,
true, true, true);
mRTCRoom.joinRoom(token, userInfo, roomConfig);
// 设置采集分辨率
VideoCaptureConfig captureConfig = new VideoCaptureConfig(720, 1280, 15);
mRTCVideo.setVideoCaptureConfig(captureConfig);
// 设置推流编码分辨率
VideoEncoderConfig config = new VideoEncoderConfig();
config.width = 720;
config.height = 1280;
config.frameRate = 15;
mRTCVideo.setVideoEncoderConfig(config);
// 开启相机和麦克风采集
mRTCVideo.startVideoCapture();
mRTCVideo.startAudioCapture();
}
/**
* RTC 业务房间相关事件回调
*/
private final RTCRoomEventHandlerWithRTS mRTCRoomEventHandler = new RTCRoomEventHandlerWithRTS() {
@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);
// 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) {
Log.d(TAG, String.format("startLiveTranscoding: %s %s %s", roomId, userId, liveUrl));
mRoomId = roomId;
LiveTranscoding liveTranscoding = LiveTranscoding.getDefualtLiveTranscode();
// 设置房间id
liveTranscoding.setRoomId(roomId);
// 设置用户id
liveTranscoding.setUserId(userId);
// 设置推流的直播地址
liveTranscoding.setUrl(liveUrl);
// 设置合流模式,0 代表服务端合流
liveTranscoding.setMixType(ByteRTCStreamMixingType.STREAM_MIXING_BY_SERVER);
// 设置合流视频参数,具体参数根据情况而定
LiveTranscoding.VideoConfig videoConfig = liveTranscoding.getVideo();
videoConfig.setWidth(mHostConfig.width);
videoConfig.setHeight(mHostConfig.height);
videoConfig.setFps(mHostConfig.frameRate);
videoConfig.setKBitRate(mHostConfig.bitRate);
liveTranscoding.setVideo(videoConfig);
// 设置合流音频参数,具体参数根据情况而定
LiveTranscoding.AudioConfig audioConfig = liveTranscoding.getAudio();
audioConfig.setSampleRate(44100);
audioConfig.setChannels(2);
liveTranscoding.setAudio(audioConfig);
// 设置合流视频布局参数
LiveTranscoding.Layout.Builder layoutBuilder = new LiveTranscoding.Layout.Builder();
LiveTranscoding.Region selfRegion = new LiveTranscoding.Region();
selfRegion.uid(userId);
selfRegion.roomId(roomId);
selfRegion.position(0, 0);
selfRegion.size(1, 1);
selfRegion.alpha(1);
selfRegion.zorder(0);
selfRegion.renderMode(LiveTranscoding.TranscoderRenderMode.RENDER_HIDDEN);
layoutBuilder.addRegion(selfRegion);
liveTranscoding.setLayout(layoutBuilder.builder());
// 开始服务端合流任务,taskid使用空字符串即可
mRTCVideo.startLiveTranscoding("", liveTranscoding, mILiveTranscodingObserver);
}
java
public void audienceOnMic(String roomId, String userId, String token) {
// 初始化 RTCVideo 对象
mRTCVideo = RTCVideo.createRTCVideo(Utilities.getApplicationContext(), appId, mRTCVideoEventHandler, null, null);
// 初始化 RTCRoom 对象
mRTCRoom = mRTCVideo.createRTCRoom(roomId);
mRTCRoom.setRTCRoomEventHandler(mRTCRoomEventHandler);
mRTCRoomEventHandler.setBaseClient(mRTSClient);
// 设置推流编码分辨率
VideoEncoderConfig config = new VideoEncoderConfig();
config.width = 250;
config.height = 250;
config.frameRate = 15;
mRTCVideo.setVideoEncoderConfig(config);
// 加入 RTC 房间
UserInfo userInfo = new UserInfo(userId, null);
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION,
true, true, true);
mRTCRoom.joinRoom(token, userInfo, roomConfig);
// 开启相机和麦克风采集
mRTCVideo.startVideoCapture();
mRTCVideo.startAudioCapture();
}
javapublic void audienceLeaveMic() {
Log.d(TAG, "audienceLeaveMic");
if (mRTCRoom != null) {
// 离开 RTC 房间
mRTCRoom.leaveRoom();
// 释放 rtcRoom 对象
mRTCRoom.destroy();
mRTCRoom = null;
}
if (mRTCVideo != null) {
// 关闭相机和麦克风采集
mRTCVideo.stopVideoCapture();
mRTCVideo.stopAudioCapture();
mRTCVideo = null;
}
}
java
public void startForwardStreamToRooms(String coHostRoomId, String coHostUserId, String token,
String selfRoomId, String selfUserId, String pushUrl) {
// 开启跨房转推
// 使用 mCoHostInfo 记录对方主播信息
mCoHostInfo = new LiveTranscodingInfo(pushUrl, selfRoomId, selfUserId, coHostRoomId, coHostUserId);
ForwardStreamInfo forwardStreamInfo = new ForwardStreamInfo(coHostRoomId, token);
if (mRTCRoom != null) {
mRTCRoom.startForwardStreamToRooms(Collections.singletonList(forwardStreamInfo));
}
}
/**
* RTC 业务加房事件回调
*/
private final RTCRoomEventHandlerWithRTS mRTCRoomEventHandler = new RTCRoomEventHandlerWithRTS() {
@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) {
if (mRTCVideo == null) {
return;
}
LiveTranscoding liveTranscoding = LiveTranscoding.getDefualtLiveTranscode();
// 设置房间id
liveTranscoding.setRoomId(selfRoomId);
// 设置推流的直播地址
liveTranscoding.setUrl(liveUrl);
// 设置合流模式
liveTranscoding.setMixType(ByteRTCStreamMixingType.STREAM_MIXING_BY_SERVER);
// 设置合流视频参数,具体参数根据情况而定
LiveTranscoding.VideoConfig videoConfig = liveTranscoding.getVideo();
videoConfig.setWidth(mFrameWidth);
videoConfig.setHeight(mFrameHeight);
videoConfig.setFps(mFrameRate);
videoConfig.setKBitRate(mBitrate);
liveTranscoding.setVideo(videoConfig);
// 设置合流音频参数,具体参数根据情况而定
LiveTranscoding.AudioConfig audioConfig = liveTranscoding.getAudio();
audioConfig.setSampleRate(44100);
audioConfig.setChannels(2);
liveTranscoding.setAudio(audioConfig);
LiveTranscoding.Layout.Builder layoutBuilder = new LiveTranscoding.Layout.Builder();
LiveTranscoding.Region selfRegion = new LiveTranscoding.Region();
selfRegion.uid(selfUserId);
selfRegion.roomId(selfRoomId);
selfRegion.position(0, 0.25); // 设置用户视频布局的相对位置,取值范围[0, 1],(0,0)为左上角,根据实际情况调整
selfRegion.size(0.5, 0.5); // 设置用户视频相对大小,取值范围[0, 1],根据实际情况调整
selfRegion.alpha(1); // 设置透明度,取值范围[0, 1],0代表完全透明
selfRegion.zorder(0); // 设置用户视频布局在画布中的层级,取值范围为[0 - 100]。0为底层,值越大越上层。
layoutBuilder.addRegion(selfRegion);
LiveTranscoding.Region hostRegion = new LiveTranscoding.Region();
hostRegion.uid(coHostUserId);
hostRegion.roomId(selfRoomId);
hostRegion.position(0.5, 0.25);
hostRegion.size(0.5, 0.5);
hostRegion.alpha(1);
hostRegion.zorder(0);
layoutBuilder.addRegion(hostRegion);
liveTranscoding.setLayout(layoutBuilder.builder());
liveTranscoding.setLayout(layoutBuilder.builder());
mRTCVideo.updateLiveTranscoding("", liveTranscoding);
}
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 |