private void launchPlayer(long atTime) {
    Log.d("jdj-ExoPlayer", "Player LOADING at " + atTime);
    playerState = STATE_LOAD;

    if (mode != null && mode.equals("audio")) {
      audioShutter.setVisibility(View.VISIBLE);

      // seek to position to keep sync
      if (baganAtTime > 0 && atTime < SystemClock.elapsedRealtime()) {
        atTime = SystemClock.elapsedRealtime() + 1500; // already late so we postpone the start
        playerPosition = atTime - baganAtTime; // start at position shifted from baganAtTime
      }
    }

    if (player == null) {
      player = new ExPlayer(getRendererBuilder());
      player.addListener(this);
      player.seekTo(playerPosition);
      playerNeedsPrepare = true;
      if (exoLog) {
        eventLogger = new EventLogger();
        eventLogger.startSession();
        player.addListener(eventLogger);
        player.setInfoListener(eventLogger);
        player.setInternalErrorListener(eventLogger);
      }
    }
    if (playerNeedsPrepare) {
      player.prepare();
      playerNeedsPrepare = false;
    }
    player.setSurface(surfaceView.getHolder().getSurface());
    player.setPlayWhenReady(false);
    atTimeUse = atTime;

    // Sync with atTime
    new Handler()
        .postDelayed(
            new Runnable() {
              @Override
              public void run() {
                if (playerState == STATE_STOP) return;
                else if (playerState >= STATE_READY) {
                  Log.d("jdj-ExoPlayer", "Player PLAY - SYNC");
                  loadShutter.setVisibility(View.GONE);
                } else Log.d("jdj-ExoPlayer", "Player PLAY - OUT OF SYNC.. (not ready yet)");

                player.setPlayWhenReady(true);
                playerState = STATE_PLAY;
                Log.d(
                    "jdj-ExoPlayer",
                    " Timer shot shift: " + (SystemClock.elapsedRealtime() - atTimeUse));
              }
            },
            Math.max(0, atTime - SystemClock.elapsedRealtime()));
  }
 private void releasePlayer(boolean savePosition) {
   playerState = STATE_STOP;
   // Log.d("jdj-ExoPlayer", "Player STOP");
   playerPosition = 0;
   if (player != null) {
     if (savePosition) playerPosition = player.getCurrentPosition();
     player.release();
     player = null;
     if (exoLog) {
       eventLogger.endSession();
       eventLogger = null;
     }
   }
   if (!savePosition) {
     loadShutter.setVisibility(View.VISIBLE);
     audioShutter.setVisibility(View.GONE);
     baganAtTime = NOW;
   }
   if (replayEnable) replayShutter.setVisibility(View.GONE);
 }