constructor(video, textDisplayer, playerInterface, config, lcevcDec) {
    /** @private {HTMLMediaElement} */
    this.video_ = video;

    /** @private {?shaka.media.MediaSourceEngine.PlayerInterface} */
    this.playerInterface_ = playerInterface;

    /** @private {?shaka.extern.MediaSourceConfiguration} */
    this.config_ = config;

    /** @private {shaka.extern.TextDisplayer} */
    this.textDisplayer_ = textDisplayer;

    /**
     * @private {!Map<shaka.util.ManifestParserUtils.ContentType, SourceBuffer>}
     */
    this.sourceBuffers_ = new Map();

    /**
     * @private {!Map<shaka.util.ManifestParserUtils.ContentType, string>}
     */
    this.sourceBufferTypes_ = new Map();


    /**
     * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
     *                    boolean>}
     */
    this.expectedEncryption_ = new Map();

    /** @private {shaka.text.TextEngine} */
    this.textEngine_ = null;

    /** @private {boolean} */
    this.segmentRelativeVttTiming_ = false;

    /** @private {?shaka.lcevc.Dec} */
    this.lcevcDec_ = lcevcDec || null;

    /**
     * @private {!Map<string, !Array<shaka.media.MediaSourceEngine.Operation>>}
     */
    this.queues_ = new Map();

    /** @private {shaka.util.EventManager} */
    this.eventManager_ = new shaka.util.EventManager();

    /**
     * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
                         !shaka.extern.Transmuxer>} */
    this.transmuxers_ = new Map();

    /** @private {?shaka.media.IClosedCaptionParser} */
    this.captionParser_ = null;

    /** @private {!shaka.util.PublicPromise} */
    this.mediaSourceOpen_ = new shaka.util.PublicPromise();

    /** @private {string} */
    this.url_ = '';

    /** @private {boolean} */
    this.playbackHasBegun_ = false;

    /** @private {boolean} */
    this.streamingAllowed_ = true;

    /** @private {boolean} */
    this.usingRemotePlayback_ = false;

    /** @private {HTMLSourceElement} */
    this.source_ = null;

    /**
     * Fallback source element with direct media URI, used for casting
     * purposes.
     * @private {HTMLSourceElement}
     */
    this.secondarySource_ = null;

    /** @private {MediaSource} */
    this.mediaSource_ = this.createMediaSource(this.mediaSourceOpen_);

    /** @private {boolean} */
    this.reloadingMediaSource_ = false;

    /** @private {boolean} */
    this.playAfterReset_ = false;

    /** @type {!shaka.util.Destroyer} */
    this.destroyer_ = new shaka.util.Destroyer(() => this.doDestroy_());

    /** @private {boolean} */
    this.sequenceMode_ = false;

    /** @private {string} */
    this.manifestType_ = shaka.media.ManifestParser.UNKNOWN;

    /** @private {boolean} */
    this.ignoreManifestTimestampsInSegmentsMode_ = false;

    /** @private {boolean} */
    this.attemptTimestampOffsetCalculation_ = false;

    /** @private {!shaka.util.PublicPromise<number>} */
    this.textSequenceModeOffset_ = new shaka.util.PublicPromise();

    /** @private {boolean} */
    this.needSplitMuxedContent_ = false;

    /** @private {?number} */
    this.lastDuration_ = null;

    /**
     * @private {!Map<shaka.util.ManifestParserUtils.ContentType,
     *                    !shaka.util.TsParser>}
     */
    this.tsParsers_ = new Map();

    /** @private {?number} */
    this.firstVideoTimestamp_ = null;

    /** @private {?number} */
    this.firstVideoReferenceStartTime_ = null;

    /** @private {?number} */
    this.firstAudioTimestamp_ = null;

    /** @private {?number} */
    this.firstAudioReferenceStartTime_ = null;

    /** @private {!shaka.util.PublicPromise<number>} */
    this.audioCompensation_ = new shaka.util.PublicPromise();

    if (this.video_.remote) {
      this.usingRemotePlayback_ = this.video_.remote.state != 'disconnected';

      this.eventManager_.listen(this.video_.remote, 'connect', () => {
        this.usingRemotePlayback_ = this.video_.remote.state != 'disconnected';
      });

      this.eventManager_.listen(this.video_.remote, 'connecting', () => {
        this.usingRemotePlayback_ = this.video_.remote.state != 'disconnected';
      });

      this.eventManager_.listen(this.video_.remote, 'disconnect', () => {
        this.usingRemotePlayback_ = this.video_.remote.state != 'disconnected';
      });
    }
  }
@param {HTMLMediaElement} video The video element, whose source is tied to
  MediaSource during the lifetime of the MediaSourceEngine.
@param {!shaka.extern.TextDisplayer} textDisplayer
   The text displayer that will be used with the text engine.
   MediaSourceEngine takes ownership of the displayer. When
   MediaSourceEngine is destroyed, it will destroy the displayer.
@param {!shaka.media.MediaSourceEngine.PlayerInterface} playerInterface
  Interface for common player methods.
@param {shaka.extern.MediaSourceConfiguration} config
@param {?shaka.lcevc.Dec} [lcevcDec] Optional -  LCEVC Decoder Object