Visual LabINTERACTIVE LEARNING
阶段 9 · 原生实践高级32 分钟

原生音画同步:时钟、队列与丢帧策略

Audio Clock、Video Clock、External Clock 与 Drift Correction

实现以音频为主时钟的视频调度,处理早到等待、轻微漂移校正、严重迟到丢帧与 Seek 后时钟重置。

LEARNING GOALS

先明确本课目标

1

从已播放样本估算 audio clock

2

按视频 PTS 计算展示延迟

3

设计漂移阈值和丢帧策略

MENTAL MODEL · 再建立心智模型

音频设备是匀速传送带,视频帧像带预约时间的包裹;调度器比较预约 PTS 与传送带时钟,决定等、送或丢。

MINIMAL EXAMPLE

视频比音频早 60ms 时应该做什么?

先把视频 PTS 和 audio clock 换算到同一秒数,diff=videoPTS-audioClock。正值表示视频早到,应延迟;负值表示视频迟到,超过阈值才考虑丢帧。

最小例子cpp
double diff = videoPtsSeconds - audioClockSeconds;
if (diff > syncThreshold) {
  scheduleAfter(std::min(diff, maxDelay));
} else if (diff < -dropThreshold) {
  dropFrame();
} else {
  renderOnNextVsync();
}
  1. 统一时间域求差 PTS 与设备时钟必须都换算为秒。
  2. 早到则有限等待 设置 maxDelay 防止异常时间戳导致长时间停顿。
  3. 严重迟到才丢帧 死区内正常展示,避免对微小抖动过度反应。

视频围绕连续音频时钟稳定展示,并能在解码落后时主动追赶。

本课概念
OPTIONAL · 按需查阅完整术语表与概念边界

遇到陌生术语时再展开,不打断主线实验。

展开⌄
LIVE EXPERIMENT · 先获得反馈

边改边运行

浏览器加载后会激活代码编辑器、独立运行环境与实时输出。

本课挑战

实现一个带时钟死区、最大校正幅度和连续丢帧保护的调度器。

DEEP DIVE · 实验之后

回到原理,解释刚才发生了什么

先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。

CORE IDEA

核心讲解

01

音频常作为主时钟

声卡连续消费样本,其播放位置可由已提交样本减缓冲剩余估算。视频较容易通过等待或丢帧调整。

02

不要追逐每个微小误差

调度需要死区和上限。小误差保持原帧时长,中等误差微调延迟,大误差才丢帧或重同步,避免画面抖动。

OPTIONAL · 迁移时查阅Web 与原生实现对照

主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。

展开⌄
API COMPARISON

HTMLMediaElement 把同步做成黑盒,原生播放器必须把误差和决策变成可观测指标。

WebGL

以设备播放进度估算 audio clock,视频刷新线程按 PTS 和 diff 调度。

WebGPU

浏览器内部协调 audio/video;自建 WebCodecs 播放器可用 AudioContext.currentTime 作为参考。

同步代码必须同时记录 master clock、frame PTS、diff 和最终决策,否则很难诊断。