Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse closed m= sections in Firefox #149

Open
wants to merge 13 commits into
base: v3
Choose a base branch
from
14 changes: 4 additions & 10 deletions src/handlers/Firefox60.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,6 @@ export class Firefox60 extends HandlerInterface
sendingRemoteRtpParameters.codecs =
ortc.reduceCodecs(sendingRemoteRtpParameters.codecs, codec);

// NOTE: Firefox fails sometimes to properly anticipate the closed media
// section that it should use, so don't reuse closed media sections.
// https://github.com/versatica/mediasoup-client/issues/104
//
// const mediaSectionIdx = this._remoteSdp!.getNextMediaSectionIdx();
const transceiver = this._pc.addTransceiver(
track, { direction: 'sendonly', streams: [ this._sendStream ] });

Expand Down Expand Up @@ -395,7 +390,8 @@ export class Firefox60 extends HandlerInterface

localSdpObject = sdpTransform.parse(this._pc.localDescription.sdp);

const offerMediaObject = localSdpObject.media[localSdpObject.media.length - 1];
const offerMediaObject =
localSdpObject.media[localSdpObject.media.findIndex((s) => s.mid == localId)];

// Set RTCP CNAME.
sendingRtpParameters.rtcp.cname =
Expand Down Expand Up @@ -451,6 +447,7 @@ export class Firefox60 extends HandlerInterface
this._remoteSdp!.send(
{
offerMediaObject,
localSdpMedia : localSdpObject.media,
offerRtpParameters : sendingRtpParameters,
answerRtpParameters : sendingRemoteRtpParameters,
codecOptions,
Expand Down Expand Up @@ -498,10 +495,7 @@ export class Firefox60 extends HandlerInterface
// {}

this._pc.removeTrack(transceiver.sender);
// NOTE: Cannot use closeMediaSection() due to the the note above in send()
// method.
// this._remoteSdp!.closeMediaSection(transceiver.mid);
this._remoteSdp!.disableMediaSection(transceiver.mid!);
this._remoteSdp!.closeMediaSection(transceiver.mid!);

const offer = await this._pc.createOffer();

Expand Down
58 changes: 57 additions & 1 deletion src/handlers/sdp/RemoteSdp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export class RemoteSdp
{
offerMediaObject,
reuseMid,
localSdpMedia,
offerRtpParameters,
answerRtpParameters,
codecOptions,
Expand All @@ -170,6 +171,7 @@ export class RemoteSdp
{
offerMediaObject: any;
reuseMid?: string;
localSdpMedia?: any;
offerRtpParameters: RtpParameters;
answerRtpParameters: RtpParameters;
codecOptions?: ProducerCodecOptions;
Expand Down Expand Up @@ -199,7 +201,14 @@ export class RemoteSdp
// Unified-Plan or Plan-B with different media kind.
else if (!this._midToIndex.has(mediaSection.mid))
{
this._addMediaSection(mediaSection);
if (localSdpMedia)
{
this._syncMediaWithLocalSdp(localSdpMedia, mediaSection);
}
else
{
this._addMediaSection(mediaSection);
}
}
// Plan-B with same media kind.
else
Expand Down Expand Up @@ -469,6 +478,53 @@ export class RemoteSdp
}
}

_syncMediaWithLocalSdp(localSdpMedia: any, newMediaSection: MediaSection): void
{
if (!this._firstMid)
{
this._firstMid = newMediaSection.mid;
}

// Append new section to the existing vector and the SDP object.
let idx = this._mediaSections.length;

this._mediaSections.push(newMediaSection);
this._sdpObject.media.push(newMediaSection.getObject());

// Add it to the map.
this._midToIndex.set(newMediaSection.mid, idx);

// Copy data to the temporary collections.
const mediaSections = this._mediaSections.slice();
const media = this._sdpObject.media.slice();

// Clean up existing collections.
this._mediaSections.length = this._sdpObject.media.length = 0;

// Refill media sections vector and SDP object media
// using the order of sections in the local SDP offer.
for (const mediaSection of localSdpMedia)
{
const i = this._midToIndex.get(String(mediaSection.mid));

if (i !== undefined)
{
this._mediaSections.push(mediaSections[i]);
this._sdpObject.media.push(media[i]);
}
}

// Recreate map.
this._midToIndex.clear();
for (idx = 0; idx < this._mediaSections.length; ++idx)
{
this._midToIndex.set(this._mediaSections[idx].mid, idx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

braces missing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Braces added.

}

// Regenerate BUNDLE mids.
this._regenerateBundleMids();
}

_findMediaSection(mid: string): MediaSection
{
const idx = this._midToIndex.get(mid);
Expand Down