适用场景
在 CDN 直播观看 和 云端录制回放 等应用场景中,常需要将 TRTC 房间里的多路音视频流混合成一路,您可以使用腾讯云服务端的 MCU 的混流转码集群完成该项工作。MCU 集群能将多路音视频流进行按需混合,并将最终生成的视频流分发给直播 CDN 和云端录制系统。
云端混流有两种控制方式:
方案一:使用服务端 REST 接口 StartMCUMixTranscode(数字房间号版本 / 字符串房间号版本)和 StopMCUMixTranscode(数字房间号版本 / 字符串房间号版本)进行控制,该接口还可以同时支持启动 CDN 观看和发起旧版云端录制功能。
方案二:使用客户端 TRTC SDK 的 setMixTranscodingConfig 接口进行控制,其原理如下图:
注意
方案二支持 iOS、Android、Windows、Mac、Electron、Flutter 和 Web 平台的 SDK,如果您希望在微信小程序上也实现混流功能,请使用方案一。
原理解析
云端混流包含解码、混合和再编码三个过程:
解码:MCU 需要将多路音视频流进行解码,包括视频解码和音频解码。
混合:MCU 需要将多路画面混合在一起,并根据来自 SDK 的混流指令实现具体 的排版方案。同时,MCU 也需要将解码后的多路音频信号进行混音处理。
编码:MCU 需要将混合后的画面和声音进行二次编码,并封装成一路音视频流,交给下游系统(例如直播和录制)。
方案一:服务端 REST API 混流方案
启动混流
步骤1:设置画面排版模式(必需)
悬浮模板(LayoutParams.Template = 0)
第一个进入房间的用户的视频画面会铺满整个屏幕,其他用户的视频画面从左下角依次水平排列,显示为小画面。
最多4行,每行最多4个,小画面悬浮于大画面之上。
最多支持1个大画面和15个小画面。
如果用户只发送音频,仍然会占用画面位置。
九宫格模板(LayoutParams.Template = 1)
所有用户的视频画面大小一致,平分整个屏幕,人数越多,每个画面的尺寸越小。
最多支持16个画面,如果用户只发送音频,仍然会占用画面位置。
屏幕分享模板(LayoutParams.Template = 2)
适合视频会议和在线教育场景的布局。
屏幕分享(或者主讲的摄像头)始终占据屏幕左侧的大画面位置,其他用户依次垂直排列于右侧。
需要通过
LayoutParams.MainVideoUserId
和 LayoutParams.MainVideoStreamType
这两个参数来指定左侧主画面的内容。最多两列,每列最多8个小画面。最多支持1个大画面和15个小画面。
如果用户只发送音频,仍然会占用画面位置。
画中画模板(LayoutParams.Template = 3)
该模板以“一大一小,一前一后”的模式混合房间中的两路画面,即将房间中一路画面铺满整个屏幕,再将一路画面作为小画面悬浮在大画面之上,小画面的位置可以通过参数指定。
您可以通过
LayoutParams
中的 MainVideoUserId
和 MainVideoStreamType
参数指定大画面这一路的用户 ID 和流类型。您可以通过
LayoutParams
中的 SmallVideoLayoutParams
参数指定小画面这一路的用户 ID、流类型和布局位置等信息。场景示例1:在线教育场景中,混合老师端摄像头(通常作为小画面)和老师端屏幕(通常作为大画面)两路画面,并混合课堂中学生的声音。
场景示例2:1v1 视频通话场景中,混合远端用户画面(通常作为大画面)和本地用户画面(通常作为小画面)。
自定义模板(LayoutParams.Template = 4)
适用于需要自定义排布各路画面位置的场景,您可以通过
LayoutParams
中的 PresetLayoutConfig
参数(这是一个数组),预先设置各路画面的位置。您可以不指定
PresetLayoutConfig
参数中的 UserId
参数,排版引擎会根据进房的先后顺序,将进房的用户依次分配到 PresetLayoutConfig
数组中指定的各个位置上。如果
PresetLayoutConfig
数组中的某一个被指定了 UserId
参数,则排版引擎会预先给指定的用户预留好他/她在画面中的位置。如果用户只上行音频,不上行视频,该用户依然会占用画面位置。
当
PresetLayoutConfig
数组中预设的位置被用完后,排版引擎将不再混合其他用户的画面和声音。注意:
云端混流服务最多支持同时混合16路音视频流,如果用户只有音频也会被算作一路。
步骤2:设置混流编码参数(必需)
名称 | 描述 | 推荐值 |
AudioSampleRate | 混流-输出流音频采样率 | 48000 |
AudioBitrate | 混流-输出流音频码率,单位 kbps | 64 |
AudioChannels | 混流-输出流音频声道数 | 2 |
VideoWidth | 混流-输出流宽,音视频输出时必填 | 自定义 |
VideoHeight | 混流-输出流高,音视频输出时必填 | 自定义 |
VideoBitrate | 混流-输出流码率,单位 kbps,音视频输出时必填 | 自定义 |
VideoFramerate | 混流-输出流帧率,音视频输出时必填 | 15 |
VideoGop | 混流-输出流 GOP,音视频输出时必填 | 3 |
BackgroundColor | 混流-输出流背景色 | 自定义 |
步骤3:指定混合后的 streamID(必需)
OutputParams.StreamId
通过该参数您可以指定混合后的音视频流在直播 CDN 上的 streamID。不过只有在您已经开通了直播服务并配置了播放域名的情况下,才能通过 CDN 正常观看这条直播流。
OutputParams.PureAudioStream
如果您只希望做纯音频直播,可以设置
OutputParams.PureAudioStream
参数为 1,代表仅把混音后的音频数据流转发到 CDN 上。步骤4:设置是否开启云端录制(可选)
OutputParams.RecordAudioOnly
如果您只希望录制音频而不需要视频内容,可以设置
OutputParams.RecordAudioOnly
参数为1,表示仅录制 MP3 格式的文件。说明:
自2022年08月01日起,新创建应用请参考新版云端录制功能说明发起录制,StartMCUMixTranscode仅可用于旧版云端录制功能应用发起录制。如需确认当前应用的云端录制功能类型请参见新、旧录制功能类型判断方式。
结束混流
方案二:客户端 SDK API 混流方案
参数项 | 纯音频模式(PureAudio) | 预排版模式(PresetLayout) | 屏幕分享模式(ScreenSharing) | 全手动模式(Manual) |
调用次数 | 只需调用一次接口 | 只需调用一次接口 | 只需调用一次接口 | 以下场景需调用混流接口: 有连麦者加入时 有连麦者离开时 连麦者开关摄像头时 连麦者开关麦克风时 |
混合内容 | 只混合音频 | 自定义设置各路内容 | 不混合学生端的画面 | 自定义设置各路内容 |
audioSampleRate | 推荐48000 | 推荐48000 | 推荐48000 | 推荐48000 |
audioBitrate | 推荐64 | 推荐64 | 推荐64 | 推荐64 |
audioChannels | 推荐2 | 推荐2 | 推荐2 | 推荐2 |
videoWidth | 无需设置 | 不能为0 | 推荐0 | 不能为0 |
videoHeight | 无需设置 | 不能为0 | 推荐0 | 不能为0 |
videoBitrate | 无需设置 | 不能为0 | 推荐0 | 不能为0 |
videoFramerate | 无需设置 | 推荐15 | 推荐15 | 推荐15 |
videoGOP | 无需设置 | 推荐3 | 推荐3 | 推荐3 |
mixUsers 数组 | 无需设置 | 使用占位符设置 | 无需设置 | 使用真实 userId 设置 |
纯音频模式(PureAudio)
适用场景
纯音频模式适用于语音通话(AudioCall)和语音聊天室(VoiceChatRoom)等纯音频应用场景,该类场景下您可以在调用 SDK 的 enterRoom 接口时进行设定。
纯音频模式下,SDK 会自动将房间里的多路音频流混合成一路。
使用步骤
1. 在调用
enterRoom()
函数进入房间时,根据您的业务需要,设定 AppScene 参数为 TRTCAppSceneAudioCall
或 TRTCAppSceneVoiceChatRoom
,明确当前房间中没有视频且只有音频。2. 开启 旁路直播,并设定 TRTCParams 中的
streamId
参数,指定 MCU 输出的混合音频流的去处。3. 调用
startLocalAudio()
开启本地音频采集和音频上行。说明
由于云端混流的本质是将多路流混合到当前(即发起混流指令的)用户所对应的音视频流上,因此当前用户本身必须有音频上行才能构成混流的前提条件。
4. 调用
setMixTranscodingConfig()
接口启动云端混流,需要您在调用时将 TRTCTranscodingConfig
中的 mode
参数设定为 TRTCTranscodingConfigMode_Template_PureAudio,并指定 audioSampleRate
、audioBitrate
和 audioChannels
等关乎音频输出质量的参数。注意
纯音频模式下
setMixTranscodingConfig()
接口无需多次调用,在进房成功并开启本地音频上行后调用一次即可。预排版模式(PresetLayout)
适用场景
预排版模式适用于视频通话(VideoCall)和互动直播(LIVE)等音频和视频皆有的应用场景,该类场景下您可以在调用 SDK 的 enterRoom 接口时进行设定。
预排版模式下,SDK 会自动按照您预先设定各路画面的排版规则将房间里的多路音频流混合成一路。
使用步骤
1. 在调用
enterRoom()
函数进入房间时,根据您的业务需要,设定 AppScene 参数为 TRTCAppSceneVideoCall
或 TRTCAppSceneLIVE
。2. 开启 旁路直播,并设定 TRTCParams 中的
streamId
参数,指定 MCU 输出的混合音频流的去处。3. 调用
startLocalPreview()
和 startLocalAudio()
开启本地的音视频上行。说明
由于云端混流的本质是将多路流混合到当前(即发起混流指令的)用户所对应的音视频流上,因此当前用户本身必须有音视频上行才能构成混流的前提条件。
4. 调用
setMixTranscodingConfig()
接口启动云端混流,需要您在调用时将 TRTCTranscodingConfig
中的 mode
参数设定为 TRTCTranscodingConfigMode_Template_PresetLayout ,并指定 audioSampleRate
、audioBitrate
和 audioChannels
等关乎音频输出质量的参数,以及 videoWidth
、videoHeight
、videoBitrate
、videoFramerate
等关乎视频输出质量的参数。5. 组装
mixUser
参数,预排版模式下 mixUser
中的 userId
参数请使用 $PLACE_HOLDER_REMOTE$、$PLACE_HOLDER_LOCAL_MAIN$ 以及 $PLACE_HOLDER_LOCAL_SUB$ 这三个占位字符串,其含义如下表所示:占位符 | 含义 | 是否支持多个 |
$PLACE_HOLDER_LOCAL_MAIN$ | 指代本地摄像头这一路 | 不支持 |
$PLACE_HOLDER_LOCAL_SUB$ | 指代本地屏幕分享这一路(只有画面) | 不支持 |
$PLACE_HOLDER_REMOTE$ | 指代远端连麦者,可以同时设置多个 | 支持 |
示例代码
您可根据下面的示例代码实现“一大二小,上下叠加”的混合效果:
TRTCTranscodingConfig *config = [[TRTCTranscodingConfig alloc] init];// 设置分辨率为720 × 1280, 码率为1500kbps,帧率为20FPSconfig.videoWidth = 720;config.videoHeight = 1280;config.videoBitrate = 1500;config.videoFramerate = 20;config.videoGOP = 2;config.audioSampleRate = 48000;config.audioBitrate = 64;config.audioChannels = 2;// 采用预排版模式config.mode = TRTCTranscodingConfigMode_Template_PresetLayout;NSMutableArray *mixUsers = [NSMutableArray new];// 主播摄像头的画面位置TRTCMixUser* local = [TRTCMixUser new];local.userId = @"$PLACE_HOLDER_LOCAL_MAIN$";local.zOrder = 0; // zOrder 为0代表主播画面位于最底层local.rect = CGRectMake(0, 0, videoWidth, videoHeight);local.roomID = nil; // 本地用户不用填写 roomID,远程需要[mixUsers addObject:local];// 连麦者的画面位置TRTCMixUser* remote1 = [TRTCMixUser new];remote1.userId = @"$PLACE_HOLDER_REMOTE$";remote1.zOrder = 1;remote1.rect = CGRectMake(400, 800, 180, 240); //仅供参考remote1.roomID = @"97392"; // 本地用户不用填写 roomID,远程需要[mixUsers addObject:remote1];// 连麦者的画面位置TRTCMixUser* remote2 = [TRTCMixUser new];remote2.userId = @"$PLACE_HOLDER_REMOTE$";remote2.zOrder = 1;remote2.rect = CGRectMake(400, 500, 180, 240); //仅供参考remote2.roomID = @"97392"; // 本地用户不用填写 roomID,远程需要[mixUsers addObject:remote2];config.mixUsers = mixUsers;// 发起云端混流[_trtc setMixTranscodingConfig:config];
TRTCCloudDef.TRTCTranscodingConfig config = new TRTCCloudDef.TRTCTranscodingConfig();// 设置分辨率为720 × 1280, 码率为1500kbps,帧率为20FPSconfig.videoWidth = 720;config.videoHeight = 1280;config.videoBitrate = 1500;config.videoFramerate = 20;config.videoGOP = 2;config.audioSampleRate = 48000;config.audioBitrate = 64;config.audioChannels = 2;// 采用预排版模式config.mode = TRTCCloudDef.TRTC_TranscodingConfigMode_Template_PresetLayout;config.mixUsers = new ArrayList<>();// 主播摄像头的画面位置TRTCCloudDef.TRTCMixUser local = new TRTCCloudDef.TRTCMixUser();local.userId = "$PLACE_HOLDER_LOCAL_MAIN$";local.zOrder = 0; // zOrder 为0代表主播画面位于最底层local.x = 0;local.y = 0;local.width = videoWidth;local.height = videoHeight;local.roomId = null; // 本地用户不用填写 roomID,远程需要config.mixUsers.add(local);// 连麦者的画面位置TRTCCloudDef.TRTCMixUser remote1 = new TRTCCloudDef.TRTCMixUser();remote1.userId = "$PLACE_HOLDER_REMOTE$";remote1.zOrder = 1;remote1.x = 400; //仅供参考remote1.y = 800; //仅供参考remote1.width = 180; //仅供参考remote1.height = 240; //仅供参考remote1.roomId = "97392"; // 本地用户不用填写 roomID,远程需要config.mixUsers.add(remote1);// 连麦者的画面位置TRTCCloudDef.TRTCMixUser remote2 = new TRTCCloudDef.TRTCMixUser();remote2.userId = "$PLACE_HOLDER_REMOTE$";remote2.zOrder = 1;remote1.x = 400; //仅供参考remote1.y = 500; //仅供参考remote1.width = 180; //仅供参考remote1.height = 240; //仅供参考remote1.roomId = "97393"; // 本地用户不用填写 roomID,远程需要config.mixUsers.add(remote2);// 发起云端混流trtc.setMixTranscodingConfig(config);
TRTCTranscodingConfig config;// 设置分辨率为1280 × 720, 码率为1500kbps,帧率为20fpsconfig.videoWidth = 1280;config.videoHeight = 720;config.videoBitrate = 1500;config.videoFramerate = 20;config.videoGOP = 2;config.audioSampleRate = 48000;config.audioBitrate = 64;config.audioChannels = 2;// 采用预排版模式config.mode == TRTCTranscodingConfigMode_Template_PresetLayoutTRTCMixUser* mixUsersArray = new TRTCMixUser[3];mixUsersArray[0].userId = "$PLACE_HOLDER_LOCAL_MAIN$";mixUsersArray[0].zOrder = 0; // zOrder 为0代表主播画面位于最底层mixUsersArray[0].rect.left = 0;mixUsersArray[0].rect.top = 0;mixUsersArray[0].rect.right = videoWidth;mixUsersArray[0].rect.bottom = videoHeight;mixUsersArray[0].roomId = nullptr; // 本地用户不用填写 roomID,远程需要mixUsersArray[1].userId = "$PLACE_HOLDER_REMOTE$";mixUsersArray[1].zOrder = 1;mixUsersArray[1].rect.left = 400; //仅供参考mixUsersArray[1].rect.top = 800; //仅供参考mixUsersArray[1].rect.right = 180; //仅供参考mixUsersArray[1].rect.bottom = 240; //仅供参考mixUsersArray[1].roomId = "97392"; // 本地用户不用填写 roomID,远程需要mixUsersArray[2].userId = "$PLACE_HOLDER_REMOTE$";mixUsersArray[2].zOrder = 1;mixUsersArray[2].rect.left = 400; //仅供参考mixUsersArray[2].rect.top = 500; //仅供参考mixUsersArray[2].rect.right = 180; //仅供参考mixUsersArray[2].rect.bottom = 240; //仅供参考mixUsersArray[2].roomId = "97393"; // 本地用户不用填写 roomID,远程需要config.mixUsersArray = mixUsersArray;// 发起云端混流trtc->setMixTranscodingConfig(&config);
TRTCTranscodingConfig config = new TRTCTranscodingConfig();// 设置分辨率为1280 × 720, 码率为1500kbps,帧率为20fpsconfig.videoWidth = 1280;config.videoHeight = 720;config.videoBitrate = 1500;config.videoFramerate = 20;config.videoGOP = 2;config.audioSampleRate = 48000;config.audioBitrate = 64;config.audioChannels = 2;config.mode = RTCTranscodingConfigMode.TRTCTranscodingConfigMode_Template_PresetLayout;TRTCMixUser[] mixUsersArray = new TRTCMixUser[3];// 主播摄像头的画面位置TRTCMixUser local = new TRTCMixUser();local.userId = "$PLACE_HOLDER_LOCAL_MAIN$";local.zOrder = 0; // zOrder 为0代表主播画面位于最底层local.roomId = null; // 本地用户不用填写 roomID,远程需要RECT rtLocal = new RECT() {left = 0,top = 0,right = videoWidth,bottom = videoHeight};local.rect = rtLocal;mixUsersArray[0] = local;// 连麦者的画面位置TRTCMixUser remote1 = new TRTCMixUser();remote1.userId = "$PLACE_HOLDER_REMOTE$";remote1.zOrder = 1;remote1.roomId = “97392”; // 本地用户不用填写 roomID,远程需要RECT rtRemote1 = new RECT() { //仅供参考left = 420,top = 81,right = 240 + left,bottom = 240 + top};remote1.rect = rtRemote1;mixUsersArray[1] = remote1;// 连麦者的画面位置TRTCMixUser remote2 = new TRTCMixUser();remote2.userId = "$PLACE_HOLDER_REMOTE$";remote2.zOrder = 1;remote2.roomId = “97393”; // 本地用户不用填写 roomID,远程需要RECT rtRemote2 = new RECT() { //仅供参考left = 660,top = 400,right = 240 + left,bottom = 240 + top};rtRemote2.rect = rtRemote2;mixUsersArray[2] = remote2;// 发起云端混流config.mixUsersArray = mixUsersArray;trtc.setMixTranscodingConfig(config);
TRTCCloud trtcCloud = await TRTCCloud.sharedInstance();trtcCloud.setMixTranscodingConfig(TRTCTranscodingConfig(appId: 1252463788, //仅供参考bizId: 3891, //仅供参考// 设置分辨率为720 × 1280, 码率为1500kbps,帧率为20FPSvideoWidth: 720,videoHeight: 1280,videoBitrate: 1500,videoFramerate: 20,videoGOP: 2,audioSampleRate: 48000,audioBitrate: 64,audioChannels: 2,// 采用预排版模式mode: TRTCCloudDef.TRTC_TranscodingConfigMode_Template_PresetLayout,mixUsers: [// 主播摄像头的画面位置TRTCMixUser(userId: "$PLACE_HOLDER_LOCAL_MAIN$",roomId: null, // 本地用户不用填写 roomID,远程需要zOrder: 0, // zOrder 为0代表主播画面位于最底层x: 0, //仅供参考y: 0,streamType: 0,width: 300,height: 400),TRTCMixUser(userId: '$PLACE_HOLDER_REMOTE$',roomId: '256', // 本地用户不用填写 roomID,远程需要zOrder: 1,x: 100, //仅供参考y: 100,streamType: 0,width: 160,height: 200)],));
try {const config = {target: {publishMode: PublishMode.publishMixStreamToCDN},encoding: {videoWidth: 720,videoHeight: 1280,videoBitrate: 1500,videoFramerate: 20,videoGOP: 2,audioSampleRate: 48000,audioBitrate: 64,audioChannels: 2,},// 一路本地摄像头、两路远端流的排版位置mix: {audioMixUserList: [{userId: 'jack'},{userId: 'jack2'},{userId: 'jack3'}],videoLayoutList: [{width: 720,height: 1280,locationX: 0,locationY: 0,userId: 'jack', // 本地摄像头占位,传入推摄像头的 client userIdzOrder: 1},{width: 180,height: 240,locationX: 400,locationY: 800,userId: 'jack2', // Web 端目前不支持预排版模式,需要传入实际的 userIdzOrder: 2},{width: 180,height: 240,locationX: 400,locationY: 500,userId: 'jack3',zOrder: 2}]}}await trtc.startPlugin('CDNStreaming', config);} catch (error) {console.error('CDNStreaming start failed ', error);}
注意
预排版模式下
setMixTranscodingConfig()
接口无需多次调用,在进房成功并开启本地音频上行后调用一次即可。上述 Web 端是 5.x 版本的代码示例,详细教程请参考 CDNStreaming Plugin。
4.x 版本请参考: Client.startMixTranscode()。
屏幕分享模式(ScreenSharing)
适用场景
屏幕分享模式适用于在线教育和互动课堂等场景,该类场景下您可以在调用 SDK 的 enterRoom 接口时将 AppScene 参数设定为
TRTCAppSceneLIVE
。
屏幕分享模式下,SDK 会先根据您所选定的目标分辨率构建一张画布。当老师未开启屏幕分享时,SDK 会将摄像头画面等比例拉伸绘制到该画布上;当老师开启屏幕分享后,SDK 会将屏幕分享画面绘制到同样的画布上。通过构建画布可以确保混流模块的输出分辨率一致,防止录制和网页观看的视频兼容性问题(普通播放器不支持分辨率会变化的视频)。使用步骤
1. 在调用
enterRoom()
函数进入房间时,根据您的业务需要,设定 AppScene 参数为 TRTCAppSceneLIVE
。2. 开启 旁路直播,并设定 TRTCParams 中的
streamId
参数,指定 MCU 输出的混合音视频流的去处。3. 调用
startLocalPreview()
和 startLocalAudio()
开启本地的音视频上行。说明
由于云端混流的本质是将多路流混合到当前(即发起混流指令的)用户所对应的音视频流上,因此当前用户本身必须有音视频上行才能构成混流的前提条件。
4. 调用
setMixTranscodingConfig()
接口启动云端混流,需要您在调用时将 TRTCTranscodingConfig
中的 mode
参数设定为 TRTCTranscodingConfigMode_Template_ScreenSharing ,并指定 audioSampleRate
、audioBitrate
和 audioChannels
等关乎音频输出质量的参数,以及 videoWidth
、videoHeight
、videoBitrate
、videoFramerate
等关乎视频输出质量的参数。说明
若将
videoWidth
和 videoHeight
参数均指定为0,SDK 会自动根据用户当前屏幕的宽高比计算出一个合适的分辨率。
注意
屏幕分享模式下
setMixTranscodingConfig()
接口无需多次调用,在进房成功并开启本地音频上行后调用一次即可。由于教学模式下的视频内容以屏幕分享为主,同时传输摄像头画面和屏幕分享画面非常浪费带宽。建议直接将摄像头画面和学生的画面通过
setLocalVideoRenderCallback()
和 setRemoteVideoRenderCallback()
接口自绘到当前屏幕上。通过将 TRTCTranscodingConfig 中的
videoWidth
和 videoHeight
参数均指定为 0,可以让 SDK 智能选择输出分辨率。如果老师当前屏幕宽度小于1920px,SDK 会使用老师当前屏幕的实际分辨率;如果老师当前屏幕宽度大于1920px,SDK 会根据当前屏幕宽高比,选择 1920 × 1080(16:9)、1920 × 1200(16:10)或1920 × 1440(4:3)。全手动模式(Manual)
适用场景
全手动模式适合于上述自动模式均不适用的场景,全手动的灵活性最高,可以自由组合出各种混流方案,但易用性最差。
全手动模式下,您需要设置
TRTCTranscodingConfig
中的所有参数,并需要监听 TRTCCloudDelegate 中的 onUserVideoAvailable()
和 onUserAudioAvailable()
回调,以便根据当前房间中各个上麦用户的音视频状态不断地调整 mixUsers
参数,否则会导致混流失败。使用步骤
1. 在调用
enterRoom()
函数进入房间时,根据您的业务需要,设定 AppScene 参数。2. 开启 旁路直播,并设定 TRTCParams 中的
streamId
参数,指定 MCU 输出的混合音视频流的去处。3. 根据您的业务需要,调用
startLocalAudio()
开启本地的音频上行(或同时调用 startLocalPreview()
开启视频上行)。说明
由于云端混流的本质是将多路流混合到当前(即发起混流指令的)用户所对应的音视频流上,因此当前用户本身必须有音视频上行才能构成混流的前提条件。
4. 调用
setMixTranscodingConfig()
接口启动云端混流,需要您在调用时将 TRTCTranscodingConfig
中的 mode
参数设定为 TRTCTranscodingConfigMode_Manual ,并指定 audioSampleRate
、audioBitrate
和 audioChannels
等关乎音频输出质量的参数。如果您的业务场景中也包含视频,需同时设置 videoWidth
、videoHeight
、videoBitrate
、videoFramerate
等关乎视频输出质量的参数。5. 监听 TRTCCloudDelegate 中的
onUserVideoAvailable()
和 onUserAudioAvailable()
回调,并根据需要指定mixUsers参数。说明
与预排版(PresetLayout)模式不同,Manual 需要您指定每一个
mixUser
中的 userId
参数为真实的连麦者 ID,并且也要根据该连麦者是否开启了视频,如实设定 mixUser
中的 pureAudio
参数。注意
全手动模式下,您需要实时监听房间中连麦者的上麦下麦动作,并根据连麦者的人数和音视频状态,多次调用
setMixTranscodingConfig()
接口。相关费用
费用的计算
云端混流转码需要对输入 MCU 集群的音视频流进行解码后重新编码输出,将产生额外的服务成本,因此 TRTC 将向使用 MCU 集群进行云端混流转码的用户收取额外的增值费用。云端混流转码费用根据转码输出的分辨率大小和转码时长进行计费,转码输出的分辨率越高、转码输出的时间越长,费用越高。详情请参见 云端混流转码计费说明。
费用的节约
在基于服务端 REST API 混流方案下,要停止混流,需要满足如下条件之一:
房间里的所有用户(包括主播和观众)都退出了房间。
调用 REST API StopMCUMixTranscode 主动停止混流。
在基于客户端 SDK API 混流方案下,要停止混流,需要满足如下条件之一:
发起混流(即调用了客户端 API
setMixTranscodingConfig
)的主播退出了房间。调用 setMixTranscodingConfig 并将参数 config 设置为
nil/null
主动停止混流。在其他情况下,TRTC 云端都将会尽力持续保持混流状态。因此,为避免产生预期之外的混流费用,请在您不需要混流的时候尽早通过上述方法结束云端混流。