"use strict"; /* Helper functions to munge SDP and split the sending track into * separate tracks on the receiving end. This can be done in a number * of ways, the one used here uses the fact that the MID and RID header * extensions which are used for packet routing share the same wire * format. The receiver interprets the rids from the sender as mids * which allows receiving the different spatial resolutions on separate * m-lines and tracks.
*/
// Borrowed from wpt, with some dependencies removed.
// Skip mid extension; we are replacing it with the rid extmap
rtpParameters.headerExtensions = rtpParameters.headerExtensions.filter(
ext => ext.uri != "urn:ietf:params:rtp-hdrext:sdes:mid"
);
for (const ext of rtpParameters.headerExtensions) { if (ext.uri == "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id") {
ext.uri = "urn:ietf:params:rtp-hdrext:sdes:mid";
}
}
// Filter rtx as we have no way to (re)interpret rrid. // Not doing this makes probing use RTX, it's not understood and ramp-up is slower.
rtpParameters.codecs = rtpParameters.codecs.filter(
c => c.name.toUpperCase() !== "RTX"
);
if (!rids) {
rids = Array.from(description.sdp.matchAll(/a=rid:(.*) send/g)).map(
r => r[1]
);
}
// Skip rid extensions; we are replacing them with the mid extmap
rtpParameters.headerExtensions = rtpParameters.headerExtensions.filter(
ext => !ridExtensions.includes(ext.uri)
);
for (const ext of rtpParameters.headerExtensions) { if (ext.uri == "urn:ietf:params:rtp-hdrext:sdes:mid") {
ext.uri = "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
}
}
if (!rids) {
rids = []; for (let i = 1; i < sections.length; i++) {
rids.push(SDPUtils.getMid(sections[i]));
}
}
let sdp =
SDPUtils.writeSessionBoilerplate() +
SDPUtils.writeDtlsParameters(dtls, setupValue) +
SDPUtils.writeIceParameters(ice) + "a=group:BUNDLE " +
localMid + "\r\n";
sdp += SDPUtils.writeRtpDescription(mline.kind, rtpParameters); // Although we are converting mids to rids, we still need a mid. // The first one will be consistent with trickle ICE candidates.
sdp += "a=mid:" + localMid + "\r\n";
sdp += directionValue + "\r\n";
async function doOfferToSendSimulcast(offerer, answerer) {
await offerer.setLocalDescription();
// Is this a renegotiation? If so, we cannot remove (or reorder!) any mids, // even if some rids have been removed or reordered.
let mids = []; if (answerer.localDescription) { // Renegotiation. Mids must be the same as before, because renegotiation // can never remove or reorder mids, nor can it expand the simulcast // envelope.
mids = [...answerer.localDescription.sdp.matchAll(/a=mid:(.*)/g)].map(
e => e[1]
);
} else { // First negotiation; the mids will be exactly the same as the rids const simulcastAttr = offerer.localDescription.sdp.match(
/a=simulcast:send (.*)/
); if (simulcastAttr) {
mids = simulcastAttr[1].split(";");
}
}
async function doAnswerToSendSimulcast(offerer, answerer) {
await answerer.setLocalDescription();
// See which mids the offerer had; it will barf if we remove or reorder them const mids = [...offerer.localDescription.sdp.matchAll(/a=mid:(.*)/g)].map(
e => e[1]
);
// This would be useful for cases other than simulcast, but we do not use it // anywhere else right now, nor do we have a place for wpt-friendly helpers at // the moment. function createPlaybackElement(track) { const elem = document.createElement(track.kind);
elem.autoplay = true;
elem.srcObject = new MediaStream([track]);
elem.id = track.id;
elem.width = 240;
elem.height = 180;
document.body.appendChild(elem); return elem;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.