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。
使用 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。