static async generateSegmentIndexFromUris(
      context, requestSegment, initSegmentReference, uris, startByte,
      endByte, scaledPresentationTimeOffset) {
    // Unpack context right away, before we start an async process.
    // This immunizes us against changes to the context object later.
    /** @type {shaka.media.PresentationTimeline} */
    const presentationTimeline = context.presentationTimeline;
    const fitLast = !context.dynamic || !context.periodInfo.isLastPeriod;
    const periodStart = context.periodInfo.start;
    const periodDuration = context.periodInfo.duration;
    const containerType = context.representation.mimeType.split('/')[1];

    // Create a local variable to bind to so we can set to null to help the GC.
    let localRequest = requestSegment;
    let segmentIndex = null;

    const responses = [
      localRequest(uris, startByte, endByte, /* isInit= */ false),
      containerType == 'webm' ?
          localRequest(
              initSegmentReference.getUris(),
              initSegmentReference.startByte,
              initSegmentReference.endByte,
              /* isInit= */ true) :
          null,
    ];

    localRequest = null;
    const results = await Promise.all(responses);
    const indexData = results[0];
    const initData = results[1] || null;
    /** @type {Array<!shaka.media.SegmentReference>} */
    let references = null;

    const timestampOffset = periodStart - scaledPresentationTimeOffset;
    const appendWindowStart = periodStart;
    const appendWindowEnd = periodDuration ?
        periodStart + periodDuration : Infinity;

    if (containerType == 'mp4') {
      references = shaka.dash.Mp4SegmentIndexParser.parse(
          indexData, startByte, uris, initSegmentReference, timestampOffset,
          appendWindowStart, appendWindowEnd);
    } else {
      goog.asserts.assert(initData, 'WebM requires init data');
      references = shaka.dash.WebmSegmentIndexParser.parse(
          indexData, initData, uris, initSegmentReference, timestampOffset,
          appendWindowStart, appendWindowEnd);
    }
    for (const ref of references) {
      ref.codecs = context.representation.codecs;
      ref.mimeType = context.representation.mimeType;
      ref.bandwidth = context.bandwidth;
    }

    presentationTimeline.notifySegments(references);

    // Since containers are never updated, we don't need to store the
    // segmentIndex in the map.
    goog.asserts.assert(!segmentIndex,
        'Should not call generateSegmentIndex twice');

    segmentIndex = new shaka.media.SegmentIndex(references);
    if (fitLast) {
      segmentIndex.fit(appendWindowStart, appendWindowEnd, /* isNew= */ true);
    }
    return segmentIndex;
  }
Creates a SegmentIndex for the given URIs and context.

@param {shaka.dash.DashParser.Context} context
@param {shaka.dash.DashParser.RequestSegmentCallback} requestSegment
@param {shaka.media.InitSegmentReference} initSegmentReference
@param {!Array<string>} uris
@param {number} startByte
@param {?number} endByte
@param {number} scaledPresentationTimeOffset
@return {!Promise<shaka.media.SegmentIndex>}