GSYVideoPlayer 如何用 Exo/Media3 的 HLS master 与 DASH MPD 实现自适应清晰度并固定清晰度轨道
【免费下载链接】GSYVideoPlayerVideo players (IJKplayer, ExoPlayer, MediaPlayer), HTTPS, 16k page size, danmaku (bullet chat) support, external subtitles, support for filters, watermarks, and GIF screenshots, pre-roll and mid-roll ads, multiple simultaneous playback, basic seeking/dragging, volume and brightness adjustment, play-while-cache support项目地址: https://gitcode.com/GitHub_Trending/gs/GSYVideoPlayer
当服务端已经能提供标准的多码率流(一个 HLS master playlist,或一个 DASH MPD)时,清晰度切换不需要为每档清晰度维护一条独立 URL。GSYVideoPlayer 的 Exo/Media3 内核支持把这类流交给 Media3 的 TrackSelector:同一 track group 里的多码率 video track 会被用于 adaptive playback,默认按带宽、buffer 和设备能力自动选档;你也可以用 override 把播放固定在某一档,再随时切回自动。demo 工程里的EXO自适应清晰度入口(ExoAdaptiveTrackActivity)完整演示了这条路径。
注意与另一条方案区分:无缝切换(SmartPickVideo)是多个独立 URL 的切换,不是HLS/DASH 标准 ABR,它靠临时 manager 预加载新 URL 后同步位置切换。如果服务端能给 HLS master 或 DASH MPD,优先使用本文的 Exo 自适应方案(依据见 RECENT_FEATURES.md 的“多 URL 清晰度切换”一节)。
准备:构建并安装 demo
demo 的轨道 API 实现在 app 模块内(GSYExoVideoManager 转调 GSYExo2MediaPlayer),所以先用仓库自带的脚本构建并安装。以下命令会执行单元测试并生成 debug APK,然后把 APK 安装到已连接的真机/模拟器上(adb install -r覆盖安装,不删除数据):
./gradlew :gsyVideoPlayer-java:testDebugUnitTest :app:assembleDebug adb install -r app/build/outputs/apk/debug/app-debug.apk这是 RECENT_FEATURES.md “回归建议”一节给出的回归命令,构建产物路径为app/build/outputs/apk/debug/app-debug.apk。启动 demo 后,在主列表打开EXO自适应清晰度入口进入播放页。
内置测试源:HLS master 与 DASH MPD
demo 内置两个测试源(定义在 DemoVideoUrls.java,整理见 VIDEO_URLS.md),页面上有HLS和DASH两个按钮可直接切换源:
| 源 | URL | 说明 |
|---|---|---|
| HLS master | https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8 | DemoVideoUrls.HLS_MUX |
| DASH MPD | https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd | DemoVideoUrls.DASH_ENVIVIO |
自适应播放的搭建路径
ExoAdaptiveTrackActivity的setupPlayer展示了最小搭建顺序。核心是:只用一个 master/MPD URL 走setUp,再用setOverrideExtension标明流类型,然后起播:
List<GSYVideoModel> urls = new ArrayList<>(); // HLS master 或 DASH MPD,二选一 urls.add(new GSYVideoModel(useDashSource ? DASH_MPD_URL : HLS_MASTER_URL, "自适应码率")); binding.detailPlayer.setUp(urls, 0); binding.detailPlayer.setOverrideExtension(useDashSource ? "mpd" : "m3u8"); binding.detailPlayer.setExoCache(false); // ...封面、标题等 UI 配置后... binding.detailPlayer.startPlayLogic();demo 中有两处值得注意的设置:
setExoCache(false):这两个测试源不走 Exo cache;你自己的源是否开 cache 取决于业务需求。- demo 进入页面时把渲染切成
GSYVideoType.SURFACE,onDestroy时恢复进入前的 render type,如果你的业务页面渲染类型不同,不要照抄这两行。
起播后 TrackSelector 默认按“自动”工作:由它根据带宽、buffer、设备能力在同一个 track group 的多码率 video track 之间选择,不需要业务侧做任何选择。
读取轨道并固定清晰度
轨道信息和 override 都通过GSYExoVideoManager暴露(API 见 USE.md “Exo 自适应清晰度相关 API”一节):
// 1. 读取当前轨道列表 List<GSYExo2MediaPlayer.VideoTrackInfo> tracks = GSYExoVideoManager.instance().getVideoTrackInfoList(); // 2. 固定到某一条 video track(参数取自 VideoTrackInfo) boolean success = GSYExoVideoManager.instance() .setVideoTrackOverride(track.groupIndex, track.trackIndex); // 3. 清除 override,恢复自适应 GSYExoVideoManager.instance().clearVideoTrackOverride();VideoTrackInfo的可用字段(见 GSYExo2MediaPlayer.java):
groupIndex/trackIndex:override 时使用的坐标,必须原样取自已读取到的 track 对象;width/height/bitrate/codecs:展示用信息;selected:当前是否被选中;supported:设备是否支持解码该轨道;adaptiveSupported:该 track group 是否支持自适应;getLabel():形如720P 1500kbps的展示文本,选中项末尾追加*标记(例如540P 1200kbps *)。
两点使用前提:
- 播放未解析完成时列表为空。
getVideoTrackInfoList()依赖当前Tracks,manifest 没解析完就返回空列表。demo 的做法是每 1 秒用 Handler 轮询一次轨道信息,空列表时展示“视频轨道:等待播放器解析中”,并监听onPrepared立即刷新。固定清晰度前应先确认列表非空。 setVideoTrackOverride会校验合法性。返回false的情况包括:player 尚未创建、groupIndex越界、该 group 不是 video 类型、trackIndex越界,或该轨道isTrackSupported为false(设备不支持解码)。demo 里只有supported为true的轨道会进入清晰度选择弹窗,切换失败时提示“清晰度切换失败”。
clearVideoTrackOverride()除了清掉 override,还会把forceLowestBitrate/forceHighestSupportedBitrate复位为false并确认 video track 类型处于启用状态,即完整回到 TrackSelector 自适应(实现见 GSYExo2MediaPlayer.java)。
demo 的交互流程可直接参考 ExoAdaptiveTrackActivity.java:点击清晰度按钮弹出列表,第一项是“自动(TrackSelector 自适应)”,其余项是各getLabel();选“自动”调clearVideoTrackOverride(),选具体档位调setVideoTrackOverride(track.groupIndex, track.trackIndex),之后延迟 500ms 再刷新一次轨道信息确认选中项变化。
验证结果
按 RECENT_FEATURES.md 的回归清单,EXO自适应清晰度的通过标准是:HLS 和 DASH 都能播放、轨道列表能显示、自动/固定清晰度能切换。在 demo 页面上逐项对应:
- 轨道列表:页面下方的轨道信息区会显示“当前源:HLS Master / DASH MPD”、源 URL 和逐条轨道;manifest 解析完成前显示“视频轨道:等待播放器解析中”。
- 选中项:轨道文本中带
*标记的是当前选中 track;固定某档后再刷新,标记应移到该档,且清晰度按钮文本更新为对应档位(自动模式下始终显示“清晰度:自动”)。 - 切换失败:
setVideoTrackOverride返回false时 demo 弹 Toast“清晰度切换失败”;clearVideoTrackOverride同理按返回值判断。 - 播放失败:
onPlayError回调触发时,demo 在轨道信息区显示“播放失败:”加 URL,可据此确认是源不可达还是其它错误。
边界与限制
- 固定清晰度是固定到单个 video track(
TrackSelectionOverride),只有清除 override 后才恢复自适应,二者互斥。 - override 坐标只对当前
Tracks有效;重新setUp或换源后旧的groupIndex/trackIndex不再可信,demo 在每次换源时重置 override 状态并重新读取。 - 服务端只有多个独立 URL、没有 master playlist / MPD 时,本方案不适用,应改用
无缝切换(SmartPickVideo)的多 URL 方案。 - 本文的轨道 API 是 Exo/Media3 内核下的能力,demo 中通过
GSYExoVideoManager访问;其它内核(IJK、System)没有对应的多码率自适应轨道管理。
【免费下载链接】GSYVideoPlayerVideo players (IJKplayer, ExoPlayer, MediaPlayer), HTTPS, 16k page size, danmaku (bullet chat) support, external subtitles, support for filters, watermarks, and GIF screenshots, pre-roll and mid-roll ads, multiple simultaneous playback, basic seeking/dragging, volume and brightness adjustment, play-while-cache support项目地址: https://gitcode.com/GitHub_Trending/gs/GSYVideoPlayer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考