如何在ExoPlayer中设置直播播放起止时间及DefaultTimeBar配置
解决方案:为DefaultTimeBar设置固定直播节目的起止时间
可以实现,下面针对你的问题给出具体修正方案和实现步骤:
问题分析
你之前的尝试存在两个核心问题:
- 调用
exoPlayerProgress.setDuration(60_000)仅设置了60秒的时长,与节目2小时的实际时长不匹配,无法生效。 LiveConfiguration中使用System.currentTimeMillis()作为偏移基准错误,系统时间与节目UTC时间存在差异,且无法对应固定的节目起止范围。
结合你提供的m3u8清单(带有EXT-X-PROGRAM-DATE-TIME时间戳),可以通过以下两种方式实现需求:
方法一:自定义Timeline指定节目范围
通过创建自定义Timeline,强制ExoPlayer使用节目固定的起止时间来更新DefaultTimeBar:
步骤1:计算节目起止时间戳(UTC时区)
假设节目日期与m3u8中的时间一致(2023-08-17),先转换为UTC时间戳:
// 节目开始时间:2023-08-17 08:00:00 UTC long startTimeUtcMs = 1692264000000L; // 节目结束时间:2023-08-17 10:00:00 UTC long endTimeUtcMs = 1692271200000L; long programTotalDurationMs = endTimeUtcMs - startTimeUtcMs;
步骤2:创建并设置自定义Timeline
// 创建自定义单周期Timeline,指定节目起止和时长 Timeline customProgramTimeline = new SinglePeriodTimeline( programTotalDurationMs, startTimeUtcMs, endTimeUtcMs, true, // 标记为直播类型 false // 非动态更新 ); // 先添加自定义Timeline的Fake媒体源 exoPlayer.setMediaSource(new FakeMediaSource(customProgramTimeline)); // 再添加真实的m3u8媒体源 MediaItem mediaItem = new MediaItem.Builder() .setUri(mUrl) .setMimeType(MimeTypes.APPLICATION_M3U8) // 移除之前错误的LiveConfiguration配置 .build(); exoPlayer.addMediaSource(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem)); exoPlayer.prepare();
注:FakeMediaSource是一个自定义的空媒体源,仅用于提供我们的自定义Timeline,示例实现如下:
public class FakeMediaSource extends BaseMediaSource { private final Timeline timeline; public FakeMediaSource(Timeline timeline) { this.timeline = timeline; } @Override protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { notifySourceInfoRefreshed(timeline, null); } @Override protected void enableInternal() {} @Override protected void disableInternal() {} @Override public void releaseSourceInternal() {} }
方法二:监听Player状态,手动更新DefaultTimeBar
通过监听ExoPlayer的Timeline变化,手动计算播放进度并更新DefaultTimeBar的显示范围:
步骤1:计算节目起止时间戳(同方法一)
long startTimeUtcMs = 1692264000000L; long endTimeUtcMs = 1692271200000L; long programTotalDurationMs = endTimeUtcMs - startTimeUtcMs;
步骤2:设置Player监听器,实时更新TimeBar
exoPlayer.addListener(new Player.Listener() { @Override public void onTimelineChanged(Timeline timeline, int reason) { super.onTimelineChanged(timeline, reason); // 强制设置TimeBar的范围为节目总时长 exoPlayerProgress.setMin(0); exoPlayerProgress.setMax((int) programTotalDurationMs); } @Override public void onPositionDiscontinuity(@NonNull PositionInfo oldPosition, @NonNull PositionInfo newPosition, int reason) { super.onPositionDiscontinuity(oldPosition, newPosition, reason); updateTimeBarProgress(); } @Override public void onPlaybackStateChanged(int playbackState) { super.onPlaybackStateChanged(playbackState); if (playbackState == Player.STATE_READY) { updateTimeBarProgress(); } } private void updateTimeBarProgress() { Timeline.Window window = new Timeline.Window(); exoPlayer.getCurrentTimeline().getWindow(0, window); // 获取当前播放片段的UTC起始时间,加上当前播放偏移得到实际播放时间戳 long currentPlaybackUtcMs = window.getPresentationStartTimeMs() + exoPlayer.getCurrentPosition(); // 计算相对于节目开始的进度 long currentProgressMs = currentPlaybackUtcMs - startTimeUtcMs; // 更新TimeBar进度 exoPlayerProgress.setProgress((int) currentProgressMs); } });
关键注意点
- 确保节目起止时间使用UTC时区,与m3u8中
EXT-X-PROGRAM-DATE-TIME的时区保持一致,避免时间偏移错误。 - 移除之前错误的
LiveConfiguration配置,因为它是针对无固定起止的实时直播设计的,不适用于固定时间段的节目。
内容的提问来源于stack exchange,提问作者Shih
相关产品推荐
相关产品推荐

