playerProxyGet_(name, dontRecordCalls = false) {
    // If name is a shortened compiled name, get the original version
    // from our map.
    if (this.compiledToExternNames_.has(name)) {
      name = this.compiledToExternNames_.get(name);
    }

    if (name == 'addEventListener') {
      return (type, listener, options) => {
        return this.playerEventTarget_.addEventListener(
            type, listener, options);
      };
    }
    if (name == 'removeEventListener') {
      return (type, listener, options) => {
        return this.playerEventTarget_.removeEventListener(
            type, listener, options);
      };
    }

    if (name == 'getMediaElement') {
      return () => this.videoProxy_;
    }

    if (name == 'getSharedConfiguration') {
      shaka.log.warning(
          'Can\'t share configuration across a network. Returning copy.');
      return this.sender_.get('player', 'getConfiguration');
    }

    if (name == 'getNetworkingEngine') {
      // Always returns a local instance, in case you need to make a request.
      // Issues a warning, in case you think you are making a remote request
      // or affecting remote filters.
      if (this.sender_.isCasting()) {
        shaka.log.warning('NOTE: getNetworkingEngine() is always local!');
      }
      return () => this.localPlayer_.getNetworkingEngine();
    }

    if (name == 'getDrmEngine') {
      // Always returns a local instance.
      if (this.sender_.isCasting()) {
        shaka.log.warning('NOTE: getDrmEngine() is always local!');
      }
      return () => this.localPlayer_.getDrmEngine();
    }

    if (name == 'getAdManager') {
      // Always returns a local instance.
      if (this.sender_.isCasting()) {
        shaka.log.warning('NOTE: getAdManager() is always local!');
      }
      return () => this.localPlayer_.getAdManager();
    }

    if (name == 'getQueueManager') {
      // Always returns a local instance.
      return () => this.localPlayer_.getQueueManager();
    }

    if (name == 'setVideoContainer') {
      // Always returns a local instance.
      if (this.sender_.isCasting()) {
        shaka.log.warning('NOTE: setVideoContainer() is always local!');
      }
      return (container) => this.localPlayer_.setVideoContainer(container);
    }

    if (!dontRecordCalls) {
      if (name == 'addThumbnailsTrack') {
        return (...args) => {
          this.addThumbnailsTrackCalls_.push(args);
          return this.playerProxyGet_(
              name, /* dontRecordCalls= */ true)(...args);
        };
      }
      if (name == 'addTextTrackAsync') {
        return (...args) => {
          this.addTextTrackAsyncCalls_.push(args);
          return this.playerProxyGet_(
              name, /* dontRecordCalls= */ true)(...args);
        };
      }
      if (name == 'addChaptersTrack') {
        return (...args) => {
          this.addChaptersTrackCalls_.push(args);
          return this.playerProxyGet_(
              name, /* dontRecordCalls= */ true)(...args);
        };
      }
    }

    if (this.sender_.isCasting()) {
      // These methods are unavailable or otherwise stubbed during casting.
      if (name == 'getManifest' || name == 'drmInfo') {
        return () => {
          shaka.log.alwaysWarn(name + '() does not work while casting!');
          return null;
        };
      }

      if (name == 'attach' || name == 'detach') {
        return () => {
          shaka.log.alwaysWarn(name + '() does not work while casting!');
          return Promise.resolve();
        };
      }

      if (name == 'getChapters') {
        // This does not follow our standard pattern (takes an arguments), and
        // therefore can't be proactively proxied and cached the way other
        // synchronous getters can.
        return () => {
          shaka.log.alwaysWarn(name + '() does not work while casting!');
          return [];
        };
      }
    }  // if (this.sender_.isCasting())

    // If we are casting, but the first update has not come in yet, use local
    // getters, but not local methods.
    if (this.sender_.isCasting() && !this.sender_.hasRemoteProperties()) {
      if (shaka.cast.CastUtils.PlayerGetterMethods.has(name) ||
          shaka.cast.CastUtils.LargePlayerGetterMethods.has(name)) {
        const value = /** @type {Object} */(this.localPlayer_)[name];
        goog.asserts.assert(typeof value == 'function',
            'only methods on Player');
        // eslint-disable-next-line no-restricted-syntax
        return value.bind(this.localPlayer_);
      }
    }

    // Use local getters and methods if we are not casting.
    if (!this.sender_.isCasting()) {
      const value = /** @type {Object} */(this.localPlayer_)[name];
      goog.asserts.assert(typeof value == 'function',
          'only methods on Player');
      // eslint-disable-next-line no-restricted-syntax
      return value.bind(this.localPlayer_);
    }

    return this.sender_.get('player', name);
  }
@param {string} name
@param {boolean} dontRecordCalls
@return {?}
@private