You need to enable JavaScript to run this app.
导航

跨房间转发媒体流

最近更新时间2024.02.28 18:03:31

首次发布时间2022.03.08 20:51:05

跨房间转发媒体流,指可见用户的媒体流可以同时转发到多个 RTC 房间。转发目标房间的数量在 RTC 侧没有限制。
使用转发媒体流功能并不会产生额外的费用,与其他音视频通话遵循相同的计费原则,详见计费规则

适用场景

本功能适用于以下场景,观众在原来的房间中就能够接收到来自其他房间主播的媒体流。

  • 主播连麦 PK:接受连麦邀请后,主播 A 的音视频流可以转发到主播 B 所在的房间,同时,B 的音视频流也可以转发到 A 房间。观众和主播均无需离开原有房间,即可观赏到两位主播连麦 PK 的音视频内容。

  • 子母直播间:母直播间的音视频为集团总部统一制作,可以同时转发到多个子直播间。子直播间的主播们直接转播母直播间内容,边与用户进行互动,也可以合入自己的个性化内容后进行直播。

前提条件

你已经集成 RTC SDK,实现了基本的音视频通话。
支持跨房间转发功能的 SDK 详见API 及回调

名词解释

转推流:跨房间转发的媒体流
目标房间:转推流到达的房间

功能实现

以下时序图以 Android SDK 中的 API 名称为例。不同端的 SDK 中 API 或回调名称可能略有不同,以 API 及回调为准。

Api sequence

1. 加入房间

创建引擎实例并加入房间,本地用户默认对他人可见。

import VERTC, { ForwardStreamState } from '@volcengine/rtc';
// 创建引擎实例
const engine = VERTC.createEngine('appid');
// 加入房间
await engine.joinRoom('roomId_token', 'roomId', { userId: 'userid' });

参考 构建 RTC 应用 获取详细步骤。

2. 开启跨房间转发

  • startForwardStreamToRooms 中所传入的 token 是与目标房间相对应的 token,而非当前用户所在房间的 token。
  • 在调用 stopForwardStreamToRooms 前,仅可调用一次 startForwardStreamToRooms
  • 向开启音频选路的房间转发媒体流,该媒体流可能无法被播放。
// 管理目标房间列表
const targetRoomList: string[] = [];

// 开启跨房间转发媒体流
const startResult = await engine.startForwardStreamToRooms([
  { roomId: 'targetRoomIdA', token: 'targetRoomIdA_token' },
  // 可以同时指定多个目标房间
  { roomId: 'targetRoomIdB', token: 'targetRoomIdB_token' }
]);

// 处理调用结果
startResult.forEach(item => {
  if (item.state === ForwardStreamState.FORWARD_STREAM_STATE_SUCCESS) {
    // 保存成功的目标房间
    targetRoomList.push(item.roomId);
  } else {
    // 根据错误码进行对应处理
    console.error(item.error);
  }
});

3. 更新转发配置

更新跨房间媒体流转发请求。
如果调用 updateForwardStreamToRooms 时不传入任何参数或者传空值,会停止所有正在转发的目标房间流。此时仍需要调用 stopForwardStreamToRooms 后才可以再次调用 startForwardStreamToRooms

// 更新跨房间转发媒体流的目标房间列表
const updateResult = await engine.updateForwardStreamToRooms([
  // 列表中不包含 targetRoomIdA,会停止该房间的转发媒体流
  // targetRoomIdB 在之前的目标房间列表中,会更新对应的 token。
  // 在暂停状态下调用更新无法对 token 进行校验。在调用恢复 resumeForwardStreamToAllRooms  后才会进行 token 校验。
  { roomId: 'targetRoomIdB', token: 'targetRoomIdB_new_token' },
  // targetRoomIdC 不在之前的目标房间列表中,会开启向该房间转发媒体流
  { roomId: 'targetRoomIdC', token: 'targetRoomIdC_token' }
]);

