TRTC Web SDKAPI 文档事件错误码类型教程更新日志
En

Tutorial: 实现直播场景切换分辨率

实现直播场景切换分辨率

功能描述

在直播观看场景中,同一路内容通常会提供多个清晰度档位,例如 1080p720p480p。当用户网络状况、设备性能或业务诉求发生变化时,您可能需要在不同档位之间切换,以在清晰度流畅度之间取得更好的平衡。

TRTC Web SDK 提供实验接口 switchPlaybackQuality,用于在多路播放流之间切换清晰度。SDK 内部会负责处理切换过程中的播放衔接和主流音频同步。

本文将介绍直播播放多分辨率切换的接入方式,以及推荐的最佳实践。

适用场景

switchPlaybackQuality 适合以下场景:

  • 直播观众端多清晰度观看:同一路直播内容提供多个分辨率档位,观众可以手动选择画质。
  • 移动端弱网播放:当带宽下降、丢包升高或画面卡顿时,自动切换到更低档位,优先保证可播放性。

该方案更适合单路直播播放场景。如果您是多人通话或宫格视频场景,建议优先参考 开启大小流功能

前提条件

使用该能力前,请确保:

  1. 同一路直播内容已经准备好多档清晰度流,每个档位都能通过唯一的 userId(以及可选的 streamType)进行区分。
  2. 已经完成 trtc.enterRoom() 进房。
  3. 观众端已经通过 trtc.startRemoteVideo() 播放了 streamList 中的某一路流。
  4. streamList[].bitrate 填写的是各档位的实际码率(单位:kbps),用于排序及自动切换判断。

接口说明

通过 callExperimentalAPI 调用:

await trtc.callExperimentalAPI('switchPlaybackQuality', options);
interface PlaybackQualityStream {
  name: string;
  userId: string;
  streamType?: TRTCStreamType;
  bitrate: number;
}
interface ResolutionConfig {
  userId: string;
  streamType: TRTCStreamType;
  name: string;
}
interface SwitchPlaybackQualityOptions {
  quality?: string;
  streamList?: PlaybackQualityStream[];
  onSwitched?: (from: ResolutionConfig, to: ResolutionConfig) => void;
}

参数说明

参数 类型 必填 说明
quality string 目标档位名称。必须与 streamList[].name 精确匹配。传入 auto 表示开启自动切换模式;不传则仅缓存 streamList
streamList array 清晰度档位列表。不传则复用上一次缓存的列表。
streamList[].name string 档位名称,例如 1080p720p
streamList[].userId string 该档位对应的播放流 userId
streamList[].streamType TRTCStreamType 流类型,默认主流。
streamList[].bitrate number 码率,单位 kbps。自动模式会按码率从高到低排序。
onSwitched function 切换成功回调,返回切换前后的档位信息。

手动切换模式

1. 准备档位列表

建议您在业务层维护一份清晰度列表,例如:

const streamList = [
  { name: '1080p', userId: 'anchor_1080p', bitrate: 2000 },
  { name: '720p', userId: 'anchor_720p', bitrate: 1000 },
  { name: '480p', userId: 'anchor_480p', bitrate: 500 },
];

2. 进房后缓存 streamList

首次调用时,如果只传 streamList 而不传 quality,SDK 只会缓存档位信息,不会立即切换。

await trtc.callExperimentalAPI('switchPlaybackQuality', {
  streamList,
});

3. 播放当前默认档位

请先通过 trtc.startRemoteVideo() 播放其中一路。当前正在播放的流必须存在于 streamList 中。

await trtc.startRemoteVideo({
  userId: 'anchor_720p',
  streamType: TRTC.TYPE.STREAM_TYPE_MAIN,
  view: document.getElementById('live-player'),
});

4. 用户切换目标清晰度

当用户在 UI 上选择新的档位时,调用 switchPlaybackQuality 即可:

await trtc.callExperimentalAPI('switchPlaybackQuality', {
  quality: '1080p',
  onSwitched(from, to) {
    console.log(`playback quality switched: ${from.name} -> ${to.name}`);
  },
});

5. 切换过程说明

默认情况下,SDK 在执行 switchPlaybackQuality 时,会优先保障当前正在播放的档位继续渲染,并在后台异步拉起目标档位的新视频流。只有当新档位拉流并进入可播放状态后,SDK 才会停止旧的视频流并完成切换。

这意味着:

  • 调用切换接口后,旧画面不会立刻消失
  • 业务层通常不需要在调用瞬间立即展示全屏 loading
  • 更推荐在 onSwitched 回调中更新“当前清晰度”UI 状态,而不是在调用切换时就主动清空旧画面。

6. 完整示例

