[FIX] mail: prevents frozen video elements

Before this commit, when a video track ended unexpectedly, the peers
were not notified that the remote track ended, which made it so that
inactive video elements remained on screen.

This commit fixes this issue.

closes odoo/odoo#77875

X-original-commit: d868582b2b409ec01bc4983429dea723f27f5513
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Thanh Dodeur
2021-10-05 15:41:38 +00:00
parent 92d4987acb
commit 023eee86f4
2 changed files with 23 additions and 25 deletions
+21 -19
View File
@@ -652,7 +652,14 @@ function factory(dependencies) {
});
}
if (type === 'video' && isSendingVideo === false) {
rtcSession.removeVideo({ stopTracks: false });
/**
* Since WebRTC "unified plan", the local track is tied to the
* remote transceiver.sender and not the remote track. Therefore
* when the remote track is 'ended' the local track is not 'ended'
* but only 'muted'. This is why we do not stop the local track
* until the peer is completely removed.
*/
rtcSession.update({ videoStream: clear() });
}
}
@@ -905,23 +912,9 @@ function factory(dependencies) {
for (const [token, peerConnection] of Object.entries(this._peerConnections)) {
await this._updateRemoteTrack(peerConnection, 'video', { token });
}
const isScreenSharingOn = !!this.sendDisplay;
const isCameraOn = !!this.sendUserVideo;
this.currentRtcSession.updateAndBroadcast({
isScreenSharingOn,
isCameraOn,
});
if (isScreenSharingOn || isCameraOn) {
// the peer already gets notified through RTC transaction.
return;
}
this._notifyPeers(Object.keys(this._peerConnections), {
event: 'trackChange',
type: 'peerToPeer',
payload: {
type: 'video',
state: { isSendingVideo: false },
},
isScreenSharingOn: !!this.sendDisplay,
isCameraOn: !!this.sendUserVideo,
});
}
@@ -973,7 +966,6 @@ function factory(dependencies) {
});
}
if (track.kind === 'video') {
rtcSession.removeVideo({ stopTracks: false });
rtcSession.update({
videoStream: stream,
});
@@ -1049,7 +1041,7 @@ function factory(dependencies) {
if (videoTrack) {
videoTrack.addEventListener('ended', async () => {
await this.async(() =>
this._toggleLocalVideoTrack({ force: false, type })
this._toggleVideoBroadcast({ force: false, type })
);
});
}
@@ -1105,6 +1097,16 @@ function factory(dependencies) {
} catch (e) {
// ignored, the transceiver is probably already removed
}
if (trackKind === 'video') {
this._notifyPeers([token], {
event: 'trackChange',
type: 'peerToPeer',
payload: {
type: 'video',
state: { isSendingVideo: false },
},
});
}
}
//----------------------------------------------------------------------
@@ -46,13 +46,9 @@ function factory(dependencies) {
/**
* cleanly removes the video stream of the session
*
* @param {Object} [param0]
* @param {Object} [param0.stopTracks] true if tracks have to be stopped,
* it is optional as tracks can be removed but still necessary for transceivers.
*/
removeVideo({ stopTracks = true } = {}) {
if (this.videoStream && stopTracks) {
removeVideo() {
if (this.videoStream) {
for (const track of this.videoStream.getTracks() || []) {
track.stop();
}