Takes advantage of the smart simulcast layer escalation of the bridge to prevent blackness when we switch to a higher order layer.
This commit is contained in:
parent
a55e3f5d9d
commit
fad08fdef0
|
@ -97,6 +97,11 @@ function onDataChannel(event)
|
||||||
var endpointSimulcastLayers = obj.endpointSimulcastLayers;
|
var endpointSimulcastLayers = obj.endpointSimulcastLayers;
|
||||||
$(document).trigger('simulcastlayerschanged', [endpointSimulcastLayers]);
|
$(document).trigger('simulcastlayerschanged', [endpointSimulcastLayers]);
|
||||||
}
|
}
|
||||||
|
else if ("SimulcastLayersChangingEvent" === colibriClass)
|
||||||
|
{
|
||||||
|
var endpointSimulcastLayers = obj.endpointSimulcastLayers;
|
||||||
|
$(document).trigger('simulcastlayerschanging', [endpointSimulcastLayers]);
|
||||||
|
}
|
||||||
else if ("StartSimulcastLayerEvent" === colibriClass)
|
else if ("StartSimulcastLayerEvent" === colibriClass)
|
||||||
{
|
{
|
||||||
var simulcastLayer = obj.simulcastLayer;
|
var simulcastLayer = obj.simulcastLayer;
|
||||||
|
|
130
videolayout.js
130
videolayout.js
|
@ -141,9 +141,9 @@ var VideoLayout = (function (my) {
|
||||||
var oldSrc = $('#largeVideo').attr('src');
|
var oldSrc = $('#largeVideo').attr('src');
|
||||||
largeVideoState.oldJid = getJidFromVideoSrc(oldSrc);
|
largeVideoState.oldJid = getJidFromVideoSrc(oldSrc);
|
||||||
|
|
||||||
var fade = false;
|
var userChanged = false;
|
||||||
if (largeVideoState.oldJid != largeVideoState.userJid) {
|
if (largeVideoState.oldJid != largeVideoState.userJid) {
|
||||||
fade = true;
|
userChanged = true;
|
||||||
// we want the notification to trigger even if userJid is undefined,
|
// we want the notification to trigger even if userJid is undefined,
|
||||||
// or null.
|
// or null.
|
||||||
$(document).trigger("selectedendpointchanged", [largeVideoState.userJid]);
|
$(document).trigger("selectedendpointchanged", [largeVideoState.userJid]);
|
||||||
|
@ -154,7 +154,41 @@ var VideoLayout = (function (my) {
|
||||||
|
|
||||||
var doUpdate = function () {
|
var doUpdate = function () {
|
||||||
|
|
||||||
$('#largeVideo').attr('src', largeVideoState.newSrc);
|
if (!userChanged && largeVideoState.preload
|
||||||
|
&& largeVideoState.preload != null
|
||||||
|
&& $(largeVideoState.preload).attr('src') == newSrc) {
|
||||||
|
|
||||||
|
console.info('Switching to preloaded video');
|
||||||
|
var attributes = $('#largeVideo').prop("attributes");
|
||||||
|
|
||||||
|
// loop through largeVideo attributes and apply them on
|
||||||
|
// preload.
|
||||||
|
$.each(attributes, function () {
|
||||||
|
if (this.name != 'id' && this.name != 'src') {
|
||||||
|
largeVideoState.preload.attr(this.name, this.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
largeVideoState.preload.appendTo($('#largeVideoContainer'));
|
||||||
|
$('#largeVideo').attr('id', 'previousLargeVideo');
|
||||||
|
largeVideoState.preload.attr('id', 'largeVideo');
|
||||||
|
$('#previousLargeVideo').remove();
|
||||||
|
|
||||||
|
largeVideoState.preload.on('loadedmetadata', function (e) {
|
||||||
|
currentVideoWidth = this.videoWidth;
|
||||||
|
currentVideoHeight = this.videoHeight;
|
||||||
|
VideoLayout.positionLarge(currentVideoWidth, currentVideoHeight);
|
||||||
|
});
|
||||||
|
largeVideoState.preload = null;
|
||||||
|
largeVideoState.preload_ssrc = 0;
|
||||||
|
} else {
|
||||||
|
if (largeVideoState.preload
|
||||||
|
&& largeVideoState.preload != null) {
|
||||||
|
$(largeVideoState.preload).remove();
|
||||||
|
largeVideoState.preload_ssrc = 0;
|
||||||
|
}
|
||||||
|
$('#largeVideo').attr('src', largeVideoState.newSrc);
|
||||||
|
}
|
||||||
|
|
||||||
var videoTransform = document.getElementById('largeVideo')
|
var videoTransform = document.getElementById('largeVideo')
|
||||||
.style.webkitTransform;
|
.style.webkitTransform;
|
||||||
|
@ -191,7 +225,7 @@ var VideoLayout = (function (my) {
|
||||||
VideoLayout.enableDominantSpeaker(resourceJid, true);
|
VideoLayout.enableDominantSpeaker(resourceJid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fade && largeVideoState.isVisible) {
|
if (userChanged && largeVideoState.isVisible) {
|
||||||
// using "this" should be ok because we're called
|
// using "this" should be ok because we're called
|
||||||
// from within the fadeOut event.
|
// from within the fadeOut event.
|
||||||
$(this).fadeIn(300);
|
$(this).fadeIn(300);
|
||||||
|
@ -200,7 +234,7 @@ var VideoLayout = (function (my) {
|
||||||
largeVideoState.updateInProgress = false;
|
largeVideoState.updateInProgress = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fade) {
|
if (userChanged) {
|
||||||
$('#largeVideo').fadeOut(300, doUpdate);
|
$('#largeVideo').fadeOut(300, doUpdate);
|
||||||
} else {
|
} else {
|
||||||
doUpdate();
|
doUpdate();
|
||||||
|
@ -1388,6 +1422,81 @@ var VideoLayout = (function (my) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).bind('simulcastlayerschanging', function (event, endpointSimulcastLayers) {
|
||||||
|
endpointSimulcastLayers.forEach(function (esl) {
|
||||||
|
var primarySSRC = esl.simulcastLayer.primarySSRC;
|
||||||
|
var msid = simulcast.getRemoteVideoStreamIdBySSRC(primarySSRC);
|
||||||
|
|
||||||
|
// Get session and stream from msid.
|
||||||
|
var session, electedStream;
|
||||||
|
var i, j, k;
|
||||||
|
if (connection.jingle) {
|
||||||
|
var keys = Object.keys(connection.jingle.sessions);
|
||||||
|
for (i = 0; i < keys.length; i++) {
|
||||||
|
var sid = keys[i];
|
||||||
|
|
||||||
|
if (electedStream) {
|
||||||
|
// stream found, stop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
session = connection.jingle.sessions[sid];
|
||||||
|
if (session.remoteStreams) {
|
||||||
|
for (j = 0; j < session.remoteStreams.length; j++) {
|
||||||
|
var remoteStream = session.remoteStreams[j];
|
||||||
|
|
||||||
|
if (electedStream) {
|
||||||
|
// stream found, stop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var tracks = remoteStream.getVideoTracks();
|
||||||
|
if (tracks) {
|
||||||
|
for (k = 0; k < tracks.length; k++) {
|
||||||
|
var track = tracks[k];
|
||||||
|
|
||||||
|
if (msid === [remoteStream.id, track.id].join(' ')) {
|
||||||
|
electedStream = new webkitMediaStream([track]);
|
||||||
|
// stream found, stop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session && electedStream) {
|
||||||
|
console.info('Switching simulcast substream.');
|
||||||
|
console.info([esl, primarySSRC, msid, session, electedStream]);
|
||||||
|
|
||||||
|
var msidParts = msid.split(' ');
|
||||||
|
var selRemoteVideo = $(['#', 'remoteVideo_', session.sid, '_', msidParts[0]].join(''));
|
||||||
|
|
||||||
|
var preload = (ssrc2jid[videoSrcToSsrc[selRemoteVideo.attr('src')]]
|
||||||
|
== ssrc2jid[videoSrcToSsrc[largeVideoState.newSrc]]);
|
||||||
|
|
||||||
|
if (preload) {
|
||||||
|
if (largeVideoState.preload)
|
||||||
|
{
|
||||||
|
$(largeVideoState.preload).remove();
|
||||||
|
}
|
||||||
|
console.info('Preloading remote video');
|
||||||
|
largeVideoState.preload = $('<video autoplay></video>');
|
||||||
|
// ssrcs are unique in an rtp session
|
||||||
|
largeVideoState.preload_ssrc = primarySSRC;
|
||||||
|
|
||||||
|
var electedStreamUrl = webkitURL.createObjectURL(electedStream);
|
||||||
|
largeVideoState.preload
|
||||||
|
.attr('src', electedStreamUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('Could not find a stream or a session.', session, electedStream);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On simulcast layers changed event.
|
* On simulcast layers changed event.
|
||||||
*/
|
*/
|
||||||
|
@ -1447,7 +1556,16 @@ var VideoLayout = (function (my) {
|
||||||
== ssrc2jid[videoSrcToSsrc[largeVideoState.newSrc]]);
|
== ssrc2jid[videoSrcToSsrc[largeVideoState.newSrc]]);
|
||||||
var updateFocusedVideoSrc = (selRemoteVideo.attr('src') == focusedVideoSrc);
|
var updateFocusedVideoSrc = (selRemoteVideo.attr('src') == focusedVideoSrc);
|
||||||
|
|
||||||
var electedStreamUrl = webkitURL.createObjectURL(electedStream);
|
var electedStreamUrl;
|
||||||
|
if (largeVideoState.preload_ssrc == primarySSRC)
|
||||||
|
{
|
||||||
|
electedStreamUrl = $(largeVideoState.preload).attr('src');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
electedStreamUrl = webkitURL.createObjectURL(electedStream);
|
||||||
|
}
|
||||||
|
|
||||||
selRemoteVideo.attr('src', electedStreamUrl);
|
selRemoteVideo.attr('src', electedStreamUrl);
|
||||||
videoSrcToSsrc[selRemoteVideo.attr('src')] = primarySSRC;
|
videoSrcToSsrc[selRemoteVideo.attr('src')] = primarySSRC;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue