1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-07 23:02:56 +03:00

Fix screenshare failing after several attempts (#2771)

* Fix screenshare failing after several attempts

Re-use any existing transceivers when screen sharing. This prevents
transceivers accumulating and making the SDP too big: see linked bug.

This also switches from `addTrack()` to `addTransceiver ()` which is
not that large of a change, other than having to explicitly find the
transceivers after an offer has arrived rather than just adding tracks
and letting WebRTC take care of it.

Fixes https://github.com/vector-im/element-call/issues/625

* Fix tests

* Unused import

* Use a map instead of an array

* Add comment

* more comment

* Remove commented code

* Remove unintentional debugging

* Add test for screenshare transceiver re-use

* Type alias for transceiver map
This commit is contained in:
David Baker
2022-10-19 16:00:54 +01:00
committed by GitHub
parent dfe535bc07
commit c57c8978cf
4 changed files with 235 additions and 108 deletions

View File

@@ -104,12 +104,12 @@ export class MockRTCPeerConnection {
private negotiationNeededListener: () => void;
public iceCandidateListener?: (e: RTCPeerConnectionIceEvent) => void;
public onTrackListener?: (e: RTCTrackEvent) => void;
private needsNegotiation = false;
public needsNegotiation = false;
public readyToNegotiate: Promise<void>;
private onReadyToNegotiate: () => void;
localDescription: RTCSessionDescription;
signalingState: RTCSignalingState = "stable";
public senders: MockRTCRtpSender[] = [];
public transceivers: MockRTCRtpTransceiver[] = [];
public static triggerAllNegotiations(): void {
for (const inst of this.instances) {
@@ -169,12 +169,23 @@ export class MockRTCPeerConnection {
}
close() { }
getStats() { return []; }
addTrack(track: MockMediaStreamTrack): MockRTCRtpSender {
addTransceiver(track: MockMediaStreamTrack): MockRTCRtpTransceiver {
this.needsNegotiation = true;
this.onReadyToNegotiate();
const newSender = new MockRTCRtpSender(track);
this.senders.push(newSender);
return newSender;
const newReceiver = new MockRTCRtpReceiver(track);
const newTransceiver = new MockRTCRtpTransceiver(this);
newTransceiver.sender = newSender as unknown as RTCRtpSender;
newTransceiver.receiver = newReceiver as unknown as RTCRtpReceiver;
this.transceivers.push(newTransceiver);
return newTransceiver;
}
addTrack(track: MockMediaStreamTrack): MockRTCRtpSender {
return this.addTransceiver(track).sender as unknown as MockRTCRtpSender;
}
removeTrack() {
@@ -182,9 +193,8 @@ export class MockRTCPeerConnection {
this.onReadyToNegotiate();
}
getSenders(): MockRTCRtpSender[] { return this.senders; }
getTransceivers = jest.fn().mockReturnValue([]);
getTransceivers(): MockRTCRtpTransceiver[] { return this.transceivers; }
getSenders(): MockRTCRtpSender[] { return this.transceivers.map(t => t.sender as unknown as MockRTCRtpSender); }
doNegotiation() {
if (this.needsNegotiation && this.negotiationNeededListener) {
@@ -198,7 +208,23 @@ export class MockRTCRtpSender {
constructor(public track: MockMediaStreamTrack) { }
replaceTrack(track: MockMediaStreamTrack) { this.track = track; }
setCodecPreferences(prefs: RTCRtpCodecCapability[]): void {}
}
export class MockRTCRtpReceiver {
constructor(public track: MockMediaStreamTrack) { }
}
export class MockRTCRtpTransceiver {
constructor(private peerConn: MockRTCPeerConnection) {}
public sender: RTCRtpSender;
public receiver: RTCRtpReceiver;
public set direction(_: string) {
this.peerConn.needsNegotiation = true;
}
setCodecPreferences = jest.fn<void, RTCRtpCodecCapability[]>();
}
export class MockMediaStreamTrack {