exoplayer2:使用ConcatenatingMediaSource

时间:2018-02-15 16:13:10

标签: android exoplayer exoplayer2.x

在播放来自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的调用。

1 个答案:

答案 0 :(得分:0)

This is not supported yet

  

使用事件侦听器的问题是无法确保请求在事件侦听器中暂停   在显示新播放列表项目的第一帧时处理。

     

如果在大约正确的框架停车是好的,你的解决方案   暂停玩家的位置不连续看起来很好,但我认为   我们无法保证视频渲染器能够跟上   玩家的位置,这就是为什么你仍然看到一个框架的原因   暂停播放器的前一个来源。对于它的原因   值得一提的是,在我的测试中,视频渲染器确实进入了第一帧   处理暂停请求之前的下一个播放列表项目。

     

其他一些建议:

     
      
  • 您可以尝试自定义MediaSource,以便在每个期间的开头插入一个位置不连续。我想你会得到   每个项目开头的onRenderedFirstFrame。如果你暂停   在那里玩家,你可以保证将玩家暂停在一个框架中   新的播放列表项目。
  •   
  • 为了让它完美运行,从某种意义上说,新播放列表项目的第一帧显示,播放器在任何播放列表之前暂停   如果显示其他框架,则需要协调显示a   框架和阻止进一步渲染(在回放线程上)   暂停播放器(在您的应用用于与之交互的线程上)   付款人)。这需要一些代码,但我认为是   可能大概如下:子类MediaCodecVideoRenderer   并覆盖onStreamChanged以获取新的时间偏移量   播放列表项目。然后覆盖processOutputBuffer。在这种方法中你   可以检测何时渲染新流的第一帧   (基于时间偏移)然后阻止处理任何输出   框架,直到您在应用程序的主题中暂停了播放器。之后   已处理暂停请求并停止渲染器   (onStopped)你可以解锁processOutputBuffer。
  •   
     

我们也可以直接在播放器中看到支持它,但它   至少暂时可能是低优先级。