// 处理调用结果
// 停止转发的目标房间也会在 updateForwardStreamToRooms 的返回结果中。
updateResult.forEach(item => {
  if (item.state === ForwardStreamState.FORWARD_STREAM_STATE_SUCCESS) {
    if (!['targetRoomIdB', 'targetRoomIdC'].includes(item.roomId)) {
      // 不在请求列表中,但在返回结果中的应当删除
      targetRoomList.splice(targetRoomList.indexOf(item.roomId), 1);
    } else if (!targetRoomList.includes(item.roomId)) {
      // 不在已有房间中,需要新增
      targetRoomList.push(item.roomId);
    }
  } else {
    // 根据错误码进行对应处理
    console.error(item.error);
  }
});

4. 暂停和恢复转发

暂停与恢复向所有目标房间转发媒体流。
在调用 resumeForwardStreamToAllRooms 恢复媒体流转发前,仅可调用一次 pauseForwardStreamToAllRooms

// 暂停跨房间转发媒体流的目标房间列表
await engine.pauseForwardStreamToAllRooms();

// 恢复跨房间转发媒体流的目标房间列表
const result = await engine.resumeForwardStreamToAllRooms();

// 处理调用结果
result.forEach(item => {
  if (item.state !== ForwardStreamState.FORWARD_STREAM_STATE_SUCCESS) {
    // 根据错误码进行对应处理
    console.error(item.error);
  }
});

5. 停止转发

停止向所有目标房间转发媒体流。

await engine.stopForwardStreamToRooms();

6. 回调

监听 onForwardStreamStateChanged,感知跨房间转发媒体流状态。

  • 转发媒体流至目标房间和进入目标房间,将分别触发一次以下回调: onUserJoinonUserLeaveonUserPublishStream / onUserPublishScreenonUserUnpublishStream / onUserUnpublishScreen

  • 如果媒体流转发过程中,用户切换为不可见,媒体流转发将停止。

function onForwardError(info) {
  console.error(info);
}

engine.on(EngineEventsTypes.onForwardStreamError, onForwardError);

示例项目

API 及回调

以下客户端 SDK 均支持跨房间转发媒体流功能。你可以根据上文中的描述和实例,使用不同的 SDK,在不同的端上实现这个功能。

说明:表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。

平台AndroidiOSmacOSWindowsLinuxWebElectronFlutter
开启跨房间转发媒体流startForwardStreamToRoomsstartForwardStreamToRooms:startForwardStreamToRooms:startForwardStreamToRoomsstartForwardStreamToRoomsstartForwardStreamToRoomsstartForwardStreamToRoomsstartForwardStreamToRooms
更新跨房间转发媒体流updateForwardStreamToRoomsupdateForwardStreamToRooms:updateForwardStreamToRooms:updateForwardStreamToRoomsupdateForwardStreamToRoomsupdateForwardStreamToRoomsupdateForwardStreamToRoomsupdateForwardStreamToRooms
恢复跨房间转发媒体流resumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRoomsresumeForwardStreamToAllRooms
暂停跨房间转发媒体流pauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRoomspauseForwardStreamToAllRooms
停止跨房间转发媒体流stopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRoomsstopForwardStreamToRooms
状态和错误回调onForwardStreamStateChangedrtcRoom:onForwardStreamStateChanged:rtcRoom:onForwardStreamStateChanged:onForwardStreamStateChangedonForwardStreamStateChangedonForwardStreamErroronForwardStreamStateChangedonForwardStreamStateChanged
事件回调onForwardStreamEventrtcRoom:onForwardStreamEvent:rtcRoom:onForwardStreamEvent:onForwardStreamEventonForwardStreamEventonForwardStreamEventonForwardStreamEvent

功能变更日志

  1. 自 Native SDK v3.34 起,本功能在 Native 端可用。

  2. 自 Web SDK v4.54 起,本功能在 Web 端可用。