首页 文章

exoplayer2:在开始时使用ConcatenatingMediaSource暂停视频

提问于
浏览
0

在播放 ConcatenatingMediaSource 播放列表中的视频时,我希望播放器在新项目开始时自动暂停,例如 . 不会自动播放 .

使用演示应用程序,我修改了 onPositionDiscontinuity 函数来检测当前项目更改:

int currentPosition = 0;
@Override
public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
    if (inErrorState) {
        // This will only occur if the user has performed a seek whilst in the error state. Update
        // the resume position so that if the user then retries, playback will resume from the
        // position to which they seeked.
        updateResumePosition();
    }
    if (player.getCurrentWindowIndex() != currentPosition) {
        currentPosition = player.getCurrentWindowIndex();
        player.setPlayWhenReady(false);
    }
}

虽然此代码暂停播放器,但它不会清除播放器使用的表面视图,因此我们仍然可以看到上一个视频的最后一帧 . 我想这个回调过早被调用,但这是我发现的唯一回调,总是在播放列表项目更改时调用(可能不会调用 onPlayerStateChanged ) .

How can I have the first frame of the newly current item displayed instead of the previous item last frame?

我的弱解决方法是使用 Handler().postDelayed({ mPlayer?.playWhenReady = false }, 200) 延迟200ms的调用 .

1 回答

  • 0

    This is not supported yet

    使用事件侦听器的问题在于,无法确保在显示新播放列表项的第一帧时处理事件侦听器中的暂停请求 . 如果在大约右边框架停止是正常的,那么暂停玩家对位置不连续性的解决方案看起来很好,但我认为无法保证视频渲染器能够跟上玩家位置,这就是为什么你仍然可以看到来自暂停播放器的前一个来源 . 值得一提的是,在我的测试中,视频渲染器在处理暂停请求之前确实前进到下一个播放列表项的第一帧 . 其他一些建议:您可以尝试自定义MediaSource以在每个时段开始时插入一个位置不连续 . 我想你会在每个项目的开头获得onRenderedFirstFrame . 如果您暂停播放器,则可以保证将播放器暂停在新播放列表项目的框架中 . 为了使其完美地工作,在显示新播放列表项的第一帧并且播放器在显示任何其他帧之前暂停的意义上,将需要协调显示帧并阻止进一步渲染(在回放线程上) )暂停播放器(在你的应用程序用来与付款人互动的线程上) . 这将需要一些代码,但我认为可能大致如下:子类MediaCodecVideoRenderer并覆盖onStreamChanged以获取新播放列表项的时间偏移量 . 然后覆盖processOutputBuffer . 在此方法中,您可以检测新流的第一帧何时被渲染(基于时间偏移),然后阻止处理任何输出帧,直到您在应用程序的线程上暂停播放器为止 . 处理暂停请求并停止渲染器(onStopped)后,您可以取消阻止processOutputBuffer . 我们也可以直接在播放器中看到支持它,但至少在目前它可能是一个低优先级 .

相关问题