syncStreamsWithSequenceNumber_(streamInfos, force = false) {
    // We assume that, when this is first called, we have enough info to
    // determine how to use the program date times (e.g. we have both a video
    // and an audio, and all other videos and audios match those).
    // Thus, we only need to calculate this once.
    const updateMinSequenceNumber = this.minSequenceNumber_ == -1;
    // Sync using media sequence number.  Find the highest starting sequence
    // number among all streams.  Later, we will drop any references to
    // earlier segments in other streams, then offset everything back to 0.
    for (const streamInfo of streamInfos) {
      const segmentIndex = streamInfo.stream.segmentIndex;
      goog.asserts.assert(segmentIndex,
          'Only loaded streams should be synced');
      const mediaSequenceToStartTime =
          this.getMediaSequenceToStartTimeFor_(streamInfo);
      const segment0 = segmentIndex.earliestReference();
      if (segment0) {
        // This looks inefficient, but iteration order is insertion order.
        // So the very first entry should be the one we want.
        // We assert that this holds true so that we are alerted by debug
        // builds and tests if it changes.  We still do a loop, though, so
        // that the code functions correctly in production no matter what.
        if (goog.DEBUG) {
          const firstSequenceStartTime =
              mediaSequenceToStartTime.values().next().value;
          if (firstSequenceStartTime != segment0.startTime) {
            shaka.log.warning(
                'Sequence number map is not ordered as expected!');
          }
        }
        for (const [sequence, start] of mediaSequenceToStartTime) {
          if (start == segment0.startTime) {
            if (updateMinSequenceNumber) {
              this.minSequenceNumber_ = Math.max(
                  this.minSequenceNumber_, sequence);
            }
            // Even if we already have decided on a value for
            // |this.minSequenceNumber_|, we still need to determine the first
            // sequence number for the stream, to offset it in the code below.
            streamInfo.firstSequenceNumber = sequence;
            break;
          }
        }
      }
    }

    if (this.minSequenceNumber_ < 0) {
      // Nothing to sync.
      return;
    }

    shaka.log.debug('Syncing HLS streams against base sequence number:',
        this.minSequenceNumber_);

    for (const streamInfo of streamInfos) {
      if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type) && !force) {
        continue;
      }
      const segmentIndex = streamInfo.stream.segmentIndex;
      if (segmentIndex) {
        // Drop any earlier references.
        const numSegmentsToDrop =
            this.minSequenceNumber_ - streamInfo.firstSequenceNumber;
        if (numSegmentsToDrop > 0) {
          segmentIndex.dropFirstReferences(numSegmentsToDrop);

          // Now adjust timestamps back to begin at 0.
          const segmentN = segmentIndex.earliestReference();
          if (segmentN) {
            const streamOffset = -segmentN.startTime;
            // Modify all SegmentReferences equally.
            streamInfo.stream.segmentIndex.offset(streamOffset);
            // Update other parts of streamInfo the same way.
            this.offsetStreamInfo_(streamInfo, streamOffset);
          }
        }
      }
    }
  }
Align the streams by sequence number by dropping early segments.  Then
offset the streams to begin at presentation time 0.
@param {!Array<!shaka.hls.HlsParser.StreamInfo>} streamInfos
@param {boolean=} force
@private