You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:58:15