Using the Vitamio media player, I do not see a constant for when the video actually starts rendering (as there has been for the normal android MediaPlayer since api 17). onPreparedListeners do not detect when the rendering physically starts, and, as a result, the black screen prior to the video starting is seemingly unavoidable.
Is there any way to detect when the video has actually started rendering in Vitamio?
Though it's a bit of a hack, I found that this way works wonders:
VideoView.
MediaPlayer.MEDIA_INFO_BUFFERING_END
yourVideoView.getCurrentPosition() != 0.
Note that 0 may be too low -- sometimes getCurrentPosition
will return a number higher than zero before it has started, but typically the returned value will be no higher than 1000 / (the fps of your video). I used 40.In an OnCompletionListener, set the created boolean back to false.
public class AnimationCanvas extends 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);
}
});
}
EDIT: Note that another option is to create a separate Runnable which does the waiting (while(vv.getCurrentPosition() < 40){}
) and then, in the same Runnable, call runOnUIThread() to run a second runnable which alters / removes / adds views if needed (Views can only be touched by the thread in which they were created.) This way, there is no need for an onInfoListener -- just start the first Runnable in an onPreparedListener.