音视频同步需用 performance.now() 和 audiocontext.currenttime 作高精度时间源,以 requestanimationframe 驱动视频渲染并按 pts 对齐音频时钟,避免定时器和自旋等待,统一时间戳单位后依据 ±40ms 差值触发同步调整。

音视频同步在前端不能靠 setInterval 或 setTimeout 实现,因为它们的精度差、不可靠,且受事件循环阻塞影响严重。真正能支撑毫秒级同步的,是浏览器提供的高精度时间接口与渲染调度机制,而不是“轮询式”定时器。
用 performance.now() 代替 Date.now() 做时间度量performance.now() 返回的是以微秒为单位、高分辨率的单调递增时间戳(通常精度达 1–5 微秒),不受系统时钟调整影响,适合做音视频帧间差值计算。而 Date.now() 精度只有毫秒级,且可能因 NTP 校时跳变,完全不适合同步逻辑。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
用 requestAnimationFrame 驱动视频渲染,而非定时器
视频帧应严格按其 PTS(Presentation Time Stamp)对齐屏幕刷新节奏。requestAnimationFrame 的回调触发时机贴近显示器垂直同步(VSync),天然适配 60fps 渲染节拍。你只需在每一帧回调中:
- 查询当前
performance.now() - 计算该视频帧应呈现的绝对时间(如:baseTime + ptsMs)
- 若未到时间,跳过渲染;若已超时,标记丢帧或加速补偿
音频作为主时钟源,需依赖 AudioContext 的 currentTime
Web Audio API 的 AudioContext.currentTime 是浏览器内最稳定、最低延迟的时间源,精度可达亚毫秒级。它由底层音频硬件时钟驱动,不受 JS 主线程卡顿影响。同步逻辑应以它为基准:
- 初始化时记录
audioContext.currentTime与首帧音频 PTS 的偏移 - 后续所有视频 PTS 都转换为对应
audioContext.currentTime下的预期播放时刻 - 视频渲染时机 =
audioContext.currentTime + (videoPTS - audioFirstPTS)
避免“主动等待”,改用“就绪即播”策略
不要写 while (performance.now() 这类自旋等待——它会阻塞主线程、耗电、且不准。正确做法是:
- 维护一个待渲染帧队列(按 PTS 排序)
- 在 rAF 回调中取出队首帧
- 若
audioContext.currentTime >= 对齐后目标时间,立即渲染;否则缓存、等待下一帧
关键细节:时间戳单位转换必须一致
WebRTC 中视频 RTP 时间戳默认按 90kHz(即每 ms +90),音频按采样率(如 48kHz → 每 ms +48)。做差值前务必统一换算成毫秒:
const videoMs = videoRtpTs / 90.0; // 转毫秒 const audioMs = audioRtpTs / 48.0; // 48kHz 下转毫秒 const diff = videoMs - audioMs;
差值超过 ±40ms 就需触发同步调整(如丢帧、插帧或变速微调)。
不复杂但容易忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










