角色、频道场景与直播
communication/live 场景、host/audience 角色、权限位、角色切换与观众端行为。
RTC 有两个正交的维度:频道场景(communication / live)决定「谁在说话」,角色(host / audience)决定「谁能发」。这一页把两者讲清楚,以及切换时 SDK 与服务端各自做什么。
前置条件
- 已创建项目并完成 Token 鉴权;Token 中的
role决定初始角色。 - 已选定频道场景(communication 或 live);场景在频道生命周期内保持不变。
频道场景
| 场景 | 语义 | 典型用途 |
|---|---|---|
communication | 所有人对等,默认都可以发布 | 会议、客服、1v1 |
live(liveBroadcasting) | 主播发布、观众只能订阅;有角色概念 | 直播、大班课、连麦 |
场景是入会时决定的:Web 端由 createClient({ mode: 'rtc' }) 选择模式,原生端由 setChannelProfile(...) 在入会前设置。 场景不能在通话中切换——要换场景就重新入会。
角色
| 角色 | 权限位 | 能发布 | 能订阅 |
|---|---|---|---|
host(broadcaster) | join_channel publish_audio publish_video publish_data subscribe | ✅ | ✅ |
audience | join_channel subscribe | ❌ | ✅ |
角色的授权依据是 Token 里的权限位(见 AccessToken2 语义),不是客户端自己声明。 所以「UI 上禁止观众发布」只是体验,真正拦住越权的是 priv 里没有 publish_*。
客户端切换角色
// 切成观众:SDK 会停止本地发布(不销毁轨道),并停止订阅视频以省流量
await client.setClientRole('audience');
// 切回主播:需要重新发布本地轨道
await client.setClientRole('host');
await client.publish([microphoneTrack, cameraTrack]);带选项的重载可以指定观众的延迟档位(低延迟 vs 省流量):
await client.setClientRole('audience', { level: 2 });角色变化会通过 user-info-updated(uid, 'role') 通知其他端;服务端侧也可以强制改角色,见 频道管理 的 POST /v1/channels/{channelName}/users/{uid}/role。
服务端强制改角色
不是所有场景都该由客户端自己决定:主播/观众的升降级通常由业务后端判定(例如付费用户才能上麦)。服务端接口改角色后:
- 该用户的权限在下一次 Token 校验/续期时生效;
- 已建立的连接会收到角色变更通知;
- 若不是续期窗口,客户端需要主动
renewToken或重连——这一点在 排障手册 有对照表。
直播场景下的三个常见坑
| 坑 | 现象 | 正确做法 |
|---|---|---|
| 观众端持续订阅视频 | 观众多了之后下行带宽爆炸 | audience 角色 + 只订阅需要的 uid |
| 切换角色后没有重新发布 | 升为主播后其他人看不到 | setClientRole('host') 之后必须重新 publish |
用 mode: 'live' 却忘了设置角色 | 默认角色可能不是你要的 | 显式 setClientRole,并在 Token 里签发对应权限位 |
与直播推流/录制的组合
- 要推 CDN:用 Media Push(
rtmp-converters),不是客户端直推; - 要录制:用 云端录制,
mode=composite时按布局合流; - 观众端要低延迟:用「观众延迟档位」+ 大小流(见 大小流与回退)。
与 IM 的边界
「谁是主播」在业务上往往由 IM 的信令决定。我们的分工是:IM 负责业务角色协商,RTC 负责媒体授权。 两者通过 Token 权限位对齐——IM 说「你现在是主播了」,你的后端签一个 host 权限的 Token,客户端 renewToken 即可。
下一步
- REST API 参考:完整端点、参数与 curl。
- 错误码:失败时按
code/ HTTP 状态定位。 - 常见问题:配额、限制与排障。