diff --git a/app/script/calling/entities/FlowEntity.js b/app/script/calling/entities/FlowEntity.js index 808fa9e69ed..82b73e9c0a9 100644 --- a/app/script/calling/entities/FlowEntity.js +++ b/app/script/calling/entities/FlowEntity.js @@ -409,7 +409,7 @@ z.calling.entities.FlowEntity = class FlowEntity { */ _closePeerConnection() { const peerConnection = this.peerConnection; - if (!this.peerConnection) { + if (!peerConnection) { return; } @@ -418,13 +418,21 @@ z.calling.entities.FlowEntity = class FlowEntity { }; peerConnection.onsignalingstatechange = () => { - const logMessage = `State change ignored - signaling state: ${this.peerConnection.signalingState}`; + const logMessage = `State change ignored - signaling state: ${peerConnection.signalingState}`; this.callLogger.log(this.callLogger.levels.OFF, logMessage); }; const isStateClosed = peerConnection.signalingState === z.calling.rtc.SIGNALING_STATE.CLOSED; if (!isStateClosed) { - amplify.publish(z.event.WebApp.CALL.MEDIA.REMOVE_STREAM, peerConnection.getRemoteStreams()); + let connectionMediaStreamTracks; + if (peerConnection.getReceivers) { + connectionMediaStreamTracks = peerConnection.getReceivers().map(receiver => receiver.track); + } else { + connectionMediaStreamTracks = peerConnection + .getRemoteStreams() + .reduce((tracks, stream) => tracks.concat(stream.getTracks()), []); + } + amplify.publish(z.event.WebApp.CALL.MEDIA.CONNECTION_CLOSED, connectionMediaStreamTracks); peerConnection.close(); const logMessage = { diff --git a/app/script/event/WebApp.js b/app/script/event/WebApp.js index 55b5c14bc3c..a7cc41fb130 100644 --- a/app/script/event/WebApp.js +++ b/app/script/event/WebApp.js @@ -52,8 +52,8 @@ z.event.WebApp = { MEDIA: { ADD_STREAM: 'wire.webapp.call.media.add_stream', CHOOSE_SCREEN: 'wire.webapp.call.media.choose_screen', + CONNECTION_CLOSED: 'wire.webapp.call.media.connection_closed', MUTE_AUDIO: 'wire.webapp.call.media.mute_audio', - REMOVE_STREAM: 'wire.webapp.call.media.remove_stream', TOGGLE: 'wire.webapp.call.media.toggle', }, SIGNALING: { diff --git a/app/script/media/MediaStreamHandler.js b/app/script/media/MediaStreamHandler.js index 6c102eb0153..59a284376fc 100644 --- a/app/script/media/MediaStreamHandler.js +++ b/app/script/media/MediaStreamHandler.js @@ -103,7 +103,7 @@ z.media.MediaStreamHandler = class MediaStreamHandler { this.request_hint_timeout = undefined; amplify.subscribe(z.event.WebApp.CALL.MEDIA.ADD_STREAM, this.addRemoteMediaStream.bind(this)); - amplify.subscribe(z.event.WebApp.CALL.MEDIA.REMOVE_STREAM, this.removeRemoteMediaStreams.bind(this)); + amplify.subscribe(z.event.WebApp.CALL.MEDIA.CONNECTION_CLOSED, this.removeRemoteMediaStreamTracks.bind(this)); } //############################################################################## @@ -525,10 +525,27 @@ z.media.MediaStreamHandler = class MediaStreamHandler { this.element_handler.add_media_element(mediaStreamInfo); } - removeRemoteMediaStreams(streams) { - const streamIds = streams.map(stream => stream.id); - this.remote_media_streams.video.remove(stream => streamIds.includes(stream.id)); - this.remote_media_streams.audio.remove(stream => streamIds.includes(stream.id)); + /** + * Removes the given tracks from the streams containing them. + * If a stream ends up having no tracks, it gets filtered out from the array of streams + * removeRemoteMediaStreamTracks + * + * @param {MediaStreamTrack[]} remoteTracks - the tracks to remove + * @returns {void} - void + */ + removeRemoteMediaStreamTracks(remoteTracks) { + const removeTracks = (streams, tracks) => { + return streams + .map(stream => { + tracks.forEach(track => stream.removeTrack(track)); + return stream; + }) + .filter(stream => stream.getTracks().length > 0); + }; + + [this.remote_media_streams.video, this.remote_media_streams.audio].forEach(streams => { + streams(removeTracks(streams(), remoteTracks)); + }); } //##############################################################################