in src/sdp/SDP.ts [421:478]
private withRtpHeaderExtension(previousSdp: SDP, url: string): SDP {
// According to https://webrtc.googlesource.com/src/+/b62ee8ce94e5f10e0a94d6f112e715cc4d0cd9dc,
// RTP header extension ID change would result in a hard failure. Therefore if the extension exists
// in the previous SDP, use the same extension ID to avoid the failure. Otherwise use a new ID
const previousId = previousSdp ? previousSdp.getRtpHeaderExtensionId(url) : -1;
const id =
previousId === -1 ? this.getUniqueRtpHeaderExtensionId(SDP.splitLines(this.sdp)) : previousId;
const sections = SDP.splitSections(this.sdp);
const newSections = [];
for (let section of sections) {
if (/^m=video/.test(section) && SDP.getRtpHeaderExtensionIdInSection(section, url) === -1) {
// Add RTP header extension when it does not already exist
const srcLines: string[] = SDP.splitLines(section);
const dstLines: string[] = [];
if (id === -1 || this.hasRtpHeaderExtensionId(id)) {
// if all ids are used or the id is already used, we won't add new line to it
newSections.push(section);
continue;
}
for (const line of srcLines) {
dstLines.push(line);
if (/^a=sendrecv/.test(line.trim())) {
const targetLine = `a=extmap:` + id + ` ` + url;
dstLines.push(targetLine);
}
}
section = dstLines.join(SDP.CRLF) + SDP.CRLF;
} else if (
previousId !== -1 &&
/^m=video/.test(section) &&
SDP.getRtpHeaderExtensionIdInSection(section, url) !== previousId
) {
// Override extension ID if it does not match previous SDP
const srcLines: string[] = SDP.splitLines(section);
const dstLines: string[] = [];
for (const line of srcLines) {
if (/^a=extmap:/.test(line.trim())) {
const headerExtension = line.split('a=extmap:')[1].split(' ');
if (headerExtension[1] === url) {
if (!this.hasRtpHeaderExtensionId(previousId)) {
// If previous ID is used by another extension, remove it from this SDP
const targetLine = `a=extmap:` + previousId + ` ` + url;
dstLines.push(targetLine);
}
continue;
}
}
dstLines.push(line);
}
section = dstLines.join(SDP.CRLF) + SDP.CRLF;
}
newSections.push(section);
}
const newSdp = newSections.join('');
return new SDP(newSdp);
}