static createManifests(compiledShaka, suffix) {
    /**
     * @param {AVMetadataType} metadata
     * @return {!shaka.test.IStreamGenerator}
     */
    function createStreamGenerator(metadata) {
      if (metadata.segmentUri.includes('.ts')) {
        return new shaka.test.TSVodStreamGenerator(
            metadata.segmentUri, metadata.segmentDuration);
      }
      if (metadata.segmentUri.includes('.aac')) {
        return new shaka.test.AACVodStreamGenerator(metadata.segmentUri);
      }
      return new shaka.test.Mp4VodStreamGenerator(
          metadata.initSegmentUri, metadata.mdhdOffset, metadata.segmentUri,
          metadata.tfdtOffset, metadata.segmentDuration);
    }

    /**
     * Not for simulating non-segmented text streams.
     *
     * @param {!shaka.test.ManifestGenerator.Stream} stream
     * @param {!shaka.test.ManifestGenerator.Variant} variant
     * @param {MetadataType} data
     * @param {shaka.util.ManifestParserUtils.ContentType} contentType
     * @param {string} name
     */
    function addStreamInfo(stream, variant, data, contentType, name) {
      const mediaQualityInfo = {
        bandwidth: 1,
        codecs: data[contentType].codecs || 'unknown',
        contentType: contentType,
        mimeType: data[contentType].mimeType,
        audioSamplingRate: null,
        frameRate: null,
        height: null,
        channelsCount: null,
        pixelAspectRatio: null,
        width: null,
        label: null,
        roles: null,
        language: null,
      };
      stream.mimeType = data[contentType].mimeType;
      stream.codecs = data[contentType].codecs;
      stream.setInitSegmentReference(
          ['test:' + name + '/' + contentType + '/init'], 0, null,
          mediaQualityInfo);
      stream.useSegmentTemplate(
          'test:' + name + '/' + contentType + '/%d',
          data[contentType].segmentDuration);
      stream.segmentIndex.markImmutable();
      stream.closedCaptions = data[contentType].closedCaptions;

      if (data[contentType].delaySetup) {
        stream.createSegmentIndex = () => shaka.test.Util.delay(1);
      }

      if (data.licenseServers) {
        // Real content typically doesn't contain license server URLs, but if it
        // does, we use them in preference over everything else.  There is a
        // config to override that for DASH, but this test utility isn't DASH
        // and that player config wouldn't do any good for a test case.
        //
        // So, we don't put the specific license servers into the manifest
        // structure.  That should always be done in the player config instead,
        // and we have the static setupPlayer() method above to do that in
        // tests.
        //
        // Instead, we place generic DrmInfo for all common key systems here,
        // and tests can use any of them by configuring a license server.
        const commonKeySystems = [
          'com.apple.fps.1_0',
          'com.microsoft.playready',
          'com.widevine.alpha',
        ];
        for (const keySystem of commonKeySystems) {
          stream.encrypted = true;
          stream.addDrmInfo(keySystem, (drmInfo) => {
            if (data[contentType].initData) {
              drmInfo.addCencInitData(data[contentType].initData);
            }
          });
        }
      }

      if (data.customizeStream) {
        data.customizeStream(stream);
      }
    }

    /**
     * @param {MetadataType} data
     * @return {string}
     */
    function getAbsoluteUri(data) {
      // This seems to be necessary.  Otherwise, we end up with an URL like
      // "http:/base/..." which then fails to load on Safari for some reason.
      const locationUri = new goog.Uri(location.href);
      const partialUri = new goog.Uri(data.text.uri);
      return locationUri.resolve(partialUri).toString();
    }

    const promises = [];
    // Include 'window' to use uncompiled version version of the library.
    const DATA = shaka.test.TestScheme.DATA;
    const GENERATORS = shaka.test.TestScheme.GENERATORS;
    const MANIFESTS = shaka.test.TestScheme.MANIFESTS;
    const ContentType = shaka.util.ManifestParserUtils.ContentType;

    for (const name in DATA) {
      GENERATORS[name + suffix] = GENERATORS[name + suffix] || {};
      const data = DATA[name];
      for (const type of [ContentType.VIDEO, ContentType.AUDIO]) {
        if (data[type]) {
          const streamGen = createStreamGenerator(data[type]);
          GENERATORS[name + suffix][type] = streamGen;
          promises.push(streamGen.init());
        }
      }

      let nextId = 0;

      const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
        manifest.presentationTimeline.setDuration(data.duration);
        manifest.sequenceMode = data.sequenceMode || false;
        if (data.nextUrl) {
          manifest.nextUrl = data.nextUrl + suffix;
        }

        const videoResolutions = data.videoResolutions || [undefined];
        const audioLanguages = data.audioLanguages ||
            (data.audio && [data.audio.language]) || [undefined];

        if (data.video && data.audio) {
          const resMap = new Map();
          const langMap = new Map();
          for (const res of videoResolutions) {
            for (const lang of audioLanguages) {
              manifest.addVariant(nextId++, (variant) => {
                if (resMap.has(res)) {
                  variant.addExistingStream(resMap.get(res));
                } else {
                  resMap.set(res, nextId);
                  variant.addVideo(nextId++, (stream) => {
                    addStreamInfo(
                        stream, variant, data, ContentType.VIDEO, name);
                    if (res) {
                      stream.size(res[0], res[1]);
                    }
                  });
                }

                if (langMap.has(lang)) {
                  variant.addExistingStream(langMap.get(lang));
                } else {
                  langMap.set(lang, nextId);
                  variant.addAudio(nextId++, (stream) => {
                    addStreamInfo(
                        stream, variant, data, ContentType.AUDIO, name);
                    if (lang) {
                      stream.language = lang;
                    }
                  });
                }

                if (lang) {
                  variant.language = lang;
                }
              });
            }
          }
        } else if (data.video) {
          for (const res of videoResolutions) {
            manifest.addVariant(nextId++, (variant) => {
              variant.addVideo(nextId++, (stream) => {
                addStreamInfo(stream, variant, data, ContentType.VIDEO, name);
                if (res) {
                  stream.size(res[0], res[1]);
                }
              });
            });
          }
        } else if (data.audio) {
          for (const lang of audioLanguages) {
            manifest.addVariant(nextId++, (variant) => {
              variant.addAudio(nextId++, (stream) => {
                addStreamInfo(stream, variant, data, ContentType.AUDIO, name);
                if (lang) {
                  variant.language = lang;
                  stream.language = lang;
                }
              });
            });
          }
        }

        if (data.text) {
          const textLanguages = data.textLanguages || [data.text.language];

          for (const lang of textLanguages) {
            manifest.addTextStream(nextId++, (stream) => {
              stream.mimeType = data.text.mimeType;
              stream.codecs = data.text.codecs || '';
              stream.textStream(getAbsoluteUri(data));

              if (lang) {
                stream.language = lang;
              }
            });
          }
        }
      }, compiledShaka);

      MANIFESTS[name + suffix] = manifest;
    }

    return Promise.all(promises);
  }
Creates the manifests and generators.
@param {shakaNamespaceType} compiledShaka
@param {string} suffix
@return {!Promise}