onResumeLocal_() {
    // Transfer back the player state.
    for (const pair of shaka.cast.CastUtils.PlayerInitState) {
      const getter = pair[0];
      const setter = pair[1];
      const value = this.sender_.get('player', getter)();
      /** @type {Object} */(this.localPlayer_)[setter](value);
    }

    const addThumbnailsTrackCalls = this.addThumbnailsTrackCalls_;
    const addTextTrackAsyncCalls = this.addTextTrackAsyncCalls_;
    const addChaptersTrackCalls = this.addChaptersTrackCalls_;

    this.resetExternalTracks();

    // Get the most recent manifest URI and ended state.
    const assetUri = this.sender_.get('player', 'getAssetUri')();
    const ended = this.sender_.get('video', 'ended');

    let manifestReady = Promise.resolve();
    const autoplay = this.localVideo_.autoplay;

    let startTime = null;

    // If the video is still playing, set the startTime.
    // Has no effect if nothing is loaded.
    if (!ended) {
      startTime = this.sender_.get('video', 'currentTime');
    }

    let activeTextTrack;
    const textTracks = this.sender_.get('player', 'getTextTracks')();

    if (textTracks && textTracks.length) {
      activeTextTrack = textTracks.find((t) => t.active);
    }

    const isTextTrackVisible =
        this.sender_.get('player', 'isTextTrackVisible')();

    // Now load the manifest, if present.
    if (assetUri) {
      // Don't autoplay the content until we finish setting up initial state.
      this.localVideo_.autoplay = false;
      manifestReady = this.localPlayer_.load(assetUri, startTime);
    }

    // Get the video state into a temp variable since we will apply it async.
    const videoState = {};
    for (const name of shaka.cast.CastUtils.VideoInitStateAttributes) {
      videoState[name] = this.sender_.get('video', name);
    }

    // Finally, take on video state and player's "after load" state.
    manifestReady.then(() => {
      if (!this.localVideo_) {
        // We've already been destroyed.
        return;
      }

      for (const args of addThumbnailsTrackCalls) {
        this.getPlayer().addThumbnailsTrack(...args);
      }
      for (const args of addTextTrackAsyncCalls) {
        this.getPlayer().addTextTrackAsync(...args);
      }
      for (const args of addChaptersTrackCalls) {
        this.getPlayer().addChaptersTrack(...args);
      }

      for (const name of shaka.cast.CastUtils.VideoInitStateAttributes) {
        this.localVideo_[name] = videoState[name];
      }

      for (const pair of shaka.cast.CastUtils.PlayerInitAfterLoadState) {
        const getter = pair[0];
        const setter = pair[1];
        const value = this.sender_.get('player', getter)();
        /** @type {Object} */(this.localPlayer_)[setter](value);
      }

      this.localPlayer_.setTextTrackVisibility(isTextTrackVisible);
      if (activeTextTrack) {
        this.localPlayer_.selectTextLanguage(
            activeTextTrack.language,
            activeTextTrack.roles,
            activeTextTrack.forced);
      }

      // Restore the original autoplay setting.
      this.localVideo_.autoplay = autoplay;
      if (assetUri) {
        // Resume playback with transferred state.
        this.localVideo_.play();
      }
    }, (error) => {
      // Pass any errors through to the app.
      goog.asserts.assert(error instanceof shaka.util.Error,
          'Wrong error type!');
      const eventType = shaka.util.FakeEvent.EventName.Error;
      const data = (new Map()).set('detail', error);
      const event = new shaka.util.FakeEvent(eventType, data);
      this.localPlayer_.dispatchEvent(event);
    });
  }
Transfer remote state back and resume local playback.
@private