在播放来自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
可能不会被调用)。
如何显示新当前项目的第一帧而不是上一帧的上一项?
我的弱解决方法是使用Handler().postDelayed({ mPlayer?.playWhenReady = false }, 200)
延迟200ms的调用。
答案 0 :(得分:0)
使用事件侦听器的问题是无法确保请求在事件侦听器中暂停 在显示新播放列表项目的第一帧时处理。
如果在大约正确的框架停车是好的,你的解决方案 暂停玩家的位置不连续看起来很好,但我认为 我们无法保证视频渲染器能够跟上 玩家的位置,这就是为什么你仍然看到一个框架的原因 暂停播放器的前一个来源。对于它的原因 值得一提的是,在我的测试中,视频渲染器确实进入了第一帧 处理暂停请求之前的下一个播放列表项目。
其他一些建议:
- 您可以尝试自定义MediaSource,以便在每个期间的开头插入一个位置不连续。我想你会得到 每个项目开头的onRenderedFirstFrame。如果你暂停 在那里玩家,你可以保证将玩家暂停在一个框架中 新的播放列表项目。
- 为了让它完美运行,从某种意义上说,新播放列表项目的第一帧显示,播放器在任何播放列表之前暂停 如果显示其他框架,则需要协调显示a 框架和阻止进一步渲染(在回放线程上) 暂停播放器(在您的应用用于与之交互的线程上) 付款人)。这需要一些代码,但我认为是 可能大概如下:子类MediaCodecVideoRenderer 并覆盖onStreamChanged以获取新的时间偏移量 播放列表项目。然后覆盖processOutputBuffer。在这种方法中你 可以检测何时渲染新流的第一帧 (基于时间偏移)然后阻止处理任何输出 框架,直到您在应用程序的主题中暂停了播放器。之后 已处理暂停请求并停止渲染器 (onStopped)你可以解锁processOutputBuffer。
我们也可以直接在播放器中看到支持它,但它 至少暂时可能是低优先级。