static defaultTrackSelect(
      tracks, preferredAudioLanguage, preferredVideoHdrLevel) {
    const ContentType = shaka.util.ManifestParserUtils.ContentType;
    const LanguageUtils = shaka.util.LanguageUtils;

    let hdrLevel = preferredVideoHdrLevel;
    if (hdrLevel == 'AUTO') {
      const someHLG = tracks.some((track) => {
        if (track.hdr && track.hdr == 'HLG') {
          return true;
        }
        return false;
      });
      const device = shaka.device.DeviceFactory.getDevice();
      hdrLevel = device.getHdrLevel(someHLG);
    }

    /** @type {!Array<shaka.extern.Track>} */
    const allVariants = tracks.filter((track) => {
      if (track.type != 'variant') {
        return false;
      }
      if (track.hdr && track.hdr != hdrLevel) {
        return false;
      }
      return true;
    });

    /** @type {!Array<shaka.extern.Track>} */
    let selectedVariants = [];

    // Find the locale that best matches our preferred audio locale.
    const closestLocale = LanguageUtils.findClosestLocale(
        preferredAudioLanguage,
        allVariants.map((variant) => variant.language));
    // If we found a locale that was close to our preference, then only use
    // variants that use that locale.
    if (closestLocale) {
      selectedVariants = allVariants.filter((variant) => {
        const locale = LanguageUtils.normalize(variant.language);
        return locale == closestLocale;
      });
    }

    // If we failed to get a language match, go with primary.
    if (selectedVariants.length == 0) {
      selectedVariants = allVariants.filter((variant) => {
        return variant.primary;
      });
    }

    // Otherwise, there is no good way to choose the language, so we don't
    // choose a language at all.
    if (selectedVariants.length == 0) {
      // Issue a warning, but only if the content has multiple languages.
      // Otherwise, this warning would just be noise.
      const languages = new Set(allVariants.map((track) => {
        return track.language;
      }));

      if (languages.size > 1) {
        shaka.log.warning('Could not choose a good audio track based on ' +
                          'language preferences or primary tracks.  An ' +
                          'arbitrary language will be stored!');
      }

      // Default back to all variants.
      selectedVariants = allVariants;
    }

    // From previously selected variants, choose the SD ones (height <= 480).
    const tracksByHeight = selectedVariants.filter((track) => {
      return track.height && track.height <= 480;
    });

    // If variants don't have video or no video with height <= 480 was
    // found, proceed with the previously selected tracks.
    if (tracksByHeight.length) {
      // Sort by resolution, then select all variants which match the height
      // of the highest SD res.  There may be multiple audio bitrates for the
      // same video resolution.
      tracksByHeight.sort((a, b) => {
        // The items in this list have already been screened for height, but the
        // compiler doesn't know that.
        goog.asserts.assert(a.height != null, 'Null height');
        goog.asserts.assert(b.height != null, 'Null height');

        return b.height - a.height;
      });
      selectedVariants = tracksByHeight.filter((track) => {
        return track.height == tracksByHeight[0].height;
      });
    }

    /** @type {!Array<shaka.extern.Track>} */
    const selectedTracks = [];

    // If there are multiple matches at different audio bitrates, select the
    // middle bandwidth one.
    if (selectedVariants.length) {
      const middleIndex = Math.floor(selectedVariants.length / 2);
      selectedVariants.sort((a, b) => a.bandwidth - b.bandwidth);
      selectedTracks.push(selectedVariants[middleIndex]);
    }

    // Since this default callback is used primarily by our own demo app and by
    // app developers who haven't thought about which tracks they want, we
    // should select all image/text tracks, regardless of language.  This makes
    // for a better demo for us, and does not rely on user preferences for the
    // unconfigured app.
    for (const track of tracks) {
      if (track.type == ContentType.TEXT || track.type == ContentType.IMAGE) {
        selectedTracks.push(track);
      }
    }

    return selectedTracks;
  }
@param {!Array<shaka.extern.Track>} tracks
@param {string} preferredAudioLanguage
@param {string} preferredVideoHdrLevel
@return {!Array<shaka.extern.Track>}