Vitamio 相当于 MEDIA_INFO_VIDEO_RENDERING_START

Vitamio equivalent of MEDIA_INFO_VIDEO_RENDERING_START

使用 Vitamio 媒体播放器时,我没有看到视频实际开始渲染的时间常量(因为自 api 17 以来正常的 android MediaPlayer 一直存在)。 onPreparedListeners 不会检测渲染的物理开始时间,因此,视频开始前的黑屏似乎是不可避免的。

有什么方法可以检测视频何时真正开始在 Vitamio 中渲染?

虽然有点hack,但我发现这种方式很有效:

  • 创建一个布尔值,默认为false,判断是否第一次缓冲完成。
  • 在你的 Vitamio 上设置一个 onInfoListener VideoView.
  • 寻找MediaPlayer.MEDIA_INFO_BUFFERING_END
  • 如果您创建的布尔值是 false,则将其设置为 true 并等待,使用 while 循环,直到 yourVideoView.getCurrentPosition() != 0. 注意 0 可能太低——有时 getCurrentPosition 会 return 开始前大于零的数字,但通常 returned 值不会高于 1000 /(视频的 fps)。我用了40.
  • 执行所需代码(删除其他视图以使 VideoView 可见,或将 VideoView 添加到布局中)。
  • 在 OnCompletionListener 中,将创建的布尔值设置回 false。

    public class AnimationCanvas 扩展 VideoView{

    public static AnimationCanvas animationCanvas;
    private static boolean bufferedOnce = false;
    public AnimationCanvas(Context context, AttributeSet attrs){
        super(context, attrs);
        animationCanvas = this;
        getHolder().addCallback(this);
        this.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                if (!bufferedOnce && what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
                    bufferedOnce = true;
                    while (getCurrentPosition() < 40) {
                        try {
                            Thread.sleep(2);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    MainActivity.frameLayout.removeView(MainCanvas.mainCanvas);
                    return true;
                }
                return false;
            }
        });
        this.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                bufferedOnce = false;
                MainActivity.frameLayout.addView(MainCanvas.mainCanvas);
                MainActivity.frameLayout.removeView(animationCanvas);
            }
        });
    }
    

编辑: 请注意,另一种选择是创建一个单独的 Runnable 来等待(while(vv.getCurrentPosition() < 40){}),然后在同一个 Runnable 中调用 运行OnUIThread() 到 运行 第二个 运行nable,如果需要,它可以更改/删除/添加视图(视图只能由创建它们的线程触及。)这样,就没有需要 onInfoListener——只需在 onPreparedListener 中启动第一个 Runnable。