From 7d216f650c32b142f53f8076a8472def7ea37731 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Sun, 17 Jan 2021 20:20:35 +0100 Subject: [PATCH] Add replace parameter to onclose stream callback. This indicates that the stream is being replaced by another one with the same id. This avoids moving videos around when they are being renegotiated. --- static/galene.js | 45 ++++++++++++++++++++++++++++----------------- static/protocol.js | 16 +++++++++------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/static/galene.js b/static/galene.js index 5b6dc9e..1566597 100644 --- a/static/galene.js +++ b/static/galene.js @@ -320,8 +320,9 @@ function gotClose(code, reason) { * @param {Stream} c */ function gotDownStream(c) { - c.onclose = function() { - delMedia(c.id); + c.onclose = function(replace) { + if(!replace) + delMedia(c.id); }; c.onerror = function(e) { console.error(e); @@ -1013,11 +1014,16 @@ async function addLocalMedia(id) { } let old = id && serverConnection.up[id]; - if(old) - old.close(); - - if(!audio && !video) + if(!audio && !video) { + if(old) + old.close(); return; + } + + if(old && old.onclose) { + // make sure that the camera is released before we try to reopen it + old.onclose.call(old, true); + } let constraints = {audio: audio, video: video}; /** @type {MediaStream} */ @@ -1040,22 +1046,25 @@ async function addLocalMedia(id) { try { let f = new Filter(stream, filter); setFilter(c, f); - c.onclose = () => { + c.onclose = replace => { stopStream(stream); setFilter(c, null); - delMedia(c.id); + if(!replace) + delMedia(c.id); } } catch(e) { displayWarning(e); - c.onclose = () => { + c.onclose = replace => { stopStream(c.stream); - delMedia(c.id); + if(!replace) + delMedia(c.id); } } } else { - c.onclose = () => { + c.onclose = replace => { stopStream(c.stream); - delMedia(c.id); + if(!replace) + delMedia(c.id); } } @@ -1106,9 +1115,10 @@ async function addShareMedia() { let c = newUpStream(); c.kind = 'screenshare'; c.stream = stream; - c.onclose = () => { + c.onclose = replace => { stopStream(stream); - delMedia(c.id); + if(!replace) + delMedia(c.id); } stream.getTracks().forEach(t => { c.pc.addTrack(t, stream); @@ -1141,7 +1151,7 @@ async function addFileMedia(file) { let c = newUpStream(); c.kind = 'video'; c.stream = stream; - c.onclose = function() { + c.onclose = function(replace) { stopStream(c.stream); let media = /** @type{HTMLVideoElement} */ (document.getElementById('media-' + this.id)); @@ -1149,8 +1159,9 @@ async function addFileMedia(file) { URL.revokeObjectURL(media.src); media.src = null; } - delMedia(c.id); - } + if(!replace) + delMedia(c.id); + }; stream.onaddtrack = function(e) { let t = e.track; diff --git a/static/protocol.js b/static/protocol.js index 19b914c..5849c48 100644 --- a/static/protocol.js +++ b/static/protocol.js @@ -634,7 +634,7 @@ ServerConnection.prototype.gotAnswer = async function(id, sdp) { if(c.onerror) c.onerror.call(c, e); } finally { - c.close(true); + c.close(); } return; } @@ -825,9 +825,10 @@ function Stream(sc, id, pc, up) { /* Callbacks */ /** - * onclose is called when the stream is closed. + * onclose is called when the stream is closed. Replace will be true + * if the stream is being replaced by another one with the same id. * - * @type{(this: Stream) => void} + * @type{(this: Stream, replace: boolean) => void} */ this.onclose = null; /** @@ -880,9 +881,10 @@ function Stream(sc, id, pc, up) { * streams in the down direction, this will be called automatically when * the server signals that it is closing a stream. * - * @param {boolean} [nocallback] + * @param {boolean} [replace] + * - true if the stream is being replaced by another one with the same id */ -Stream.prototype.close = function(nocallback) { +Stream.prototype.close = function(replace) { let c = this; if(!c.sc) { @@ -920,8 +922,8 @@ Stream.prototype.close = function(nocallback) { } c.sc = null; - if(!nocallback && c.onclose) - c.onclose.call(c); + if(c.onclose) + c.onclose.call(c, replace); }; /**