日志获取渠道与基础命令

现象识别:播放失败后第一步做什么

播放失败通常表现为以下现象之一:

  • 视频画面黑屏、卡住、闪退
  • 音频无声音、断断续续、不同步
  • 弹出错误提示框(如“无法播放此视频”“网络异常”)
  • 播放器状态回调返回 Player.STATE_ENDED 却无画面

当现象出现时,第一动作不是修复代码,而是锁定日志采集方式。不同渠道的日志决定了能追查到什么深度的信息。

排查铁律: 先保证当前播放器版本和重现路径稳定,再开启日志。不要在无日志的情况下反复重试,否则浪费排查窗口。

数据采集:三大日志获取渠道

ExoPlayer 播放失败的日志可以从以下三个渠道获取,每种渠道适用不同场景:

渠道 适用场景 特点
ADB logcat(实时) 开发阶段、真机调试、无根权限设备 无需修改代码,可过滤标签和级别;但日志量多,易被冲走
播放器内部日志开关 线上场景、用户反馈复现、需要持久化日志 需提前在代码中启用,输出到文件;可控制详细程度
系统日志 API(EventLog) 框架层问题、编解码器崩溃 需 adb 权限,适合深度底层分析

1. ADB logcat 过滤命令

最常用的实时渠道。使用以下命令组合精确捕获 ExoPlayer 日志:

# 过滤 ExoPlayer 相关标签(大小写敏感)
adb logcat -v threadtime ExoPlayer:I MediaCodec:I *:S

# 同时保留 MediaCodec 和播放器内部事件
adb logcat -v threadtime | grep -E "(ExoPlayer|MediaCodec|TrackSelector|LoadControl)"

# 输出到文件并带上时间戳
adb logcat -v threadtime -f /sdcard/playback_log.txt -r 2048 -n 3 *:V
推荐最低级别: 排查播放失败时,至少使用 I(Info)级别。若出现解码错误或缓冲区问题,升级到 V(Verbose)并配合 MediaCodec 标签。

2. 播放器内部日志开关

在 ExoPlayer.Builder 中通过 setLogLogger 或全局 LogManager 开启:

// 在 Application 初始化时开启
DefaultLogLogger.Factory factory = new DefaultLogLogger.Factory();
factory.setLogLevel(Log.LEVEL_INFO); // V:2, D:3, I:4, W:5, E:6
LogManager.setLogLoggerFactory(factory);

输出路径默认为 Logcat;如需写入文件,可自定义 LogLogger 实现。

3. 日志级别选择判断规则

根据问题现象快速决定日志级别:

  • 播放无法开始 → Info 级别 + 过滤 TrackSelector、LoadControl
  • 播放中卡顿、跳帧 → Debug 级别 + 过滤 MediaCodec、Decoder
  • 解码正常但无画面/声音 → Verbose 级别 + 过滤 Renderer、AudioSink
  • 频繁崩溃 → Error 级别 + 获取 tombstone 和系统日志
避免误区: 不要一开始就开 Verbose 级别,会导致日志刷屏、丢帧、甚至影响性能。先收窄范围,再逐步放宽松。
日志采集决策流程 播放失败现象出现 是否需要实时日志? ADB logcat 过滤 内部日志开关 选择日志级别(V/D/I/W/E) 采集日志文件/流 分析定位根因 根据问题现象匹配日志级别:卡顿用 D,崩溃用 E,音画不同步用 V

原因定位:从日志中快速抓取关键线索

采集到日志后,优先搜索以下关键词(按出现频率排序):

  1. PlaybackException – 播放器抛出的异常,包含错误码和说明
  2. MediaCodec error – 编解码器初始化或运行失败
  3. Track selection failed – 轨道选择无法匹配
  4. Source error – 数据源(网络/本地)读取异常
  5. DRM error – 数字版权管理问题
快捷定位命令(Linux/Mac):
grep -E "(Exception|error|fail|crash)" playback_log.txt | head -30

修复动作:配置正确的日志开关

若发现日志缺失或级别不够,按以下步骤调整:

  • 在 Application.onCreate() 中设置 LogManager.setLogLevel(Log.LEVEL_VERBOSE)
  • 为线上版本添加 LogLogger 写入文件,保留最近 3 次播放日志(循环覆盖)
  • 在 ExoPlayer.Builder 后调用 player.setHandleWakeLock(false) 避免日志丢失

复测:验证日志产出

复现一次播放失败,检查是否产生以下预期输出:

# 期望的 logcat 示例片段
ExoPlayerImpl: Init 4.0.0 [1080p, dp=480]
MediaCodecVideoRenderer: video decoder output format changed: surface=0x...
TrackSelector: selected track: video/avc, audio/mp4a-latm
PlaybackException: PlayerError{type=SOURCE, code=4002, message="IO error"}

如果日志未出现,检查是否被其他进程日志淹没(改用 grep 或调整过滤标签),或确认内部日志开关已生效。

预防:建立日志命名与轮转规范

  • 统一日志文件名前缀:exo_dump_yyyyMMdd_HHmmss.log
  • 单文件最大 2MB,保留 5 个文件(通过 LogLogger 实现)
  • 发布版本默认关闭 Verbose,通过动态配置开关按需打开(例如白名单设备或摇一摇触发)
  • 在 CI 中集成日志校验规则:若构建版本未包含日志开关,则报警提示
实战建议: 在播放器初始化时输出一行 TAG = "ExoPlayerInit" 的 Info 日志,方便后续快速定位日志起点。