private sectionWithCodecPreferences()

in src/sdp/SDP.ts [719:787]


  private sectionWithCodecPreferences(
    section: string,
    preferences: VideoCodecCapability[]
  ): string {
    const payloadTypeToCodec: Map<string, VideoCodecCapability> = new Map();
    const lines = SDP.splitLines(section);

    // Process each line to map payload types to their respective codecs
    lines.forEach(line => {
      if (!line.startsWith('a=rtpmap:')) {
        return;
      }

      const payloadMatch = /^a=rtpmap:(\d+)\s/.exec(line);
      if (!payloadMatch) {
        return;
      }
      const payloadTypeString: string = payloadMatch[1];

      for (const preference of preferences) {
        if (!line.includes(`${preference.codecName}/${preference.codecCapability.clockRate}`)) {
          continue;
        }

        let codecMatches = false;
        if (preference.codecCapability.sdpFmtpLine !== undefined) {
          let hasVp9ProfileId = false;

          for (const prospectiveFmtpLine of lines) {
            if (preference.fmtpLineMatches(prospectiveFmtpLine, parseInt(payloadTypeString))) {
              codecMatches = true;
              break;
            }

            hasVp9ProfileId ||= prospectiveFmtpLine.startsWith(
              `a=fmtp:${payloadTypeString} profile-id=`
            );
          }

          if (preference.equals(VideoCodecCapability.vp9Profile0()) && !hasVp9ProfileId) {
            codecMatches = true;
          }
        } else {
          codecMatches = true;
        }

        if (codecMatches) {
          payloadTypeToCodec.set(payloadTypeString, preference);
          break;
        }
      }
    });

    const payloadTypesToRemove: Set<string> = new Set(payloadTypeToCodec.keys());
    const mline = lines[0].split(' ').filter(text => !payloadTypesToRemove.has(text));

    const orderedPreferedPayloadTypes = Array.from(payloadTypeToCodec.entries())
      .sort(([_payloadType1, codec1], [_payloadType2, codec2]) => {
        const priority1 = preferences.indexOf(codec1);
        const priority2 = preferences.indexOf(codec2);
        return priority1 - priority2;
      })
      .map(([payloadType, _]) => payloadType);

    mline.splice(3, 0, ...orderedPreferedPayloadTypes);
    lines[0] = mline.join(' ');

    return lines.join(SDP.CRLF) + SDP.CRLF;
  }