const streamList = [
  { name: '1080p', userId: 'anchor_1080p', bitrate: 2000 },
  { name: '720p', userId: 'anchor_720p', bitrate: 1000 },
  { name: '480p', userId: 'anchor_480p', bitrate: 500 },
];
await trtc.enterRoom({
  sdkAppId: 1400000000,
  userId: 'audience_123',
  userSig: 'xxx',
  roomId: 12345,
  scene: 'live',
  role: 'audience',
});
await trtc.callExperimentalAPI('switchPlaybackQuality', { streamList });
await trtc.startRemoteVideo({
  userId: 'anchor_720p',
  streamType: TRTC.TYPE.STREAM_TYPE_MAIN,
  view: document.getElementById('live-player'),
});
// 用户点击“高清”按钮时
await trtc.callExperimentalAPI('switchPlaybackQuality', {
  quality: '1080p',
  onSwitched(from, to) {
    console.log(`switch success: ${from.name} -> ${to.name}`);
  },
});

自动切换模式

如果您希望 SDK 根据当前播放状态自动在不同档位之间切换,可以传入 quality: 'auto' 开启自动模式。

开启方式

const streamList = [
  { name: '1080p', userId: 'anchor_1080p', bitrate: 2000 },
  { name: '720p', userId: 'anchor_720p', bitrate: 1000 },
  { name: '480p', userId: 'anchor_480p', bitrate: 500 },
];
await trtc.callExperimentalAPI('switchPlaybackQuality', { streamList });
await trtc.startRemoteVideo({
  userId: 'anchor_720p',
  streamType: TRTC.TYPE.STREAM_TYPE_MAIN,
  view: document.getElementById('live-player'),
});
await trtc.callExperimentalAPI('switchPlaybackQuality', {
  quality: 'auto',
  onSwitched(from, to) {
    console.log(`auto switch: ${from.name} -> ${to.name}`);
  },
});

默认策略说明

自动模式下,SDK 会根据 streamList[].bitrate 从高到低排序,并结合当前网络和播放状态决定是否切换。

下切条件

满足以下任一条件时,SDK 会尝试切换到更低档位:

  • 弱网且帧率低:下行丢包率较高,同时当前解码帧率较低。
  • 渲染卡顿明显:检测到较长时间的画面渲染卡顿。

默认阈值如下:

指标 默认值
下行丢包率阈值 20%
解码帧率阈值 5fps
渲染卡顿时长阈值 1500ms

上切条件

当网络恢复到较好状态后,SDK 会在满足以下条件时尝试切回更高档位:

  • 下行丢包率持续保持在较低水平;
  • 距离上一次下切已经超过冷却时间;
  • 当前会话内上切失败次数未达到限制。

默认阈值如下:

指标 默认值
良好丢包率阈值 15%
上切冷却时间 120s
最大连续上切失败次数 3

解码失败兜底

如果当前正在播放的档位发生视频解码失败,SDK 会自动回退到更低档位,并记录本次会话中设备可稳定播放的最高档位,避免后续反复上切失败。

如果您在自动模式下再次调用 switchPlaybackQuality 并传入具体档位,例如 quality: '720p',SDK 会退出自动模式并按手动切换处理。

与大小流方案的区别

switchPlaybackQuality 和“大小流”都能实现清晰度切换,但适用场景不同:

方案 适用场景 特点
大小流 多人通话、宫格视频、同一 userId 下切大流/小流 适合 RTC 多路订阅优化
switchPlaybackQuality 单路直播播放、多档分辨率切换 适合直播观众端手动/自动切换画质

如果您的业务是“一个主播、多档清晰度、观众只播放其中一路”,更建议使用 switchPlaybackQuality

最佳实践建议

如果您需要同时兼顾默认体验、弱网适配和用户自主选择,推荐采用以下接入方式:

  1. 首次播放默认中档:例如优先播放 720p,兼顾首屏体验和兼容性。
  2. 移动端默认开启自动模式:让 SDK 在弱网或渲染卡顿时自动降档。
  3. 用户手动选择时切为指定档位:一旦用户手动选择 1080p / 720p / 480p,就调用一次具体 quality,覆盖自动模式。
  4. 使用 onSwitched 同步 UI 状态:在切换成功后更新当前档位按钮、提示文案或埋点数据。

常见问题

1. 调用后没有发生切换,应该怎么排查?

您可以优先检查以下几点:

  • 是否已经先调用过一次 switchPlaybackQuality({ streamList }) 缓存档位列表;
  • 当前正在播放的流是否存在于 streamList 中;
  • quality 是否与 streamList[].name 精确匹配;
  • 目标档位是否与当前播放档位相同。

3. 自动模式为什么没有触发上切?

自动上切不仅依赖网络恢复,还会受到冷却时间、历史上切失败次数以及当前设备能力上限的影响。如果设备在更高档位上发生过解码失败,SDK 会降低后续自动上切的最高目标档位。

4. 手动切换时,音频需要业务层自己切吗?

在主流切换场景下,SDK 会同步处理音频切换,业务层通常不需要额外再做一次音频切换。

5. 自动模式和手动模式可以混用吗?

可以。推荐做法是默认开启自动模式;当用户明确选择某个档位时,再调用一次具体 quality 切为手动模式。