这篇写什么?
盒子 / STB 上「画面有、声音也有,但口型对不上」是播放问题里很常见的一类。原因可能在:
- 同步策略(播放器以内音频为基准,还是 Tunnel 交给底层)
- 时钟 / Position(AudioPosition、Video 送显、AudioHal position 谁和系统时间对不上)
- 码流 PTS(解码前后跳变、喂数不连续)
- 特定电视 + 音频格式路径(auto / none / passthrough 透传到电视再解码)
本文把现场常用的抓 log 要求、同步方案、分析步骤和一份真实计算案例整理成可复用路径。框架背景可先看:Android 音频框架总览;「有画无声」见:无声排查手册。


一句话:
先钉死复现电视 + Select Formats
→ 确认同步方案(播放器内 / Tunnel)
→ AudioPosition 是否与系统时间 match
→ Video 送显 / PTS / 喂数是否 match
→ AudioHal position;必要时二分定位漂移窗口
〇、复现时先备齐这些信息
抓 log 之前,先把边界钉死,否则「音视频不同步」会变成全链路乱翻:
| 需要提供 | 为什么重要 |
|---|---|
| 复现问题的电视型号 | 很多问题只在特定 TV / EDID / 解码能力上出现 |
| Select Formats | Settings → Device Preference → Display & Sound → Advanced sound settings → Select Formats:auto / none / passthrough |
| 现象描述 | 声音超前还是落后?固定偏移还是越播越漂?起播就偏还是播一段时间后偏? |
| 片源 / App | 本地 / Netflix / YouTube / DVB;码率与音频格式(AAC / AC3 / E-AC3 等) |
| 同步模式 | 播放器内部同步,还是 Tunnel(见下一节) |
抓 log 入口(现场常用):
- Get AV information from STB(按你们平台的 AV 信息采集流程出一份)
- 复现过程完整 logcat(至少覆盖起播到问题稳定出现的一段时间)
- 附上:电视型号、Select Formats 选项、复现步骤与概率
Select Formats 为什么单独点名:在 passthrough / auto 下,压缩音频可能透传到电视再解码,延迟来自 TV 侧解码与缓冲,盒子上按「本机 PCM 时钟」做同步时,肉眼就会表现为 A/V 不同步。换 none(或强制 PCM)往往能快速验证「是不是电视解码路径」的问题。
一、常见音视频同步方案
1.1 播放器内部做同步(最常见)
| 方式 | 做法 | 典型场景 |
|---|---|---|
| 以音频为基准 | Audio 正常往下写;Video 延时送显或丢帧,往音频时钟上靠 | 绝大多数播放器默认策略 |
| 内部同步时钟 | 播放器创建内部时钟;视频和音频都往这个时钟同步 | 如部分 800MKT / DT Launcher 方案 |
直觉:人耳对「声音卡顿」比「偶发丢一帧画面」更敏感,所以多数实现选 audio master。
1.2 Tunnel:由底层做同步
播放器把同步责任交给硬件 / 框架:
- 创建 MediaCodec 时传入
tunnel = true - 创建 AudioTrack 时传入
FLAG_HW_AV_SYNC
此时排查重点会更多落在底层 AV sync、HDMI / 显示管线,而不是应用层「多延时几毫秒视频」。
排查前先问清当前路径是 Player sync 还是 Tunnel,后续看的 log 点不一样。
二、音视频同步问题常见分析步骤
按「谁和系统时间对不上」分层,不要一上来就改播放器阈值。
2.1 AudioPosition 是否与系统时间 match
- 检查解码前后的 audio PTS 是否有跳变
- 检查 AudioTrack 写数据是否足够且连续(欠写 / 断写会让 position 落后)
- 用 AudioTrack 的 Last rendered frame + Timestamp 与墙钟比对(见第四节案例)
2.2 Video 送显是否与系统时间 match
- 解码前后的 video PTS 是否有跳变
- 解码器出帧是否与系统时间 match
- Player 送入解码器的数据是否足够(视频欠喂 → 画面卡住 / 追时钟时乱跳)
2.3 AudioHal 的 position 是否与系统时间 match
若 App / AudioTrack 层 position 正常,但听感仍偏,继续看 HAL / 输出侧 position,区分「框架时钟」和「真实出声时钟」。
2.4 特定电视复现
确认输入输出格式,以及 auto / passthrough 是否把解码甩给电视。同一片源换电视或改 Select Formats,是最快的二分之一。
电视型号 + Select Formats 钉死
│
AudioPosition ↔ 系统时间? ──否──→ PTS / write / HAL / 透传延迟
│是
Video 送显 ↔ 系统时间? ──否──→ PTS / 解码出帧 / 喂数 / 丢帧策略
│是
仍不同步 ──→ Tunnel 路径、显示链路、或 TV 侧额外延迟
三、用 AudioTrack 日志算 Audio Position
现场常见日志形态(标签与行号因平台略有差异):
I/AudioTrack: [getTimestamp_logTimeStamp:...] Last rendered frame:1824 Timestamp:... nanotime
公式(单位 us):
audio_position_us = Last_rendered_frame * 1_000_000 / sampleRate
例如采样率 48000 Hz:
1824 * 1_000_000 / 48000 = 38_000 us ≈ 38 ms
和系统时间比较的方法:
- 取一段区间的起点、终点:
t0、t1(log 时间戳) - 算音频走过的时长:
Δaudio = pos(t1) - pos(t0) - 算墙钟走过的时长:
Δwall = t1 - t0 - 若
Δaudio < Δwall,说明这段时间里 音频 position 偏慢(声音相对「理想时钟」落后),易表现为音画不同步
若全程都偏一点点且恒定,可能是固定延迟(缓冲 / 透传);若某一段突然拉开,用 二分时间窗 找到第一次漂移区间,再对着该窗口查 PTS、write、underrun、格式切换。
四、案例分析:Audio 比系统时间慢约 100ms
4.1 日志片段(节选)
02-01 20:19:01.728 I/AudioTrack: Last rendered frame:1824 Timestamp:...
02-01 20:19:11.788 I/AudioTrack: Last rendered frame:485024
...
02-01 20:19:51.941 I/AudioTrack: Last rendered frame:2412192
02-01 20:20:11.949 I/AudioTrack: Last rendered frame:3367584
...
02-01 20:23:12.045 I/AudioTrack: Last rendered frame:12012192
4.2 从有有效 frame 开始算整段
假设 sampleRate = 48000:
| 时刻 | Last rendered frame | audio_pos |
|---|---|---|
| 20:19:01.728 | 1824 | 38 ms |
| 20:23:12.045 | 12012192 | 250254 ms |
Δaudio = 250254 - 38 = 250216 ms
Δwall = 20:23:12.045 - 20:19:01.728 = 250317 ms
Audio position 比系统时间慢约 101 ms → 确认存在漂移,不是「感觉问题」。
4.3 二分:定位从哪一段开始漂
继续缩小窗口,最终落到:
20:19:51.941 → frame 2412192
20:20:11.949 → frame 3367584
Δwall = 20008 ms
Δaudio = (3367584 - 2412192) * 1000 / 48 = 19904 ms
这一段慢了约 104 ms;此前窗口基本同步。说明问题更像是 播到某一时刻后开始拉开,而不是「一起播就固定偏 100ms」。下一步应盯住 20:19:51 ~ 20:20:11 附近的:
- audio / video PTS 是否跳变
- AudioTrack write 是否断续、是否 underrun
- 是否发生格式切换、路由变化、隧道/非隧道切换
- 该时段是否叠加了电视侧透传解码抖动
五、现场排查清单(可直接贴工单)
复现时附上:
- Get AV information from STB
- 复现电视型号
- Select Formats:
auto/none/passthrough(截图更好) - 现象:超前 / 落后 / 越播越漂;起播即偏 or 播后出现
- 同步方案:播放器内(audio master / 内部时钟)还是 Tunnel(
tunnel+FLAG_HW_AV_SYNC) - 含问题时段的 AudioTrack
Last rendered frame日志(建议 ≥ 几十秒连续) - 同时段 audio/video PTS、送显与喂数相关 log(若有)
分析顺序建议:
- 用公式算
ΔaudiovsΔwall,确认是否真有 position 漂移 - 二分找到第一段漂移窗口
- 窗口内查 PTS / write / HAL
- 特定电视:改 Select Formats 或换机验证透传路径
六、小结
音视频不同步,本质是 音频时钟、视频送显、系统时间(以及电视侧解码延迟)没有对齐。
最容易踩的坑:
- 没记录电视型号和 Select Formats,把透传 TV 解码延迟当成播放器 bug
- 只听感觉不定量:不拿
Last rendered frame和墙钟算Δaudio/Δwall - 不分同步方案:Player 内同步与 Tunnel HW sync 的责任边界不同,乱改一侧无效
- 不二分时间窗:全程差 100ms 和「某一分钟突然漂 100ms」的根因完全不同
把「复现边界 + Position 定量 + 漂移窗口」三件事做扎实,大部分 A/V sync 问题都能从「感觉不同步」收敛到「哪一段、哪一层时钟先歪了」。
相关阅读:
评论
还没有评论,来做第一个吧
读完了不评论,作者会以为你在沉思