async parseManifestInner_() {
    this.makeStateChangeEvent_('manifest-parser');

    if (!this.parser_) {
      // Create the parser that we will use to parse the manifest.
      this.parserFactory_ = shaka.media.ManifestParser.getFactory(
          this.assetUri_, this.mimeType_);
      goog.asserts.assert(this.parserFactory_, 'Must have manifest parser');
      this.parser_ = this.parserFactory_();

      this.parser_.configure(this.config_.manifest, () => this.isPreload_);
    }

    const startTime = Date.now() / 1000;

    this.makeStateChangeEvent_('manifest');

    if (!this.manifest_) {
      this.manifest_ = await this.parser_.start(
          this.assetUri_, this.manifestPlayerInterface_);

      if (this.manifest_.variants.length == 1) {
        const createSegmentIndexPromises = [];
        const variant = this.manifest_.variants[0];
        for (const stream of [variant.video, variant.audio]) {
          if (stream && !stream.segmentIndex) {
            createSegmentIndexPromises.push(stream.createSegmentIndex());
          }
        }
        if (createSegmentIndexPromises.length > 0) {
          await Promise.all(createSegmentIndexPromises);
        }
      }
    }

    this.manifestPromise_.resolve();

    // This event is fired after the manifest is parsed, but before any
    // filtering takes place.
    const event =
          this.makeEvent_(shaka.util.FakeEvent.EventName.ManifestParsed);
    // Delay event to ensure manifest has been properly propagated
    // to the player.
    await Promise.resolve();
    this.dispatchEvent(event);

    // We require all manifests to have at least one variant.
    if (this.manifest_.variants.length == 0) {
      throw new shaka.util.Error(
          shaka.util.Error.Severity.CRITICAL,
          shaka.util.Error.Category.MANIFEST,
          shaka.util.Error.Code.NO_VARIANTS);
    }

    // Make sure that all variants are either: audio-only, video-only, or
    // audio-video.
    shaka.media.PreloadManager.filterForAVVariants_(this.manifest_);

    const now = Date.now() / 1000;
    const delta = now - startTime;
    this.stats_.setManifestTime(delta);
  }
Pick and initialize a manifest parser, then have it download and parse the
manifest.

@return {!Promise}
@private