Skip to content

Commit

Permalink
Add audio redundancy RED RFC2198 support (#14)
Browse files Browse the repository at this point in the history
Add audio redundancy RED RFC2198 support
  • Loading branch information
misi authored Oct 6, 2023
1 parent 4937cb6 commit a90ba25
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
32 changes: 26 additions & 6 deletions src/webrtc/P2pRtcManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,28 @@ export default class P2pRtcManager extends BaseRtcManager {
}
}

_setCodecPreferences(pc, vp9On, av1On) {
_setCodecPreferences(pc, vp9On, av1On, redOn) {
try {
// audio
const audioTransceivers = pc
.getTransceivers()
.filter((transceiver) => transceiver?.sender?.track?.kind === "audio");

audioTransceivers.forEach((audioTransceiver) => {
// If not implemented return
if (typeof RTCRtpSender.getCapabilities === "undefined") return;
const capabilities = RTCRtpSender.getCapabilities("audio");
for (let i = 0; i < capabilities.codecs.length; i++) {
if (redOn && capabilities.codecs[i].mimeType.toLowerCase() === "audio/red") {
capabilities.codecs.unshift(capabilities.codecs.splice(i, 1)[0]);
break;
}
}
// If not implemented return
if (typeof audioTransceiver.setCodecPreferences === "undefined") return;
audioTransceiver.setCodecPreferences(capabilities.codecs);
});
// video
const videoTransceivers = pc
.getTransceivers()
.filter((transceiver) => transceiver?.sender?.track?.kind === "video");
Expand Down Expand Up @@ -89,19 +109,19 @@ export default class P2pRtcManager extends BaseRtcManager {
}
session.isOperationPending = true;

const { vp9On, av1On } = this._features;
const { vp9On, av1On, redOn } = this._features;

// Set codec preferences to video transceivers
if (vp9On || av1On) {
this._setCodecPreferences(pc, vp9On, av1On);
if (vp9On || av1On || redOn) {
this._setCodecPreferences(pc, vp9On, av1On, redOn);
}

pc.createOffer(constraints || this.offerOptions)
.then((offer) => {
// SDP munging workaround for Firefox, because it doesn't support setCodecPreferences()
// Only vp9 because FF does not support AV1 yet
if (vp9On && browserName === "firefox") {
offer.sdp = setCodecPreferenceSDP(offer.sdp, vp9On);
if ((vp9On || redOn) && browserName === "firefox") {
offer.sdp = setCodecPreferenceSDP(offer.sdp, vp9On, redOn);
}

this._emitServerEvent(RELAY_MESSAGES.SDP_OFFER, {
Expand Down
18 changes: 17 additions & 1 deletion src/webrtc/sdpModifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ import * as sdpTransform from "sdp-transform";
const browserName = adapter.browserDetails.browser;
const browserVersion = adapter.browserDetails.version;

export function setCodecPreferenceSDP(sdp, vp9On) {
export function setCodecPreferenceSDP(sdp, vp9On, redOn) {
try {
const sdpObject = sdpTransform.parse(sdp);
if (Array.isArray(sdpObject?.media)) {
//audio
const mediaAudio = sdpObject.media.find((m) => m.type === "audio");
if (Array.isArray(mediaAudio?.rtp)) {
const rtp = mediaAudio.rtp;
for (let i = 0; i < rtp.length; i++) {
if (redOn && rtp[i].codec === "red") {
const payloads = mediaAudio.payloads.split(" ");
const pt = payloads.indexOf("" + rtp[i].payload);
if (pt && pt !== -1 && pt >= 0) {
payloads.unshift(payloads.splice(pt, 1)[0]);
mediaAudio.payloads = payloads.join(" ");
}
}
}
}
//video
const mediaVideo = sdpObject.media.find((m) => m.type === "video");
if (Array.isArray(mediaVideo?.rtp)) {
const rtp = mediaVideo.rtp;
Expand Down

0 comments on commit a90ba25

Please sign in to comment.