分享来自“关键帧Keyframe”的音视频面试题集锦第 53 期,本期内容主要是 WebRTC 音视频方面常见的 5 个面试题。
1、【架构与扩展篇】在多人视频会议场景中,SFU (Selective Forwarding Unit) 是目前的主流架构。请深入对比 Simulcast (多流发送) 与 SVC (可伸缩视频编码) 的工作原理区别。作为客户端,在弱网环境下,SFU 是如何利用这两种技术进行“抗弱网”调度的?
考察点: 流媒体架构、视频编码分层技术、带宽自适应策略。
参考答案:
核心区别:
- Simulcast (多流发送 – 空间分离):
- 原理: 客户端同时编码并发送 多路独立 的视频流(通常是 3 路:High 1080p, Medium 720p, Low 360p)。这三路流在编码上是完全解耦的,互不依赖。
- 优点: 兼容性极好(H.264 也能用),容错率高(丢了大流不影响小流)。
- SFU 行为: SFU 根据订阅端(Receiver)的带宽情况,直接选择转发其中“一路”完整的流。如果接收端带宽下降,SFU 瞬间切换到 Low 流。
- SVC (Scalable Video Coding – 时空分层):
- 时域分层 (Temporal): 不同的帧率 (15fps -> 30fps -> 60fps)。
- 空域分层 (Spatial): 不同的分辨率。
- 质量分层 (Quality): 不同的清晰度。
- 原理: 客户端只发送 一路 视频流,但这路流包含多个“层级”(Base Layer 基础层 + Enhancement Layers 增强层)。
- 依赖性: 增强层必须依赖基础层才能解码。如果基础层丢了,增强层全是废数据。
- SFU 行为: SFU 充当“提取器”,根据接收端带宽,丢弃不需要的增强层数据包,只转发基础层或部分增强层。
弱网调度策略:
- Simulcast 场景: 当上行带宽不足时,发送端 WebRTC 引擎会利用
Padding或直接停止发送高分辨率流(High),只保中低流。接收端如果弱网,SFU 会直接停止转发 High 流,切到 Low 流,切换过程可能需要请求关键帧(PLI),会有瞬间黑屏或卡顿。 - SVC 场景: 更加平滑。当带宽波动时,SFU 只需要丢弃最外层的增强层数据包(例如丢弃 T2 层,帧率从 30 降到 15)。因为基础层还在,接收端解码器不会花屏,只是视频变模糊或帧率变低,不需要重新请求关键帧,体验更流畅。
2、【拥塞控制篇】Google Congestion Control (GCC) 是 WebRTC 的核心拥塞控制算法。请详述 GCC 中 “基于延迟的控制器” (Delay-based) 和 “基于丢包的控制器” (Loss-based) 是如何协同工作的?在 Transport-CC (TWCC) 出现后,控制逻辑发生了什么位置上的变化?
考察点: GCC 算法细节、Trendline 滤波器、Transport-wide Congestion Control。
参考答案:
GCC 的两大引擎:
- 基于延迟 (Delay-based Controller):
- 核心逻辑: 监测包的到达时间梯度。如果
到达时间差 - 发送时间差 > 0,说明网络 buffer 正在堆积(拥塞预兆)。 - 算法: 使用 Kalman Filter(旧版)或 Trendline Filter(新版)来平滑计算延迟梯度。
- 状态机: 判定网络处于
Overuse(过载)、Underuse(欠载)还是Normal,据此由 AIMD(加增倍减)算法调整发送码率。 - 特点: 反应灵敏,用于探测带宽上限。
- 核心逻辑: 监测包的到达时间梯度。如果
- 基于丢包 (Loss-based Controller):
- 丢包 < 2%:提升码率 (
1.05 * current)。 - 丢包 2% – 10%:保持码率。
- 丢包 > 10%:直接降低码率 (
current * (1 - 0.5 * loss_rate))。
- 核心逻辑: 依据 RTCP Receiver Report 中的丢包率(Packet Loss Ratio)。
- 规则:
- 特点: 反应较慢,作为最后的保底手段(因为一旦丢包,说明 buffer 已经溢出)。
- 丢包 < 2%:提升码率 (
协同工作 (取最小值):最终的发送码率 = min(DelayBasedEstimate, LossBasedEstimate)。通常由延迟控制器探测带宽,一旦发生物理丢包,丢包控制器会强行压低带宽。
Transport-CC (TWCC) 的变革:
- 旧版 GCC (Receiver-side): 延迟计算逻辑在接收端运行,计算出建议码率后,通过
REMB(RTCP) 消息回传给发送端。 - 新版 GCC (Sender-side / TWCC):
- 接收端变为“哑节点”,只记录每个包的到达时间,通过
Transport-Feedback消息把原始数据回传给发送端。 - 所有的计算逻辑(Delay & Loss)全部移至发送端。
- 优势: 发送端掌握全局信息,更容易配合 Pacer(发包平滑器)进行调节,且不需要等待 REMB 往返,响应更快。
- 接收端变为“哑节点”,只记录每个包的到达时间,通过
3、【QoS 机制篇】在对抗弱网时,FEC (前向纠错) 和 ARQ (NACK 重传) 是两种主要手段。请分析:在 RTT (往返时延) 很大和 RTT 很小 两种场景下,应该优先选择哪种策略?WebRTC 中的 NACK, PLI, FIR 有什么具体区别?
考察点: 弱网对抗策略、RTP 协议扩展、关键帧请求机制。
参考答案:
FEC vs ARQ 选择策略:
- RTT 很小 (如 < 50ms): **优先 ARQ (NACK)**。
- 因为重传回来得很快,不会导致播放缓冲区耗尽。FEC 需要占用额外的冗余带宽(Redundancy),在低 RTT 下,重传的“按需付费”比 FEC 的“预付费”性价比更高。
- RTT 很大 (如 > 200ms) 或 丢包率极高:优先 FEC。
- 高 RTT 下,发现丢包再请求重传,等包回来时已经错过了渲染时间(过期了)。FEC 通过增加冗余包(如 ULPFEC 或 FlexFEC),接收端无需重传即可通过数学计算恢复丢失的包,以带宽换延迟。
NACK, PLI, FIR 的区别:
- NACK (Negative Acknowledgement):
- 含义: “我丢了序列号为 X 的包,请重传这一个包”。
- 场景: 普通的丢包,解码器还能撑住,只需要补齐数据即可。
- PLI (Picture Loss Indication):
- 含义: “我这边画面已经花屏或者无法解码了(通常是因为丢了关键参考帧,或者 NACK 失败多次),请你重新发一个关键帧 (Keyframe/IDR) 给我”。
- 场景: 严重丢包导致解码依赖链断裂。这会导致发送端重新编码 IDR 帧,瞬间码率飙升。
- FIR (Full Intra Request):
- 含义: 作用与 PLI 几乎一样,请求关键帧。
- 区别: PLI 是 RFC 4585 定义的特定于 Payload 的反馈;FIR 是 RFC 5104 定义的通用控制信令。在多流切换(SFU 切流)场景下,SFU 通常发送 FIR 要求发送端重置编码器。
4、【安全与连接篇】WebRTC 强制使用 DTLS-SRTP 进行加密传输。请描述 DTLS 握手过程中,ClientHello 和 ServerHello 是如何确定角色的?SDP 中的 a=setup:active/passive/actpass 属性在这个过程中起到了什么决定性作用?
考察点: DTLS 握手状态机、SDP 协商机制、P2P 连接建立。
参考答案:
DTLS 角色问题:DTLS 是基于 UDP 的 SSL/TLS。在传统的 C/S 架构中,谁是 Client 谁是 Server 很明确。但在 WebRTC P2P 场景中,两个对等端必须协商出 “谁充当 TLS Client(发送 ClientHello)”,“谁充当 TLS Server(回应 ServerHello)”。
SDP 属性 a=setup 的作用:这个协商完全依赖 SDP Offer/Answer 模型中的 a=setup 属性:
- Offer 端 (发起方):
- 通常设置为
a=setup:actpass。 - 含义: “我可以是 Active(Client),也可以是 Passive(Server),由你(Answerer)来定”。
- 通常设置为
- Answer 端 (响应方):
- 收到
actpass后,Answer 端必须做出选择。 - 如果 Answer 选
a=setup:active:它将作为 DTLS Client,主动发起ClientHello。 - 如果 Answer 选
a=setup:passive:它将作为 DTLS Server,等待对方握手。 - 注:WebRTC 标准规定,Answerer 几乎总是选择
active。
- 收到
- 最终结果:
- Offer 端 收到 Answer 的
active后,自己变为passive(Server)。 - Answer 端 变为
active(Client),向 Offer 端发送 DTLS ClientHello。
- Offer 端 收到 Answer 的
指纹验证 (Fingerprint):SDP 中还包含 a=fingerprint:sha-256 ...。DTLS 握手完成后,双方会计算对方证书的哈希值,并与 SDP 中传输的指纹进行比对。如果匹配,说明中间没有“中间人攻击 (MITM)”,SRTP 密钥派生才会开始。
5、【音画同步篇】在 RTP 层面,音频流和视频流的时间戳 (Timestamp) 频率和起始值都是独立的且随机的。接收端是如何利用 RTCP Sender Report (SR) 将这两条独立的流对齐到同一个“时间轴”上实现 Lip-sync(唇音同步)的?
考察点: RTP/RTCP 协议原理、NTP 时间、同步算法。
参考答案:
问题的核心:
- 音频 RTP 时间戳步进由采样率决定(如 48kHz,每秒增加 48000)。
- 视频 RTP 时间戳步进由 90kHz 时钟决定(每秒增加 90000)。
- 两者的随机起始值(Random Offset)完全不同,仅靠 RTP 头部无法知道“视频的第 1000 帧”对应“音频的哪一秒”。
RTCP Sender Report (SR) 的桥梁作用:发送端会周期性发送 RTCP SR 包,SR 包中包含一对关键映射数据:
- RTP Timestamp: 当前流的某个 RTP 时间戳。
- NTP Timestamp: 该 RTP 时间戳对应的绝对墙上时间 (Wallclock Time,通常是自 1900 年以来的秒数)。
接收端的同步计算逻辑:
- 建立映射: 接收端收到音频 SR,计算出
Audio_NTP = f(Audio_RTP);收到视频 SR,计算出Video_NTP = f(Video_RTP)。 - 统一基准: 当播放一个视频帧(RTP 为 )时,通过线性回归或最近的 SR 计算出它对应的绝对时间 。同理计算音频采样 。
- 计算 Diff:
Diff = T_{video} - T_{audio}。 - 调整播放:
- 如果
Diff > 0(视频比音频快):视频帧放入渲染队列等待,或者音频加速播放。 - 如果
Diff < 0(视频比音频慢):视频直接渲染(追赶),或者丢帧。 - WebRTC 默认策略:Audio is Master。视频去将就音频,因为人耳对音频卡顿/变速非常敏感,而对视频快进/慢放容忍度较高。
- 如果
学习和提升音视频开发技术,推荐你加入我们的知识星球:【关键帧的音视频开发圈】

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。