parseAudioChannels_(audioChannelConfigs) {
    for (const elem of audioChannelConfigs) {
      const scheme = elem.attributes['schemeIdUri'];
      if (!scheme) {
        continue;
      }

      const value = elem.attributes['value'];
      if (!value) {
        continue;
      }

      switch (scheme) {
        case 'urn:mpeg:dash:outputChannelPositionList:2012':
          // A space-separated list of speaker positions, so the number of
          // channels is the length of this list.
          return value.trim().split(/ +/).length;

        case 'urn:mpeg:dash:23003:3:audio_channel_configuration:2011':
        case 'urn:dts:dash:audio_channel_configuration:2012': {
          // As far as we can tell, this is a number of channels.
          const intValue = parseInt(value, 10);
          if (!intValue) {  // 0 or NaN
            shaka.log.warning('Channel parsing failure! ' +
                          'Ignoring scheme and value', scheme, value);
            continue;
          }
          return intValue;
        }

        case 'tag:dolby.com,2015:dash:audio_channel_configuration:2015': {
          // ETSI TS 103 190-2 v1.2.1, Annex G.3
          // LSB-to-MSB order
          const channelCountMapping =
            [2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2];
          const hexValue = parseInt(value, 16);
          if (!hexValue) {  // 0 or NaN
            shaka.log.warning('Channel parsing failure! ' +
                          'Ignoring scheme and value', scheme, value);
            continue;
          }
          let numBits = 0;
          for (let i = 0; i < channelCountMapping.length; i++) {
            if (hexValue & (1<<i)) {
              numBits += channelCountMapping[i];
            }
          }
          if (numBits) {
            return numBits;
          }
          continue;
        }

        case 'tag:dolby.com,2014:dash:audio_channel_configuration:2011':
        case 'urn:dolby:dash:audio_channel_configuration:2011': {
          // Defined by https://ott.dolby.com/OnDelKits/DDP/Dolby_Digital_Plus_Online_Delivery_Kit_v1.5/Documentation/Content_Creation/SDM/help_files/topics/ddp_mpeg_dash_c_mpd_auchlconfig.html
          // keep list in order of the spec; reverse for LSB-to-MSB order
          const channelCountMapping =
            [1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1].reverse();
          const hexValue = parseInt(value, 16);
          if (!hexValue) {  // 0 or NaN
            shaka.log.warning('Channel parsing failure! ' +
                          'Ignoring scheme and value', scheme, value);
            continue;
          }
          let numBits = 0;
          for (let i = 0; i < channelCountMapping.length; i++) {
            if (hexValue & (1<<i)) {
              numBits += channelCountMapping[i];
            }
          }
          if (numBits) {
            return numBits;
          }
          continue;
        }

        // Defined by https://dashif.org/identifiers/audio_source_metadata/ and clause 8.2, in ISO/IEC 23001-8.
        case 'urn:mpeg:mpegB:cicp:ChannelConfiguration': {
          const noValue = 0;
          const channelCountMapping = [
            noValue, 1, 2, 3, 4, 5, 6, 8, 2, 3, /* 0--9 */
            4, 7, 8, 24, 8, 12, 10, 12, 14, 12, /* 10--19 */
            14, /* 20 */
          ];
          const intValue = parseInt(value, 10);
          if (!intValue) {  // 0 or NaN
            shaka.log.warning('Channel parsing failure! ' +
                          'Ignoring scheme and value', scheme, value);
            continue;
          }
          if (intValue > noValue && intValue < channelCountMapping.length) {
            return channelCountMapping[intValue];
          }
          continue;
        }

        default:
          shaka.log.warning(
              'Unrecognized audio channel scheme:', scheme, value);
          continue;
      }
    }

    return null;
  }
@param {!Array<!shaka.extern.xml.Node>} audioChannelConfigs An array of
  AudioChannelConfiguration elements.
@return {?number} The number of audio channels, or null if unknown.
@private