如下是一个总体接入流程,详细细节请参见 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);//设置合流视频宽度。单位为 px,范围为 [2, 1920],必须是偶数。默认值为 640 px。 设置值为非偶数时,自动向上取偶数 videoConfig.setHeight(mHostConfig.height);//设置合流视频高度。单位为 px,范围为 [2, 1920],必须是偶数。默认值为 360 px。 设置值为非偶数时,自动向上取偶数 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);//设置本地主播画面左上角在整个画布坐标系中的 X 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的横向位移,取值范围为 [0, 整体画布宽度) localRegionConfig.setLocationY(0);//设置本地主播画面左上角在整个画布坐标系中的 Y 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的纵向位移,取值范围为 [0, 整体画布高度) localRegionConfig.setWidth(mHostConfig.width);//设置本地主播画面宽度。取值范围为 [0, 整体画布宽度],默认值为 360 localRegionConfig.setHeight(mHostConfig.height);//设置本地主播画面高度。取值范围为 [0, 整体画布高度],默认值为 640 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); }
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(); }
public 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; } }
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);// 设置合流视频宽度。单位为 px,范围为 [2, 1920],必须是偶数。默认值为 640 px。 设置值为非偶数时,自动向上取偶数 videoConfig.setHeight(mHostConfig.height);//设置合流视频高度。单位为 px,范围为 [2, 1920],必须是偶数。默认值为 360 px。 设置值为非偶数时,自动向上取偶数 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);// 设置本地主播画面左上角在整个画布坐标系中的 X 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的横向位移。取值范围为 [0, 整体画布宽度) localRegion.setLocationY(0.25);// 设置本地主播画面左上角在整个画布坐标系中的 Y 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的纵向位移。取值范围为 [0, 整体画布高度) localRegion.setWidth((int) (mHostConfig.width * 0.5));//用户画面宽度。取值范围为 [0, 整体画布宽度],默认值为 360 localRegion.setHeight((int) (mHostConfig.height * 0.5));//用户画面高度。取值范围为 [0, 整体画布高度],默认值为 640 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);// 设置远端主播画面左上角在整个画布坐标系中的 X 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的横向位移。取值范围为 [0, 整体画布宽度) hostRegion.setLocationY(0.25);// 设置远端主播画面左上角在整个画布坐标系中的 Y 坐标(pixel),即以画布左上角为原点,用户画面左上角相对于原点的纵向位移。取值范围为 [0, 整体画布高度) localRegion.setWidth((int) (mHostConfig.width * 0.5));//远端主播画面宽度。取值范围为 [0, 整体画布宽度],默认值为 360 localRegion.setHeight((int) (mHostConfig.height * 0.5));//远端主播画面高度。取值范围为 [0, 整体画布高度],默认值为 640 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); }
功能点 | 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 |