Search code examples
androidandroid-mediaplayervitamio

Vitamio equivalent of MEDIA_INFO_VIDEO_RENDERING_START


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?


Solution

  • Though it's a bit of a hack, I found that this way works wonders:

    • Create a boolean, defaulted to false, which determines whether or not buffering has completed for the first time.
    • Set an onInfoListener on your Vitamio VideoView.
    • Look for MediaPlayer.MEDIA_INFO_BUFFERING_END
    • If the boolean you created is false, then set it to true and wait, with a while loop, until 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.
    • Execute desired code (remove other views to make the VideoView visible, or add the VideoView to the layout).
    • 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.