KunSpace
返回博客

Android 音视频同步排查:从抓 Log 到 AudioPosition 二分定位

2026年8月1日
1 次阅读

读完了?别空手走啊 😏

这行字出现时,你的大拇指应该已经 itch 了

写评论

读完了不评论,作者会以为你在沉思

这篇写什么?

盒子 / STB 上「画面有、声音也有,但口型对不上」是播放问题里很常见的一类。原因可能在:

  • 同步策略(播放器以内音频为基准,还是 Tunnel 交给底层)
  • 时钟 / Position(AudioPosition、Video 送显、AudioHal position 谁和系统时间对不上)
  • 码流 PTS(解码前后跳变、喂数不连续)
  • 特定电视 + 音频格式路径(auto / none / passthrough 透传到电视再解码)

本文把现场常用的抓 log 要求、同步方案、分析步骤和一份真实计算案例整理成可复用路径。框架背景可先看:Android 音频框架总览;「有画无声」见:无声排查手册

Android 音视频同步排查主流程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 Formatsauto / none / passthrough
现象描述 声音超前还是落后?固定偏移还是越播越漂?起播就偏还是播一段时间后偏?
片源 / App 本地 / Netflix / YouTube / DVB;码率与音频格式(AAC / AC3 / E-AC3 等)
同步模式 播放器内部同步,还是 Tunnel(见下一节)

抓 log 入口(现场常用):

  1. Get AV information from STB(按你们平台的 AV 信息采集流程出一份)
  2. 复现过程完整 logcat(至少覆盖起播到问题稳定出现的一段时间)
  3. 附上:电视型号、Select Formats 选项、复现步骤与概率

Select Formats 为什么单独点名:在 passthrough / auto 下,压缩音频可能透传到电视再解码,延迟来自 TV 侧解码与缓冲,盒子上按「本机 PCM 时钟」做同步时,肉眼就会表现为 A/V 不同步。换 none(或强制 PCM)往往能快速验证「是不是电视解码路径」的问题。


一、常见音视频同步方案

1.1 播放器内部做同步(最常见)

方式 做法 典型场景
以音频为基准 Audio 正常往下写;Video 延时送显丢帧,往音频时钟上靠 绝大多数播放器默认策略
内部同步时钟 播放器创建内部时钟;视频和音频都往这个时钟同步 如部分 800MKT / DT Launcher 方案

直觉:人耳对「声音卡顿」比「偶发丢一帧画面」更敏感,所以多数实现选 audio master

1.2 Tunnel:由底层做同步

播放器把同步责任交给硬件 / 框架:

  1. 创建 MediaCodec 时传入 tunnel = true
  2. 创建 AudioTrack 时传入 FLAG_HW_AV_SYNC

此时排查重点会更多落在底层 AV sync、HDMI / 显示管线,而不是应用层「多延时几毫秒视频」。

排查前先问清当前路径是 Player sync 还是 Tunnel,后续看的 log 点不一样。


二、音视频同步问题常见分析步骤

按「谁和系统时间对不上」分层,不要一上来就改播放器阈值。

2.1 AudioPosition 是否与系统时间 match

  1. 检查解码前后的 audio PTS 是否有跳变
  2. 检查 AudioTrack 写数据是否足够且连续(欠写 / 断写会让 position 落后)
  3. 用 AudioTrack 的 Last rendered frame + Timestamp 与墙钟比对(见第四节案例)

2.2 Video 送显是否与系统时间 match

  1. 解码前后的 video PTS 是否有跳变
  2. 解码器出帧是否与系统时间 match
  3. 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

和系统时间比较的方法:

  1. 取一段区间的起点、终点:t0t1(log 时间戳)
  2. 算音频走过的时长:Δaudio = pos(t1) - pos(t0)
  3. 算墙钟走过的时长:Δwall = t1 - t0
  4. Δ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(若有)

分析顺序建议:

  1. 用公式算 Δaudio vs Δwall,确认是否真有 position 漂移
  2. 二分找到第一段漂移窗口
  3. 窗口内查 PTS / write / HAL
  4. 特定电视:改 Select Formats 或换机验证透传路径

六、小结

音视频不同步,本质是 音频时钟、视频送显、系统时间(以及电视侧解码延迟)没有对齐

最容易踩的坑:

  1. 没记录电视型号和 Select Formats,把透传 TV 解码延迟当成播放器 bug
  2. 只听感觉不定量:不拿 Last rendered frame 和墙钟算 Δaudio / Δwall
  3. 不分同步方案:Player 内同步与 Tunnel HW sync 的责任边界不同,乱改一侧无效
  4. 不二分时间窗:全程差 100ms 和「某一分钟突然漂 100ms」的根因完全不同

把「复现边界 + Position 定量 + 漂移窗口」三件事做扎实,大部分 A/V sync 问题都能从「感觉不同步」收敛到「哪一段、哪一层时钟先歪了」。

相关阅读:

评论

还没有评论,来做第一个吧

读完了不评论,作者会以为你在沉思