Skip to content

Commit

Permalink
Enable nack for audio track only if offer want it (#555)
Browse files Browse the repository at this point in the history
* Enable nack for audio track only if offer want it

* changeset

* prettier

* Update .changeset/rare-rivers-collect.md

Co-authored-by: lukasIO <mail@lukasseiler.de>

Co-authored-by: lukasIO <mail@lukasseiler.de>
  • Loading branch information
cnderrauber and lukasIO committed Jan 14, 2023
1 parent fe08625 commit 0bc67ba
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/rare-rivers-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'livekit-client': patch
---

Enable nack for audio track only if offer wants it
28 changes: 22 additions & 6 deletions src/room/PCTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export default class PCTransport extends EventEmitter {

remoteStereoMids: string[] = [];

remoteNackMids: string[] = [];

onOffer?: (offer: RTCSessionDescriptionInit) => void;

constructor(config?: RTCConfiguration) {
Expand All @@ -50,7 +52,9 @@ export default class PCTransport extends EventEmitter {

async setRemoteDescription(sd: RTCSessionDescriptionInit): Promise<void> {
if (sd.type === 'offer') {
this.remoteStereoMids = extractStereoTracksFromOffer(sd);
let { stereoMids, nackMids } = extractStereoAndNackAudioFromOffer(sd);
this.remoteStereoMids = stereoMids;
this.remoteNackMids = nackMids;
}
await this.pc.setRemoteDescription(sd);

Expand Down Expand Up @@ -116,7 +120,7 @@ export default class PCTransport extends EventEmitter {
const sdpParsed = parse(offer.sdp ?? '');
sdpParsed.media.forEach((media) => {
if (media.type === 'audio') {
ensureAudioNackAndStereo(media, []);
ensureAudioNackAndStereo(media, [], []);
} else if (media.type === 'video') {
// mung sdp for codec bitrate setting that can't apply by sendEncoding
this.trackBitrates.some((trackbr): boolean => {
Expand Down Expand Up @@ -169,7 +173,7 @@ export default class PCTransport extends EventEmitter {
const sdpParsed = parse(answer.sdp ?? '');
sdpParsed.media.forEach((media) => {
if (media.type === 'audio') {
ensureAudioNackAndStereo(media, this.remoteStereoMids);
ensureAudioNackAndStereo(media, this.remoteStereoMids, this.remoteNackMids);
}
});
await this.setMungedLocalDescription(answer, write(sdpParsed));
Expand Down Expand Up @@ -226,6 +230,7 @@ function ensureAudioNackAndStereo(
payloads?: string | undefined;
} & MediaDescription,
stereoMids: string[],
nackMids: string[],
) {
// found opus codec to add nack fb
let opusPayload = 0;
Expand All @@ -243,7 +248,10 @@ function ensureAudioNackAndStereo(
media.rtcpFb = [];
}

if (!media.rtcpFb.some((fb) => fb.payload === opusPayload && fb.type === 'nack')) {
if (
nackMids.includes(media.mid!) &&
!media.rtcpFb.some((fb) => fb.payload === opusPayload && fb.type === 'nack')
) {
media.rtcpFb.push({
payload: opusPayload,
type: 'nack',
Expand All @@ -264,8 +272,12 @@ function ensureAudioNackAndStereo(
}
}

function extractStereoTracksFromOffer(offer: RTCSessionDescriptionInit): string[] {
function extractStereoAndNackAudioFromOffer(offer: RTCSessionDescriptionInit): {
stereoMids: string[];
nackMids: string[];
} {
const stereoMids: string[] = [];
const nackMids: string[] = [];
const sdpParsed = parse(offer.sdp ?? '');
let opusPayload = 0;
sdpParsed.media.forEach((media) => {
Expand All @@ -278,6 +290,10 @@ function extractStereoTracksFromOffer(offer: RTCSessionDescriptionInit): string[
return false;
});

if (media.rtcpFb?.some((fb) => fb.payload === opusPayload && fb.type === 'nack')) {
nackMids.push(media.mid!);
}

media.fmtp.some((fmtp): boolean => {
if (fmtp.payload === opusPayload) {
if (fmtp.config.includes('sprop-stereo=1')) {
Expand All @@ -289,5 +305,5 @@ function extractStereoTracksFromOffer(offer: RTCSessionDescriptionInit): string[
});
}
});
return stereoMids;
return { stereoMids, nackMids };
}

0 comments on commit 0bc67ba

Please sign in to comment.