ExoPlayer是否提供区分滑动窗口与完整直播播放列表的方法?
区分HLS滑动窗口与持续增长播放列表(ExoPlayer 2.6.1)
你遇到的这个问题确实很常见——ExoPlayer 2.6.1本身没有直接暴露区分这两种HLS直播播放列表的API,但我们可以通过监听播放列表的解析事件,拿到ExoPlayer解析后的原始播放列表元数据来判断。
为什么Timeline区分不了?
Timeline是ExoPlayer抽象出来的播放时间线模型,不管是滑动窗口还是持续增长的直播流,在Timeline上都会表现为“无限时长的直播序列”,所以无法直接通过它判断播放列表类型,必须从HLS的原始元数据入手。
核心判断逻辑
HLS协议里,滑动窗口类型的直播会携带#EXT-X-WINDOW-SIZE标签,用来指定保留的最大片段数;而持续增长的完整直播列表不会有这个标签。ExoPlayer会把这个标签解析为HlsLivePlaylist.windowSize属性:
- 滑动窗口类型:
windowSize是具体的数字(比如10代表保留最近10个片段) - 持续增长类型:
windowSize默认是Integer.MAX_VALUE
具体实现代码
创建HlsMediaSource时,设置播放列表解析监听器,在回调里做类型判断:
// 初始化数据源工厂(替换成你自己的UA和上下文) DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory( context, Util.getUserAgent(context, "YourAppName") ); // 创建HLS媒体源并绑定监听器 HlsMediaSource hlsMediaSource = new HlsMediaSource( Uri.parse("你的HLS直播地址"), dataSourceFactory, new Handler(Looper.getMainLooper()), new HlsMediaSource.EventListener() { @Override public void onPlaylistParsed(HlsPlaylist playlist) { // 先判断是否为直播播放列表 if (playlist instanceof HlsLivePlaylist) { HlsLivePlaylist livePlaylist = (HlsLivePlaylist) playlist; // 通过windowSize判断播放列表类型 boolean isSlidingWindow = livePlaylist.windowSize != Integer.MAX_VALUE; if (isSlidingWindow) { // 展示滑动窗口对应的播放器控件 showSlidingWindowControls(); } else { // 展示持续增长类型对应的控件 showContinuousPlaylistControls(); } } else if (playlist instanceof HlsMasterPlaylist) { // 如果是多码率主播放列表,需要等待具体变体的播放列表解析 // 监听器会在每个变体播放列表加载时再次触发onPlaylistParsed HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist; // 可根据业务需求处理多码率场景 } } @Override public void onPlaylistLoadError(IOException error) { // 处理播放列表加载失败逻辑 Log.e("HLS Playlist", "Load failed", error); } } ); // 将媒体源设置给ExoPlayer player.prepare(hlsMediaSource);
额外注意点
如果你的HLS流是多码率主播放列表(.m3u8包含多个变体地址),主列表本身不会携带窗口大小信息,需要等待具体变体的播放列表被解析后,监听器会再次触发onPlaylistParsed,此时再做类型判断即可。
内容的提问来源于stack exchange,提问作者anthonylawson
相关产品推荐
相关产品推荐

