@@ -1280,7 +1280,10 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
12801280 setTracksEnabled ( stream . getAudioTracks ( ) , audioEnabled ) ;
12811281 setTracksEnabled ( stream . getVideoTracks ( ) , videoEnabled ) ;
12821282
1283- // We want to keep the same stream id, so we replace the tracks rather than the whole stream
1283+ // We want to keep the same stream id, so we replace the tracks rather
1284+ // than the whole stream.
1285+
1286+ // Firstly, we replace the tracks in our localUsermediaStream.
12841287 for ( const track of this . localUsermediaStream ! . getTracks ( ) ) {
12851288 this . localUsermediaStream ! . removeTrack ( track ) ;
12861289 track . stop ( ) ;
@@ -1289,10 +1292,23 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
12891292 this . localUsermediaStream ! . addTrack ( track ) ;
12901293 }
12911294
1295+ // Secondly, we remove tracks that we no longer need from the peer
1296+ // connection, if any. This only happens when we mute the video atm.
1297+ // This will change the transceiver direction to "inactive" and
1298+ // therefore cause re-negotiation.
1299+ for ( const kind of [ "audio" , "video" ] ) {
1300+ const sender = this . transceivers . get ( getTransceiverKey ( SDPStreamMetadataPurpose . Usermedia , kind ) ) ?. sender ;
1301+ // Only remove the track if we aren't going to immediately replace it
1302+ if ( sender && ! stream . getTracks ( ) . find ( ( t ) => t . kind === kind ) ) {
1303+ this . peerConn ?. removeTrack ( sender ) ;
1304+ }
1305+ }
1306+ // Thirdly, we replace the old tracks, if possible.
12921307 for ( const track of stream . getTracks ( ) ) {
12931308 const tKey = getTransceiverKey ( SDPStreamMetadataPurpose . Usermedia , track . kind ) ;
12941309
1295- const oldSender = this . transceivers . get ( tKey ) ?. sender ;
1310+ const transceiver = this . transceivers . get ( tKey ) ;
1311+ const oldSender = transceiver ?. sender ;
12961312 let added = false ;
12971313 if ( oldSender ) {
12981314 try {
@@ -1306,6 +1322,10 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
13061322 `) to peer connection` ,
13071323 ) ;
13081324 await oldSender . replaceTrack ( track ) ;
1325+ // Set the direction to indicate we're going to be sending.
1326+ // This is only necessary in the cases where we're upgrading
1327+ // the call to video after downgrading it.
1328+ transceiver . direction = transceiver . direction === "inactive" ? "sendonly" : "sendrecv" ;
13091329 added = true ;
13101330 } catch ( error ) {
13111331 logger . warn ( `replaceTrack failed: adding new transceiver instead` , error ) ;
@@ -1349,7 +1369,12 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
13491369 await this . upgradeCall ( false , true ) ;
13501370 return this . isLocalVideoMuted ( ) ;
13511371 }
1352- this . localUsermediaFeed ?. setAudioVideoMuted ( null , muted ) ;
1372+ if ( this . opponentSupportsSDPStreamMetadata ( ) ) {
1373+ const stream = await this . client . getMediaHandler ( ) . getUserMediaStream ( true , ! muted ) ;
1374+ await this . updateLocalUsermediaStream ( stream ) ;
1375+ } else {
1376+ this . localUsermediaFeed ?. setAudioVideoMuted ( null , muted ) ;
1377+ }
13531378 this . updateMuteStatus ( ) ;
13541379 await this . sendMetadataUpdate ( ) ;
13551380 return this . isLocalVideoMuted ( ) ;
0 commit comments