多路分辨率视频流 (ABR)
在互动直播、会议、大班课等涉及多终端、多网络环境的实时互动场景中,如果可以动态调整发布和订阅的视频分辨率,会显著提升互动体验。典型适用场景如下:
- 直播推流:主推高分辨率,弱网环境下可自动切换到低分辨率流
- 视频会议:主讲人画面用高层,缩略图用低层,提升整体体验
- 多终端适配:高性能终端拉高层,低性能终端拉低层,提升整体体验和带宽利用率
- 多屏幕适配:根据大、中、小屏,分别推不同的分辨率
本文介绍如何使用 RTC SDK 在你的项目中实现多路分辨率视频流功能。
功能简介
从 v4.6.0 起,RTC SDK 新增多分辨率视频流(Adaptive Bitrate Video Streaming,简称 ABR)功能,支持对同一视频源设置同时发送最多 4 路不同规格的视频流(1 路源流 + 3 路扩展流),并支持多频道场景。接收端可以根据渲染窗口大小或其他业务逻辑按需订阅不同层级的流,实现画质、性能、带宽、网络质量的最佳平衡。当发流端带宽或设备性能受限时,会自适应关闭多流。
和已有的视频双流模式相比,ABR 功能在可订阅流层级数和切换体验上有显著改进。如果你之前实现过视频双流模式,可以参考 ABR Vs 视频双流了解详细信息,并根据实际业务需求,选择合适的集成方案。
前提条件
开始前,请确保你已经参考快速开始在项目中实现了基础的实时互动。
实现方式
发布多路分辨率视频流
加入频道前,你可以调用 setSimulcastConfig
方法,设置视频多路分层 (simulcastConfig
) 参数,来实现多分辨率流的灵活推送。
virtual int setSimulcastConfig(const SimulcastConfig& simulcastConfig) = 0;
其中,SimulcastConfig
定义如下:
struct SimulcastConfig {
// 定义扩展流的层级
enum StreamLayerIndex {
STREAM_LAYER_1 = 0,
STREAM_LAYER_2 = 1,
STREAM_LAYER_3 = 2,
STREAM_LAYER_4 = 3,
STREAM_LAYER_5 = 4,
STREAM_LAYER_6 = 5,
STREAM_LOW = 6,
STREAM_LAYER_COUNT_MAX = 7
};
// 配置各扩展流的视频属性
struct StreamLayerConfig {
// 分辨率
VideoDimensions dimensions;
// 帧率
int framerate;
// 是否启用该层
bool enable;
StreamLayerConfig() : dimensions(0, 0), framerate(0), enable(false) {}
};
// 各扩展流的具体参数配置
StreamLayerConfig configs[STREAM_LAYER_COUNT_MAX];
// 是否允许发送端性能或上行网络差时动态关闭多路流
bool publish_fallback_enable;
SimulcastConfig(): publish_fallback_enable(false) {}
};
参数配置注意事项
在配置各层级扩展流时,请确保满足如下条件:
- 你需要在加入频道前配置各扩展流的分辨率和帧率。加入频道后,不能修改各层级的分辨率与帧率,只能通过
StreamLayerConfig
下的enable
开启或关闭对应层级的扩展流。 - 扩展流的分辨率和帧率应低于源流,即你在
VideoEncoderConfiguration
中设置的视频编码分辨率和帧率。 - 扩展流的设置应逐层递减,即
STREAM_LAYER_2
对应视频流的分辨率帧率应低于STREAM_LAYER_1
对应视频流的分辨率和帧率,以此类推。 - 最多只能同时开启 3 路扩展流(包括视频小流)。
示例代码
请结合业务需求和带宽情况合理设置不同层级的分辨率和帧率。在业务实现中,我们建议只配置实际需要的层,其余层直接将 StreamLayerConfig
中的 enable
设为 false
。
如下示例代码展示的是配置多层分辨率视频流的实现方式:
#include "IAgoraRtcEngine.h"
#include "AgoraBase.h"
using namespace agora::rtc;
SimulcastConfig config;
// 配置低层(如需低分辨率流)
config.configs[SimulcastConfig::STREAM_LOW].dimensions.width = 320;
config.configs[SimulcastConfig::STREAM_LOW].dimensions.height = 180;
config.configs[SimulcastConfig::STREAM_LOW].framerate = 15;
config.configs[SimulcastConfig::STREAM_LOW].enable = true;
// 配置高层(如需高分辨率流)
config.configs[SimulcastConfig::STREAM_LAYER_1].dimensions.width = 1280;
config.configs[SimulcastConfig::STREAM_LAYER_1].dimensions.height = 720;
config.configs[SimulcastConfig::STREAM_LAYER_1].framerate = 30;
config.configs[SimulcastConfig::STREAM_LAYER_1].enable = true;
// 可选:按需推流和性能回退
// 默认为 false,表示不允许性能或上行网络差时自动关闭多路流
config.publish_fallback_enable = false;
// 设置 Simulcast 配置
int ret = rtcEngine->setSimulcastConfig(config);
if (ret != 0) {
// 错误处理
}
接收端订阅指定流
远端用户可以通过 setRemoteVideoStreamType
中的 streamType
参数来指定想要订阅的视频质量层级,示例代码如下:
// 订阅高分辨率流
rtcEngine->setRemoteVideoStreamType(remoteUid, VIDEO_STREAM_HIGH);
// 订阅视频质量层级 1
rtcEngine->setRemoteVideoStreamType(remoteUid, VIDEO_STREAM_LAYER_1);
// 订阅低分辨率流
rtcEngine->setRemoteVideoStreamType(remoteUid, VIDEO_STREAM_LOW);
在实时互动过程中,你可以多次调用 setRemoteVideoStreamType
设置及更新想要订阅的视频层级,实现动态调整。
参考信息
示例项目
声网提供实现了多路分辨率视频流的开源示例项目供你参考,你可以前往下载或查看其中的源代码。
API 参考
ABR Vs 视频双流
ABR (setSimulcastConfig
) 和视频双流 (setDualStreamMode
) 为互斥关系;后设置的 API 行为会覆盖前者。请根据实际业务需求选择一种方案进行集成,并关闭另一种方案。
和视频双流模式相比,ABR 功能在以下方面有显著改进:
- 可订阅流从 2 条扩展到 8 条。ABR 在原有的大 (
VIDEO_STREAM_TYPE::VIDEO_STREAM_HIGH
)、小(VIDEO_STREAM_TYPE::VIDEO_STREAM_LOW
)流的 2 条流的基础上,新增了 6 条扩展流,分别定义为VIDEO_STREAM_LAYER_1
到VIDEO_STREAM_LAYER_6
,对应SimulcastConfig::StreamLayerIndex::STREAM_LAYER_1
到SimulcastConfig::StreamLayerIndex::STREAM_LAYER_6
。
- 切换体验更平滑。相较大小流的双档切换,通过 ABR 多级分辨率的支持,用户可以获得更加平滑的切换体验,以及更多业务场景的灵活选择。
此外,为了更好平衡 ABR 的性能和网络消耗,我们还实现了如下策略:
- 在发送端性能受限的情况下,会自动关闭上行扩展流,订阅端也会自动适配到剩余的扩展流。
- 在上行带宽受限下,会优先关闭扩展流,然后按照之前大小流的码率控制策略,保证发布和订阅的平滑发送和丝滑切换。
在功能实现上,ABR 和双流模式的差异对比如下表所示。声网会在后续版本中补齐 ABR 的特性差距。
特性 | ABR | 双流模式 |
---|---|---|
支持多频道场景 | ✔ | ✔ |
小流支持自动适配视频属性 | ✘ | ✔ |
发流端根据订阅端设置的层级发布视频流 | ✔(需联系技术支持) | ✔ |
发流端性能受限时,可以关闭发布源流之外的视频流 | ✔ | ✘ |
下行网络受限时,可以自动开启上行小流 | ✘ | ✔ |