fix(webcams): handle Firefox video stream cleanup edge case

Firefox doesnt fire the ended evt/onended callback for live video mediastreamtracks. That caused the stream storage to not run the cleanup procedure in some scenarios

Manually emit the ended event which works with the onended callback when a track is stopped
This commit is contained in:
prlanzarin 2021-07-05 16:01:13 +00:00
parent 60dd10510c
commit d8dae1ec90
3 changed files with 15 additions and 2 deletions

View File

@ -52,6 +52,9 @@ const storeStream = (deviceId, stream) => {
const track = MediaStreamUtils.getVideoTracks(stream)[0];
if (track) {
track.addEventListener('ended', cleanup, { once: true });
// Extra safeguard: Firefox doesn't fire the 'ended' when it should
// but it invokes the callback (?), so hook up to both
track.onended = cleanup;
}
}

View File

@ -1,8 +1,12 @@
const stopMediaStreamTracks = (stream) => {
if (stream && typeof stream.getTracks === 'function') {
stream.getTracks().forEach(track => {
if (typeof track.stop === 'function') {
if (typeof track.stop === 'function' && track.readyState !== 'ended') {
track.stop();
// Manually emit the event as a safeguard; Firefox doesn't fire it when it
// should with live MediaStreamTracks...
const trackStoppedEvt = new MediaStreamTrackEvent('ended', { track });
track.dispatchEvent(trackStoppedEvt);
}
});
}

View File

@ -38,7 +38,13 @@ function noop(error) {
logger.error(error);
}
function trackStop(track) {
track && track.stop && track.stop();
if (track && typeof track.stop === 'function' && track.readyState !== 'ended') {
track.stop();
// Manually emit the event as a safeguard; Firefox doesn't fire it when it
// should with live MediaStreamTracks...
const trackStoppedEvt = new MediaStreamTrackEvent('ended', { track });
track.dispatchEvent(trackStoppedEvt);
}
}
function streamStop(stream) {
let track = stream.track;