
简介ITU-R BT.1359-1是国际电信联盟ITU发布的音视频相对时序推荐标准面向广播工程师、视频处理和音频制作人员用于解决节目制作与传输中的声画不同步问题。压缩包内仅1个PDF文件约138KB为英文标准全文内容包含时间零点定义、整体容差90ms至-185ms、图像源与零点间25ms至-100ms的控制区以及主观察觉阈值约45ms至-125ms和可接受阈值约90ms至-185ms。标准还解释了独立图像/声音处理、数字设备、串联工作室等引入延时的原因并给出各下游环节不超过±2ms的误差建议同时明确了测量参考点设在最终节目源选择元素处可直接用于延时预算计算、合规性验证及主观测试方案设计。目前已有323人学习适合音视频同步设计、测试和学术引用也可作为技术报告与论文的规范依据。1. 音视频同步 ITU-R BT.1359先说结论声音比画面早 15ms 就要治做直播或者点播交付时最怕的不是码率不够而是用户一句“口型对不上”。你翻遍编码参数、CDN 日志最后往往是音视频同步问题声音和画面之间存在一个相对偏移也就是音视频延时。ITU-R BT.1359 正是广播电视领域解决这类问题最常被引用的建议书它把音视频延时要求定成了一个不对称的容限窗口声音相对画面提前不超过约 15ms滞后不超过约 45ms。这篇文章就顺着这个标准往下走先讲清容限逻辑再给可复现的测量方法和补偿命令最后把 BT.1359 落到监控告警上。适合广播运维、编码转码开发和流媒体技术同学直接抄作业。2. ITU-R BT.1359 的容限逻辑15ms 与 45ms 从哪里来2.1 标准定义的是“相对定时”不是“总延时”很多人第一次接触 BT.1359 时有个误解以为它规定了“从摄像头到用户端的总延时不能超过多少毫秒”。实际上 ITU-R BT.1359 全名是《Relative timing of sound and vision for broadcasting》中文可译作《广播中声音与图像相对定时》。它关心的不是整条链路花了多少时间而是同一个节目里声音到达耳朵的时刻和图像到达眼睛的时刻相差多少。这个“相对差”才是音视频同步的核心。假设一条直播链路从采集到播出要花费 800ms如果声音和画面都被同时推后 800ms观众完全感知不到问题真正刺眼的是音频先到了 20ms或者视频先到了 100ms。所以工程上我们常说的 AV offset、lip sync error、audio/video relative delay指的都是这个相对偏差而不是链路总耗时。BT.1359 在行业里最常被引用的数值是一个不对称窗口声音领先画面sound leading vision不超过 15ms声音落后画面sound lagging vision不超过 45ms。少数资料会把 5ms / 15ms 说成 BT.1359 的要求那多半是把 EBU R37 的播出验收限值混进来了。BT.1359 给的是系统级可接受上限EBU R37 给的是更严格的播出信号质量标准两者适用场景不一样。2.2 15ms / 45ms 容限从哪来不对称的主观感知标准为什么把“提前”和“滞后”区别对待原因在人的感知特性。主观实验里观众对“声音先到”明显更敏感画面上一个人刚张嘴声音却先冒出来哪怕只有十几毫秒也会让人产生“看外国片配音没对上”的不适感反过来声音稍微晚到一点人会把它解释成声音从远处传来的延迟容忍度大得多。所以 BT.1359 的容限是一个不对称窗口声音早到 15ms 就必须处理声音晚到可以放到 45ms。这个结论也直接决定了补偿策略。实际做系统时我不会把目标设成“零误差”因为链路上任何一个小抖动都会让零值变成负值而负值方向更容易被观众察觉。把目标控制在 -5ms 到 30ms 之间比死磕 0ms 更稳妥既留了抖动余量也完全落在 BT.1359 窗口内。另外标准讨论的是“可接受”而不是“不可感知”。语言类节目比如新闻主播、访谈唇读信息强烈15ms 已经算临界纯音乐、体育比赛、宣传片这类画面与嘴型弱相关的内容实际可以放到更宽。做项目时我会按内容类型决定告警阈值而验收基线一律按 BT.1359 来。2.3 为什么编码链路会把音视频延时做歪增量累积一条典型的播出链路里音视频相对偏移是多个环节“增量”叠加的结果。视频编码器有 B 帧重排、GOP 缓存、码控 lookahead音频编码器有 AAC/AC-3 的帧缓冲和前置采样响度归一化处理器里的 look-ahead 限幅器也会给音频额外增加 10ms 到 50ms 的延迟。再到传输侧IP 抖动缓冲、FEC 交错、PCR 抖动修正都可能让音视频时间戳的到达节奏发生相对变化。这些延迟并不总是同方向。视频编码器往往比音频晚交出数据所以你会看到“音频早到”而 AC-3 解码器又会把音频按住一段时间导致“声音迟到”。链路越长正负偏移就越不可预测。BT.1359 的价值正在于给这个失控的累积过程画了一条底线不管中间经过多少设备在链路出口处声音相对画面的偏移必须落在 -15ms 到 45ms 内。下面就从测量开始把这条底线变成可执行的流程。3. 把音视频延时测出来测试信号、示波器与 ffprobe 三种量法3.1 先做一个可以复现的测试源测量音视频延时前提是有一个“起点明确”的测试信号。行业里最常见的做法是一段带秒表计数的测试卡画面叠加一个 1kHz 猝发音画面的时间码给出视频基准音频脉冲的起始沿给出声音基准。没有专用测试卡发生器时用 ffmpeg 可以现场生成一个。ffmpeg -f lavfi -i testsrc2size1280x720:rate25:duration10 \ -f lavfi -i sinefrequency1000:sample_rate48000:duration9 \ -filter:a adelay1000:all1 \ -c:v libx264 -preset veryfast -c:a pcm_s16le avsync_probe.mkv这段命令生成一个 10 秒的测试片段testsrc2画面自带滚动时间码每一帧都能读出精确到 1 秒的计数音频是 1kHz 正弦但通过adelay1000:all1被整体推迟到第 1 秒才开始。这样做的目的是给音频一个尖锐的起始沿方便在波形上定位。all1表示所有声道都延迟相同毫秒数避免多声道之间再引入新的相对偏差。视频用veryfast预设只是为了让本地测试源生成快一些实际过链路时建议用更高画质预设避免编码器自身的延时污染测量结果。3.2 电信号判读为什么“听起来差不多”不算数很多现场工程师习惯用耳朵判断音画同步这是最容易翻车的环节。人对音画偏移的主观感知存在个体差异而且越紧张越觉得不对凭感觉说“好像差了一帧”往往差到 100ms 以上远超 BT.1359 的容限。规范的测量方法是把测试源送入被测链路在链路输出端录一段信号然后用非编软件或示波器测量。具体步骤是把生成的 avsync_probe.mkv 从链路起点播放在链路出口用采集卡录回一段 10 秒信号把录回的文件导入非编软件在音频轨道上找到 1kHz 猝发音的起始沿再在视频轨道上读同一时刻的测试卡时间码。如果音频起始沿出现在时间码 00:00:01:00 处说明链路音视频相对偏移为零如果起始沿落在 00:00:01:10说明音频比视频晚了 10ms25fps 下 10 帧约等于 400ms注意换算。测量对象参考信号判读方式分辨率视频testsrc2 时间码/白场切换沿非编软件逐场定位帧 40ms场 20ms音频1kHz 猝发音起始沿波形编辑器看采样起点约 0.02ms48kHz 采样下要提高分辨率优先看视频的“场”而不是“帧”。1080i50 下每一场是 20ms帧是 40ms音频侧直接放大波形48kHz 采样率下每个采样只有约 0.02ms。这样组合起来测量精度可以到 20ms 以内已经足够判定 BT.1359 是否超限。注意不要用视频播放器自带的 A/V 同步显示功能当依据很多播放器会主动做追帧补偿反而掩盖了链路真实状态。3.3 用 ffprobe 做批量的 AV offset 粗筛示波器加非编的测量方式准确但没法每天巡检几百个文件。更实际的做法是用 ffprobe 读取音视频流的起始时间戳快速计算封装层的 AV offset作为批量粗筛手段。V$(ffprobe -v error -select_streams v:0 -show_entries streamstart_time -of csvp0 input.ts) A$(ffprobe -v error -select_streams a:0 -show_entries streamstart_time -of csvp0 input.ts) OFFSET$(awk -v a$A -v v$V BEGIN{printf %.4f, a - v}) echo A-V offset $OFFSET seconds这段脚本的输出是音频流起点减去视频流起点单位秒。结果为正值表示在封装层音频起点比视频晚负值表示音频起点更早。整个逻辑只做一件事从容器里读出两个流各自的start_time再相减不涉及解码所以速度快适合批量脚本。但它有一个明显局限只能反映“文件把音视频写在哪个位置”不能代表解码器输出、声卡渲染之后的真实感知偏移。实际使用中我把它当第一道筛子发现异常再上示波器和非编复核。后面第 6 章会讲如何给这个粗筛值乘上链路标定系数让它更接近真实偏移。4. 把偏移拉回容限内音频延迟、-itsoffset 与编码器补偿4.1 补偿前先统一符号约定听感和电信号之间经常出现“越补越歪”的翻车事故多半是符号约定没统一。我在团队里强制规定所有测量和补偿脚本里AV offset 一律按“正 音频晚到”来写。也就是说 offset 音频时刻 - 视频时刻正值表示声音出来得晚负值表示声音出来得早。这个约定和 ffprobe 的计算方式一致也和 BT.1359 的方向描述一致声音领先、声音滞后后续就不会反。补偿口诀只有一句音频晚了就把它提前音频早了就把它推后。下面两个命令分别对应这两个方向。4.2 音频早到用 adelay 把声音推后如果实测结果是音频比视频早 20ms也就是 offset 约为 -0.020 秒最直接的修法是给音频加一个正向延迟把它往后推。ffmpeg -i input.ts -af adelay20:all1 -c:v copy -c:a aac corrected.tsadelay20给所有声道增加 20ms 延迟单位是毫秒all1指定这个延迟应用到所有声道。加大延迟后音频编码器会重新工作所以音频编码写成了aac视频流用-c:v copy不动。这个命令适合处理已经封装好的文件也适合在转码环节临时修正。需要注意adelay 会引入等量的额外编码时间但不会改变音频的采样率误差范围在采样级完全可以接受。4.3 音频晚到用 -itsoffset 把声音提前如果音频比视频晚 30ms也就是 offset 约为 0.030 秒需要把音频整体提前。常见做法是对音视频源文件各读一次用-itsoffset把音频输入流的起始时间戳提前。ffmpeg -i corrected.ts -itsoffset -0.030 -i corrected.ts \ -map 0:v -map 1:a -c:v copy -c:a aac final.ts这里同一个文件被 ffmpeg 打开了两次第一个输入取视频-map 0:v第二个输入通过-itsoffset -0.030把时间戳整体减掉 30ms再取音频-map 1:a。命令里的负号表示提前正号表示推迟。结果就是音频相对视频提前了 30ms正好把晚到的问题抵消。注意两个输入来自同一文件时ffmpeg 需要在读取端多留一些缓冲录制长文件时建议加-max_interleave_delta防止音视频交错缓存不足但这个参数不是每次都需要。4.4 编码器/复用器里的持久化设置用 ffmpeg 修文件适合事后补救但在直播、转码服务里更合理的做法是把补偿量配置在编码器或复用器里让链路出口始终落在 BT.1359 窗口内。常见做法是找音频处理单元里的 “Audio Delay”、“A/V Offset”、“Lip Sync” 参数。注意不同厂商对这个参数的正负号定义完全不同有的设备数值为正表示把音频推迟有的数值为正表示把音频提前配置前必须先看设备手册最好用测试源实测确认方向。如果你在 GStreamer 链路里工作audiodelay元素和adelay行为类似可以直接插在音频队列后面。硬件编码器改参数后必须重新跑一遍测试源不能只依赖面板读数。我的习惯是每次改完都记录三组数据改之前偏移、设备参数、改之后偏移这样即使符号定义再混乱也能靠实测数据兜底。5. 音视频延时排查五个翻车现场和对应解法5.1 翻车现场一解码器黑匣子AC-3 出来晚了 40ms现象编码器输出端测出来偏移是 0ms观众仍然反馈声音滞后。 原因编码器输出的是 AC-3 码流到了终端解码器里AC-3 需要按帧积累缓冲才能解码这个缓冲加上解码器内部处理固定引入 40ms 左右延迟。很多专业解码器的这个延迟在规格书里写得很隐蔽不测根本发现不了。 解决在编码器前的音频处理单元里把声音提前 40ms让解码端输出的最终结果回到 0 附近。注意补偿位放在编码前不是编码后否则又会把延迟重新加回去。5.2 翻车现场二一次转码让声音“早到”20ms现象源文件测出来是 5ms经过一次 AAC 转码后变成 -20ms声音反而比画面早了。 原因AAC 编码器自身带 lookahead 延迟转码时视频被 B 帧重排多留了几帧音频却没被等量推迟于是音频相对视频“跑”到了前面。这种问题最容易出现在硬件转码服务里因为视频 GOP 结构变了音频编码参数没跟着调。 解决先读转码日志里的 encoder delay 参数确认音频输出端实际延迟再对音频加adelay把偏移拉回窗口内。转码服务建议直接在流程里配置自动 AV offset 补偿而不是每次手动改。5.3 翻车现场三测量点不一致输入端零误差、接收端超限 30ms现象在演播室输出口量BT.1359 完全达标到了 IPTV 机顶盒出来一量声音晚了 30ms。 原因多了 IP 抖动缓冲、解码器和机顶盒自身的音频增强处理。这些终端设备为了抗网络抖动会把音频多缓存一小段视频端则没有等量延迟。 解决把测量点分开处理。演播室到播出机房这一段属于系统链路严格按 BT.1359 验收机顶盒到电视机这一段属于用户终端另设一张校准记录。如果终端的固定偏移已知就在链路出口做一次固定的反向补偿如果终端偏移随内容变化至少保证系统链路留出足够裕量别一上来就把 15ms 余量用光。5.4 翻车现场四节目放久了声音越跑越早现象节目开头测一切正常播到第十分钟观众开始抱怨“嘴型和声音对不上”拉出来一看音频提前了 30ms。 原因直播流的 PCR 抖动变大或者视频端发生丢帧后解码器做了追帧而音频端按时间戳连续播放两者节奏出现偏差。这种漂移不是固定值单点测量发现不了。 解决不要只测文件开头分别在开头、中间、结尾各抓 10 秒分析。检查 PCR 的间隔和抖动幅度再看音视频 PTS 的间距是否随时间扩大。漂移类问题用打点式测量很难根治最后往往要回到传输层修正 PCR 或换用带小抖动的音频队列策略。5.5 翻车现场五补偿符号没定死越补越歪现象某次排查发现音频晚到 20ms在编码器里把 “Audio Delay” 调成 20ms出来变成了音频早到 30ms。 原因那台设备的 “Audio Delay” 正数表示“提前音频”而我们习惯的正数表示“推迟音频”。符号定义一冲突整个链路所有补偿全部反掉。 解决在设备台账里标明每台设备的正数含义并在补偿脚本里写死口诀“正 音频晚到补偿量 -实测偏移”。晚到 20ms 就把补偿写成 -20ms早到 15ms 就把补偿写成 15ms然后再做一轮实测验证。这个约定成本很低但能避免大多数人为返工。6. 把 BT.1359 变成自动化监控告警阈值与一圈检查清单手动测量只能解决问题不能防止问题。落地的最后一步是把 BT.1359 的容限写进监控脚本。我习惯把告警分成三档偏移落在 -15ms 到 45ms 内判定正常-30ms 到 -15ms 以及 45ms 到 60ms 为关注区提示观察低于 -30ms 或高于 60ms直接告警并切换冗余链路。#!/usr/bin/env bash IN${1:?usage: av_sync_mon.sh input.ts} V$(ffprobe -v error -select_streams v:0 -show_entries streamstart_time -of csvp0 $IN) A$(ffprobe -v error -select_streams a:0 -show_entries streamstart_time -of csvp0 $IN) CRUDE$(awk -v a$A -v v$V BEGIN{printf %.4f, a - v}) K0.000 OFFSET$(awk -v x$CRUDE -v k$K BEGIN{printf %.4f, x k}) echo crude$CRUDE estimate$OFFSET awk -v o$OFFSET BEGIN{ if (o -0.015) print ALARM audio leads too much; else if (o 0.045) print ALARM audio lags too much; else if (o -0.030 || o 0.060) print ALARM critical; else print OK; }脚本里K是链路标定常数初始设成 0。第一次部署时用第 3 章的示波器/非编方法测出真实链路偏移R再用这个脚本测出同文件的容器偏移C把K R - C填进去。之后脚本输出的estimate就更接近真实链路偏移不需要每次都接示波器。日常巡检时在链路出口每两小时自动录一个 10 秒文件跑一次这个脚本把结果打进监控系统。我现在的习惯是每改一次编码参数就在链路两端放同一套测试源先录 30 秒用非编标定一次K再让脚本盯趋势。这样既能保证新改动没有引入偏移也能在观众投诉前把问题拦下来。音视频同步看起来像玄学其实把阈值、符号、测量点三件事定死它比码率问题是更好修的。希望帮到你。本文还有配套的精品资源点击获取