/**
   * Called after media player has been prepared. This method is executed on the caller's thread.
   */
  void onPrepared(final boolean startWhenPrepared) {
    playerLock.lock();

    if (playerStatus != PlayerStatus.PREPARING) {
      playerLock.unlock();
      throw new IllegalStateException("Player is not in PREPARING state");
    }

    if (BuildConfig.DEBUG) Log.d(TAG, "Resource prepared");

    if (mediaType == MediaType.VIDEO) {
      VideoPlayer vp = (VideoPlayer) mediaPlayer;
      videoSize = new Pair<Integer, Integer>(vp.getVideoWidth(), vp.getVideoHeight());
    }

    if (media.getPosition() > 0) {
      mediaPlayer.seekTo(media.getPosition());
    }

    if (media.getDuration() == 0) {
      if (BuildConfig.DEBUG) Log.d(TAG, "Setting duration of media");
      media.setDuration(mediaPlayer.getDuration());
    }
    setPlayerStatus(PlayerStatus.PREPARED, media);

    if (startWhenPrepared) {
      resumeSync();
    }

    playerLock.unlock();
  }
 /**
  * Return width and height of the currently playing video as a pair.
  *
  * @return Width and height as a Pair or null if the video size could not be determined. The
  *     method might still return an invalid non-null value if the getVideoWidth() and
  *     getVideoHeight() methods of the media player return invalid values.
  */
 public Pair<Integer, Integer> getVideoSize() {
   if (!playerLock.tryLock()) {
     // use cached value if lock can't be aquired
     return videoSize;
   }
   Pair<Integer, Integer> res;
   if (mediaPlayer == null || playerStatus == PlayerStatus.ERROR || mediaType != MediaType.VIDEO) {
     res = null;
   } else {
     VideoPlayer vp = (VideoPlayer) mediaPlayer;
     videoSize = new Pair<Integer, Integer>(vp.getVideoWidth(), vp.getVideoHeight());
     res = videoSize;
   }
   playerLock.unlock();
   return res;
 }