1. ExoPlayer 音轨架构概览:TrackSelector、MediaSource、Renderer、音轨组与轨道格式

ExoPlayer 的音轨切换能力建立在 四层核心组件 之上:TrackSelector、MediaSource、Renderer,以及底层的数据抽象——音轨组与轨道格式(MimeType)。理解这四者的职责与协作关系,是掌握音轨边界切换的前提。

关键认识:ExoPlayer 的“音轨”并非单一视频或音频流,而是由 TrackGroup 组织的一组可选轨道,TrackSelector 根据应用策略动态选出最佳组合。

1.1 四层组件职责概览

组件 职责 与音轨切换的关系
TrackSelector 选择播放器应使用的轨道(视频/音频/字幕)组合 切换时重新评估轨道,触发 onTrackSelectionsChanged
MediaSource 提供媒体流的数据源,解析并暴露可用轨道信息 负责创建 TrackGroupArray,供 Selector 决策
Renderer 渲染指定轨道的媒体数据(音频、视频、字幕) 接收 Selector 选中的 TrackSelection,缓冲并输出
TrackGroup / TrackFormat 描述一组同质轨道(如多语言音频)与单个轨道的编解码参数 通过 MimeType 区分轨道类型,切换时比对映射

1.2 协作流程图(第 1 章核心 SVG)

ExoPlayer 音轨架构核心组件关系 TrackSelector 选择轨道组合 MediaSource 提供轨道源 Renderer 渲染轨道数据 TrackGroup + MimeType 一组同质轨道 (如多语言音频) 每个轨道有唯一 MimeType 图释: 实线箭头表示数据流或作用方向;虚线箭头表示 Renderer 对已选轨道的消费依赖。 TrackGroup 作为桥梁,将 MediaSource 的原始轨道信息传递给 TrackSelector。

1.3 深入组件细节

1.3.1 TrackSelector —— 决策引擎

  • 继承 DefaultTrackSelector 可获得默认音视频字幕选择逻辑。
  • 核心接口:selectTracks(RendererCapabilities[], TrackGroupArray) 返回 TrackSelection[]。
  • 音轨边界切换本质是重新触发 selectTracks 并应用新选中的 TrackSelection。

1.3.2 MediaSource —— 轨道信息提供者

  • 常见实现:DashMediaSource、HlsMediaSource、ProgressiveMediaSource。
  • 每个 MediaSource 在预处理阶段(prepareSource)解析清单,构造 TrackGroupArray。
  • 一个 TrackGroup 包含多个相同类型、不同比特率/语言/角度的轨道。

1.3.3 Renderer —— 轨道消费者

  • 每种媒体类型对应一个 Renderer:MediaCodecVideoRenderer、MediaCodecAudioRenderer、TextRenderer。
  • Renderer 通过 RendererCapabilities 向 TrackSelector 声明支持的 MimeType 与格式。
  • 切换音轨时,Renderer 会 flush 当前缓冲,重新从新选中的 Track 读取数据。

1.3.4 TrackGroup 与 MimeType

  • TrackGroup:com.google.android.exoplayer2.source.TrackGroup,包含多个 Format。
  • Format 中包含关键字段:sampleMimeType(如 "audio/mp4a-latm")、language、bitrate 等。
  • MimeType 是区分音视频字幕的核心标识:常见有 video/avc、audio/opus、text/vtt。
实践要点:调试音轨切换时,打印 TrackGroupArray 中的每个 TrackGroup 及内部 Format 的 MimeType,能快速定位是解析失败还是选择逻辑未命中。

1.4 常见错误与调优提示

错误场景 原因 解决方向
切换后无声 / 黑屏 Renderer 未正确接收新 TrackSelection,或缓冲未清空 检查 onTrackSelectionsChanged 回调是否触发
MimeType 不匹配 MediaSource 暴露的格式与 Renderer 声明的支持列表不一致 确保 Renderer 注册时包含所需的 MimeType
选择器忽略某些音轨 TrackSelector 配置了语言/比特率过滤条件 暂时禁用过滤,观察 TrackGroupArray 中的完整轨道

1.5 小结