async setStreamProperties(
      contentType, timestampOffset, appendWindowStart, appendWindowEnd,
      ignoreTimestampOffset, mimeType, codecs, streamsByType) {
    const ContentType = shaka.util.ManifestParserUtils.ContentType;
    if (contentType == ContentType.TEXT) {
      if (!ignoreTimestampOffset) {
        this.textEngine_.setTimestampOffset(timestampOffset);
      }
      this.textEngine_.setAppendWindow(appendWindowStart, appendWindowEnd);
      return;
    }
    const operations = [];

    const hasChangedCodecs = await this.codecSwitchIfNecessary_(
        contentType, mimeType, codecs, streamsByType);

    if (!hasChangedCodecs) {
      // Queue an abort() to help MSE splice together overlapping segments.
      // We set appendWindowEnd when we change periods in DASH content, and the
      // period transition may result in overlap.
      //
      // An abort() also helps with MPEG2-TS.  When we append a TS segment, we
      // always enter a PARSING_MEDIA_SEGMENT state and we can't change the
      // timestamp offset.  By calling abort(), we reset the state so we can
      // set it.
      operations.push(this.enqueueOperation_(
          contentType,
          () => this.abort_(contentType),
          null));
      if (this.needSplitMuxedContent_) {
        operations.push(this.enqueueOperation_(
            ContentType.AUDIO,
            () => this.abort_(ContentType.AUDIO),
            null));
      }
    }
    if (!ignoreTimestampOffset) {
      operations.push(this.enqueueOperation_(
          contentType,
          () => this.setTimestampOffset_(contentType, timestampOffset),
          null));
      if (this.needSplitMuxedContent_) {
        operations.push(this.enqueueOperation_(
            ContentType.AUDIO,
            () => this.setTimestampOffset_(
                ContentType.AUDIO, timestampOffset),
            null));
      }
    }
    if (appendWindowStart != 0 || appendWindowEnd != Infinity) {
      operations.push(this.enqueueOperation_(
          contentType,
          () => this.setAppendWindow_(
              contentType, appendWindowStart, appendWindowEnd),
          null));
      if (this.needSplitMuxedContent_) {
        operations.push(this.enqueueOperation_(
            ContentType.AUDIO,
            () => this.setAppendWindow_(
                ContentType.AUDIO, appendWindowStart, appendWindowEnd),
            null));
      }
    }

    if (operations.length) {
      await Promise.all(operations);
    }
  }
Sets the timestamp offset and append window end for the given content type.

@param {shaka.util.ManifestParserUtils.ContentType} contentType
@param {number} timestampOffset The timestamp offset.  Segments which start
  at time t will be inserted at time t + timestampOffset instead.  This
  value does not affect segments which have already been inserted.
@param {number} appendWindowStart The timestamp to set the append window
  start to.  For future appends, frames/samples with timestamps less than
  this value will be dropped.
@param {number} appendWindowEnd The timestamp to set the append window end
  to.  For future appends, frames/samples with timestamps greater than this
  value will be dropped.
@param {boolean} ignoreTimestampOffset  If true, the timestampOffset will
  not be applied in this step.
@param {string} mimeType
@param {string} codecs
@param {!Map<shaka.util.ManifestParserUtils.ContentType,
              shaka.extern.Stream>} streamsByType
  A map of content types to streams.

@return {!Promise}