Tutorial: 实现跨房连麦

实现跨房连麦

前言

在直播场景中,常常需要跨房连麦来支持不同直播间的主播实时互动的需求,本文主要介绍 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.createClient({
  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(localStream)
// 主播 B 在2000房间推流
let localStreamB = TRTC.createClient({
  userId: 'B',
  audio: true,
  video: true
})
let clientB1 = TRTC.createClient({
  sdkAppId: 0,
  userId: 'B',
  userSig: 'xxxx',
  mode: 'live'
})
await clientA1.join({
  roomId: 2000,
  role: 'anchor'
})
await clientA1.publish(localStream)

此时,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. 混流前提条件 - 开通旁路
  1. 登录 实时音视频控制台
  2. 在左侧导航栏选择【应用管理】,单击目标应用所在行的【功能配置】。
  3. 在【旁路推流配置】中,单击【启用旁路推流】右侧的开关,在弹出的【开启旁路推流功能】对话框中,单击【开启旁路推流功能】即可开通。 img
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

情况二:当您推流到指定 CDN 地址之后,请使用您的推流地址对应的拉流地址观看混合之后的流;