前言
在直播场景中,常常需要跨房连麦来支持不同直播间的主播实时互动的需求,本文主要介绍 Web 端跨房间连麦及混流后推流到CDN 的实现方式。
实现方式
在实现 Web 端跨房连麦之前,我们先来确认一下实时音视频的一些基础信息。
-
userId,用户的标识 Id, 每个用户拥有独一无二的 Id;
-
roomId,直播间 Id;
-
stream,由 TRTC.createStream 创建的音视频流对象,包括本地音视频流 LocalStream 和 远端音视频流 RemoteStream;
-
client,由 TRTC.createClient 创建的客户端对象,拥有加入通话房间,发布本地音视频流,订阅远端流的功能;
实现基础音视频通话时,我们根据 userId 创建 client 进入某个特定的 roomId 房间并发布本地流、订阅远端流以实现同一个房间中多个用户之间的音视频通话。
在 Web 端, 让不同房间的 A,B 两个主播,分别使用自己的 userId 创建新的 client,进入到对方主播所在的房间订阅对方主播的流,即可实现跨房连麦。
详细流程说明
步骤一:主播进入各自的房间并发布流。
主播 A(创建 clientA1)以主播身份在 1000 房间推流;
主播 B(创建 clientB1)以主播身份在 2000 房间推流。
// 主播 A 在1000房间推流
let localStreamA = TRTC.createStream({
userId: 'A',
audio: true,
video: true
})
let clientA1 = TRTC.createClient({
sdkAppId: 0,
userId: 'A',
userSig: 'xxxx',
mode: 'live'
})
await clientA1.join({
roomId: 1000,
role: 'anchor'
})
await clientA1.publish(localStreamA)
// 主播 B 在2000房间推流
let localStreamB = TRTC.createStream({
userId: 'B',
audio: true,
video: true
})
let clientB1 = TRTC.createClient({
sdkAppId: 0,
userId: 'B',
userSig: 'xxxx',
mode: 'live'
})
await clientB1.join({
roomId: 2000,
role: 'anchor'
})
await clientB1.publish(localStreamB)
此时,1000 房间和 2000 房间的用户状态如下:
房间 1000 房间 2000
------------- ------------
跨房连麦前: | 主播 A | | 主播 B |
| 观众 U V W | | 观众 X Y Z |
------------- ------------
?
对于观众是通过标准直播拉流(CDN拉流)的情况,主播需要将自己的音视频流推流到 CDN,请参考 实现推流到 CDN。
步骤二:主播跨房连麦
主播 A(创建 clientA2)以观众身份进入房间 2000 订阅主播 B 的流;
主播 B(创建 clientB2)以观众身份进入房间 1000 订阅主播 A 的流;
此时主播 A 和 主播 B 跨房间连麦成功。
// 主播 A 以观众身份进入 2000 房间并订阅主播 B 的流
let clientA2 = TRTC.createClient({
sdkAppId: 0,
userId: 'A',
userSig: 'xxxx',
mode: 'live'
})
clientA2.on('stream-added', ({ stream: remoteStream }) => {
if (remoteStream.getUserId() === 'B') {
clientA2.subscribe(remoteStream);
}
})
clientA2.on('stream-subscribed', ({ stream: remoteStream }) => {
remoteStream.play('B_containerId');
})
await clientA2.join({
roomId: 2000,
role: 'audience'
})
// 主播 B 以观众身份进入 1000 房间并订阅主播 A 的流
let clientB2 = TRTC.createClient({
sdkAppId: 0,
userId: 'B',
userSig: 'xxxx',
mode: 'live'
})
clientB2.on('stream-added', ({ stream: remoteStream }) => {
if (remoteStream.getUserId() === 'A') {
clientB2.subscribe(remoteStream);
}
})
clientB2.on('stream-subscribed', ({ stream: remoteStream }) => [
remoteStream.play('A_containerId');
])
await clientB2.join({
roomId: 1000,
role: 'audience'
})
房间 1000 房间 2000
-------------- --------------
跨房连麦后: | 主播 A | | 主播 B |
| 观众 B U V W | | 观众 A X Y Z |
-------------- --------------
步骤三:跨房连麦后混流
对于标准直播拉流(CDN拉流)的场景来说,主播跨房间连麦之后需要将双方主播连麦的音视频混流后发布到 CDN。
注意:
Web TRTC SDK 自 v4.11.5 开始支持跨房间混流。详见 client.startMixTranscode。
a. 混流前提条件 - 开通旁路
- 登录 实时音视频控制台。
- 在左侧导航栏选择【应用管理】,单击目标应用所在行的【功能配置】。
- 在【旁路推流配置】中,单击【启用旁路推流】右侧的开关,在弹出的【开启旁路推流功能】对话框中,单击【开启旁路推流功能】即可开通。
b. 发起混流
连麦中的主播需要在各自的推流房间中发起混流,将其他房间主播的流混到自己已经发布在 CDN 的音视频流上。
注意:只有当 client.startMixTranscode 接口中的 streamId 参数为 undefined 或者 '' 的时候,才会将 mixUsers 中的其他用户流混合到接口调用者的 CDN 音视频流上。
// 主播 A 发起跨房间混流,将房间 2000 中 B 主播的音视频流混到自己的旁路流
// 注意:必须由发布本地流的 clientA1 发起混流
clientA1.startMixTranscode({
mode: 'manual',
videoWidth: 1280,
videoHeight: 480,
videoBitrate: 1500,
videoFramerate: 15,
mixUsers: [
{
userId: 'A',
roomId: 1000, // roomId 字段自 v4.11.5 版本开始支持,支持跨房间混流
pureAudio: false,
width: 640,
height: 480,
locationX: 0,
locationY: 0,
streamType: 'main',
zOrder: 1
},
{
userId: 'B',
roomId: 2000, // roomId 字段自 v4.11.5 版本开始支持,支持跨房间混流
pureAudio: false,
width: 640,
height: 480,
locationX: 640,
locationY: 0,
streamType: 'main',
zOrder: 1
},
})
// 主播 B 发起跨房间混流,将房间 1000 中 A 主播的音视频流混到自己的旁路流
// 注意:必须由发布本地流的 clientB1 发起混流
clientB1.startMixTranscode({
mode: 'manual',
videoWidth: 1280,
videoHeight: 480,
videoBitrate: 1500,
videoFramerate: 15,
mixUsers: [
{
userId: 'B',
roomId: 2000, // roomId 字段自 v4.11.5 版本开始支持,支持跨房间混流
pureAudio: false,
width: 640,
height: 480,
locationX: 0,
locationY: 0,
streamType: 'main',
zOrder: 1
},
{
userId: 'A',
roomId: 1000, // roomId 字段自 v4.11.5 版本开始支持,支持跨房间混流
pureAudio: false,
width: 640,
height: 480,
locationX: 640,
locationY: 0,
streamType: 'main',
zOrder: 1
},
})
c. CDN 拉流
情况一:当您推流到腾讯云 CDN 之后,TRTC 房间里的每一路画面都匹配一路对应的播放地址,播放地址拼接格式如下:
http://播放域名/live/[streamId].flv
- 拉流地址播放域名请在 [控制台]-[域名管理] 页面配置。
- 获取 streamId
- streamId 默认为
${sdkAppId}_${roomId}_${userId}_main
; - 当您指定了 TRTC.createClient 中的 streamId 字段时,请使用 TRTC.createClient 接口指定的 streamId 拼接播放地址;
- 当您指定了 client.startPublishCDNStream 的 streamId 字段时,请使用 client.startPublishCDNStream 接口指定的 streamId 拼接播放地址;
- streamId 默认为
情况二:当您推流到指定 CDN 地址之后,请使用您的推流地址对应的拉流地址观看混合之后的流;