From 46766ec239cac30ecca07807250ac8e23ee2cc6e Mon Sep 17 00:00:00 2001 From: paweldomas Date: Thu, 22 Sep 2016 16:21:01 -0500 Subject: [PATCH] fix(RemoteVideo): avoid black thumbnail When the user is having connectivity issues we use the image cached in the video element to show the preview in greyscale. It looks like this cached image gets invalided after prolonged periods of time the video element being hidden(and it is hidden when the video is muted). So we never show this image if the user gets muted during connectivity disruption in order to avoid blackness. --- modules/UI/videolayout/RemoteVideo.js | 51 +++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/modules/UI/videolayout/RemoteVideo.js b/modules/UI/videolayout/RemoteVideo.js index 05750f045..da9fc9693 100644 --- a/modules/UI/videolayout/RemoteVideo.js +++ b/modules/UI/videolayout/RemoteVideo.js @@ -37,6 +37,16 @@ function RemoteVideo(user, VideoLayout, emitter) { * @type {boolean} */ this.wasVideoPlayed = false; + /** + * The flag is set to true if remote participant's video gets muted + * during his media connection disruption. This is to prevent black video + * being render on the thumbnail, because even though once the video has + * been played the image usually remains on the video element it seems that + * after longer period of the video element being hidden this image can be + * lost. + * @type {boolean} + */ + this.mutedWhileDisconnected = false; } RemoteVideo.prototype = Object.create(SmallVideo.prototype); @@ -179,6 +189,33 @@ RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted, force) { } }; +/** + * @inheritDoc + */ +RemoteVideo.prototype.setMutedView = function(isMuted) { + SmallVideo.prototype.setMutedView.call(this, isMuted); + // Update 'mutedWhileDisconnected' flag + this._figureOutMutedWhileDisconnected(this.isConnectionActive() === false); +} + +/** + * Figures out the value of {@link #mutedWhileDisconnected} flag by taking into + * account remote participant's network connectivity and video muted status. + * + * @param {boolean} isDisconnected true if the remote participant is + * currently having connectivity issues or false otherwise. + * + * @private + */ +RemoteVideo.prototype._figureOutMutedWhileDisconnected += function(isDisconnected) { + if (isDisconnected && this.isVideoMuted) { + this.mutedWhileDisconnected = true; + } else if (!isDisconnected && !this.isVideoMuted) { + this.mutedWhileDisconnected = false; + } +} + /** * Adds the remote video menu element for the given id in the * given parentElement. @@ -237,6 +274,9 @@ RemoteVideo.prototype.removeRemoteStreamElement = function (stream) { // update the stage if (isVideo && this.isCurrentlyOnLargeVideo()) this.VideoLayout.updateLargeVideo(this.id); + else + // Missing video stream will affect display mode + this.updateView(); }; /** @@ -259,16 +299,20 @@ RemoteVideo.prototype.isConnectionActive = function() { */ RemoteVideo.prototype.isVideoPlayable = function () { return SmallVideo.prototype.isVideoPlayable.call(this) - && this.hasVideoStarted(); + && this.hasVideoStarted() && !this.mutedWhileDisconnected; }; /** * @inheritDoc */ RemoteVideo.prototype.updateView = function () { - SmallVideo.prototype.updateView.call(this); + this.updateConnectionStatusIndicator( null /* will obtain the status from 'conference' */); + + // This must be called after 'updateConnectionStatusIndicator' because it + // affects the display mode by modifying 'mutedWhileDisconnected' flag + SmallVideo.prototype.updateView.call(this); }; /** @@ -290,6 +334,9 @@ RemoteVideo.prototype.updateConnectionStatusIndicator = function (isActive) { console.debug(this.id + " thumbnail is connection active ? " + isActive); + // Update 'mutedWhileDisconnected' flag + this._figureOutMutedWhileDisconnected(!isActive); + if(this.connectionIndicator) this.connectionIndicator.updateConnectionStatusIndicator(isActive);