|
|
|
@ -61,11 +61,19 @@ var VideoLayout = (function (my) { |
|
|
|
|
var localVideoSelector = $('#' + localVideo.id); |
|
|
|
|
// Add click handler to both video and video wrapper elements in case
|
|
|
|
|
// there's no video.
|
|
|
|
|
localVideoSelector.click(function () { |
|
|
|
|
VideoLayout.handleVideoThumbClicked(RTC.getVideoSrc(localVideo), false, connection.emuc.myroomjid); |
|
|
|
|
localVideoSelector.click(function (event) { |
|
|
|
|
event.stopPropagation(); |
|
|
|
|
VideoLayout.handleVideoThumbClicked( |
|
|
|
|
RTC.getVideoSrc(localVideo), |
|
|
|
|
false, |
|
|
|
|
Strophe.getResourceFromJid(connection.emuc.myroomjid)); |
|
|
|
|
}); |
|
|
|
|
$('#localVideoContainer').click(function () { |
|
|
|
|
VideoLayout.handleVideoThumbClicked(RTC.getVideoSrc(localVideo), false, connection.emuc.myroomjid); |
|
|
|
|
$('#localVideoContainer').click(function (event) { |
|
|
|
|
event.stopPropagation(); |
|
|
|
|
VideoLayout.handleVideoThumbClicked( |
|
|
|
|
RTC.getVideoSrc(localVideo), |
|
|
|
|
false, |
|
|
|
|
Strophe.getResourceFromJid(connection.emuc.myroomjid)); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Add hover handler
|
|
|
|
@ -155,15 +163,15 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
my.getLargeVideoState = function () { |
|
|
|
|
return largeVideoState; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Updates the large video with the given new video source. |
|
|
|
|
*/ |
|
|
|
|
my.updateLargeVideo = function(newSrc, vol, jid) { |
|
|
|
|
my.updateLargeVideo = function(newSrc, vol, resourceJid) { |
|
|
|
|
console.log('hover in', newSrc); |
|
|
|
|
|
|
|
|
|
if (RTC.getVideoSrc($('#largeVideo')[0]) != newSrc) { |
|
|
|
|
if (RTC.getVideoSrc($('#largeVideo')[0]) !== newSrc) { |
|
|
|
|
|
|
|
|
|
$('#activeSpeakerAvatar').css('visibility', 'hidden'); |
|
|
|
|
// Due to the simulcast the localVideoSrc may have changed when the
|
|
|
|
@ -176,28 +184,26 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
largeVideoState.newSrc = newSrc; |
|
|
|
|
largeVideoState.isVisible = $('#largeVideo').is(':visible'); |
|
|
|
|
largeVideoState.isDesktop = isVideoSrcDesktop(jid); |
|
|
|
|
if(jid2Ssrc[largeVideoState.userJid] || |
|
|
|
|
largeVideoState.isDesktop = isVideoSrcDesktop(resourceJid); |
|
|
|
|
if(jid2Ssrc[largeVideoState.userResourceJid] || |
|
|
|
|
(connection && connection.emuc.myroomjid && |
|
|
|
|
largeVideoState.userJid == Strophe.getResourceFromJid(connection.emuc.myroomjid))) |
|
|
|
|
{ |
|
|
|
|
largeVideoState.oldJid = largeVideoState.userJid; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
largeVideoState.oldJid = null; |
|
|
|
|
largeVideoState.userResourceJid === |
|
|
|
|
Strophe.getResourceFromJid(connection.emuc.myroomjid))) { |
|
|
|
|
largeVideoState.oldResourceJid = largeVideoState.userResourceJid; |
|
|
|
|
} else { |
|
|
|
|
largeVideoState.oldResourceJid = null; |
|
|
|
|
} |
|
|
|
|
largeVideoState.userJid = jid; |
|
|
|
|
largeVideoState.userResourceJid = resourceJid; |
|
|
|
|
|
|
|
|
|
// Screen stream is already rotated
|
|
|
|
|
largeVideoState.flipX = (newSrc === localVideoSrc) && flipXLocalVideo; |
|
|
|
|
|
|
|
|
|
var userChanged = false; |
|
|
|
|
if (largeVideoState.oldJid != largeVideoState.userJid) { |
|
|
|
|
if (largeVideoState.oldResourceJid !== largeVideoState.userResourceJid) { |
|
|
|
|
userChanged = true; |
|
|
|
|
// we want the notification to trigger even if userJid is undefined,
|
|
|
|
|
// or null.
|
|
|
|
|
$(document).trigger("selectedendpointchanged", [largeVideoState.userJid]); |
|
|
|
|
$(document).trigger("selectedendpointchanged", [largeVideoState.userResourceJid]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!largeVideoState.updateInProgress) { |
|
|
|
@ -205,11 +211,13 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
var doUpdate = function () { |
|
|
|
|
|
|
|
|
|
Avatar.updateActiveSpeakerAvatarSrc(largeVideoState.userJid); |
|
|
|
|
Avatar.updateActiveSpeakerAvatarSrc( |
|
|
|
|
connection.emuc.findJidFromResource( |
|
|
|
|
largeVideoState.userResourceJid)); |
|
|
|
|
|
|
|
|
|
if (!userChanged && largeVideoState.preload |
|
|
|
|
&& largeVideoState.preload != null |
|
|
|
|
&& RTC.getVideoSrc($(largeVideoState.preload)[0]) == newSrc) |
|
|
|
|
if (!userChanged && largeVideoState.preload && |
|
|
|
|
largeVideoState.preload !== null && |
|
|
|
|
RTC.getVideoSrc($(largeVideoState.preload)[0]) === newSrc) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
console.info('Switching to preloaded video'); |
|
|
|
@ -218,7 +226,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
// loop through largeVideo attributes and apply them on
|
|
|
|
|
// preload.
|
|
|
|
|
$.each(attributes, function () { |
|
|
|
|
if (this.name != 'id' && this.name != 'src') { |
|
|
|
|
if (this.name !== 'id' && this.name !== 'src') { |
|
|
|
|
largeVideoState.preload.attr(this.name, this.value); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
@ -263,13 +271,17 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
// Only if the large video is currently visible.
|
|
|
|
|
// Disable previous dominant speaker video.
|
|
|
|
|
if (largeVideoState.oldJid) { |
|
|
|
|
VideoLayout.enableDominantSpeaker(largeVideoState.oldJid, false); |
|
|
|
|
if (largeVideoState.oldResourceJid) { |
|
|
|
|
VideoLayout.enableDominantSpeaker( |
|
|
|
|
largeVideoState.oldResourceJid, |
|
|
|
|
false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Enable new dominant speaker in the remote videos section.
|
|
|
|
|
if (largeVideoState.userJid) { |
|
|
|
|
VideoLayout.enableDominantSpeaker(largeVideoState.userJid, true); |
|
|
|
|
if (largeVideoState.userResourceJid) { |
|
|
|
|
VideoLayout.enableDominantSpeaker( |
|
|
|
|
largeVideoState.userResourceJid, |
|
|
|
|
true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (userChanged && largeVideoState.isVisible) { |
|
|
|
@ -279,7 +291,9 @@ var VideoLayout = (function (my) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(userChanged) { |
|
|
|
|
Avatar.showUserAvatar(largeVideoState.oldJid); |
|
|
|
|
Avatar.showUserAvatar( |
|
|
|
|
connection.emuc.findJidFromResource( |
|
|
|
|
largeVideoState.oldResourceJid)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
largeVideoState.updateInProgress = false; |
|
|
|
@ -291,15 +305,21 @@ var VideoLayout = (function (my) { |
|
|
|
|
doUpdate(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
Avatar.showUserAvatar( |
|
|
|
|
connection.emuc.findJidFromResource( |
|
|
|
|
largeVideoState.userResourceJid)); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
my.handleVideoThumbClicked = function(videoSrc, noPinnedEndpointChangedEvent, jid) { |
|
|
|
|
my.handleVideoThumbClicked = function(videoSrc, |
|
|
|
|
noPinnedEndpointChangedEvent,
|
|
|
|
|
resourceJid) { |
|
|
|
|
// Restore style for previously focused video
|
|
|
|
|
var oldContainer = null; |
|
|
|
|
if(focusedVideoSrc) { |
|
|
|
|
var focusJid = focusedVideoSrc.jid; |
|
|
|
|
oldContainer = getParticipantContainer(focusJid); |
|
|
|
|
if(focusedVideoInfo) { |
|
|
|
|
var focusResourceJid = focusedVideoInfo.resouceJid; |
|
|
|
|
oldContainer = getParticipantContainer(focusResourceJid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (oldContainer) { |
|
|
|
@ -307,9 +327,9 @@ var VideoLayout = (function (my) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Unlock current focused.
|
|
|
|
|
if (focusedVideoSrc && focusedVideoSrc.src === videoSrc) |
|
|
|
|
if (focusedVideoInfo && focusedVideoInfo.src === videoSrc) |
|
|
|
|
{ |
|
|
|
|
focusedVideoSrc = null; |
|
|
|
|
focusedVideoInfo = null; |
|
|
|
|
var dominantSpeakerVideo = null; |
|
|
|
|
// Enable the currently set dominant speaker.
|
|
|
|
|
if (currentDominantSpeaker) { |
|
|
|
@ -318,7 +338,10 @@ var VideoLayout = (function (my) { |
|
|
|
|
.get(0); |
|
|
|
|
|
|
|
|
|
if (dominantSpeakerVideo) { |
|
|
|
|
VideoLayout.updateLargeVideo(RTC.getVideoSrc(dominantSpeakerVideo), 1, currentDominantSpeaker); |
|
|
|
|
VideoLayout.updateLargeVideo( |
|
|
|
|
RTC.getVideoSrc(dominantSpeakerVideo), |
|
|
|
|
1, |
|
|
|
|
currentDominantSpeaker); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -329,23 +352,23 @@ var VideoLayout = (function (my) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Lock new video
|
|
|
|
|
focusedVideoSrc = { |
|
|
|
|
focusedVideoInfo = { |
|
|
|
|
src: videoSrc, |
|
|
|
|
jid: jid |
|
|
|
|
resouceJid: resourceJid |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Update focused/pinned interface.
|
|
|
|
|
if (jid) |
|
|
|
|
if (resourceJid) |
|
|
|
|
{ |
|
|
|
|
var container = getParticipantContainer(jid); |
|
|
|
|
var container = getParticipantContainer(resourceJid); |
|
|
|
|
container.addClass("videoContainerFocused"); |
|
|
|
|
|
|
|
|
|
if (!noPinnedEndpointChangedEvent) { |
|
|
|
|
$(document).trigger("pinnedendpointchanged", [jid]); |
|
|
|
|
$(document).trigger("pinnedendpointchanged", [resourceJid]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($('#largeVideo').attr('src') == videoSrc) { |
|
|
|
|
if ($('#largeVideo').attr('src') === videoSrc) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -353,7 +376,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
// this isn't a prezi.
|
|
|
|
|
$(document).trigger("video.selected", [false]); |
|
|
|
|
|
|
|
|
|
VideoLayout.updateLargeVideo(videoSrc, 1, Strophe.getResourceFromJid(jid)); |
|
|
|
|
VideoLayout.updateLargeVideo(videoSrc, 1, resourceJid); |
|
|
|
|
|
|
|
|
|
$('audio').each(function (idx, el) { |
|
|
|
|
if (el.id.indexOf('mixedmslabel') !== -1) { |
|
|
|
@ -399,7 +422,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
* Shows/hides the large video. |
|
|
|
|
*/ |
|
|
|
|
my.setLargeVideoVisible = function(isVisible) { |
|
|
|
|
var resourceJid = largeVideoState.userJid; |
|
|
|
|
var resourceJid = largeVideoState.userResourceJid; |
|
|
|
|
|
|
|
|
|
if (isVisible) { |
|
|
|
|
$('#largeVideo').css({visibility: 'visible'}); |
|
|
|
@ -410,6 +433,16 @@ var VideoLayout = (function (my) { |
|
|
|
|
$('#largeVideo').css({visibility: 'hidden'}); |
|
|
|
|
$('.watermark').css({visibility: 'hidden'}); |
|
|
|
|
VideoLayout.enableDominantSpeaker(resourceJid, false); |
|
|
|
|
var focusJid = VideoLayout.getLargeVideoState().userJid; |
|
|
|
|
var oldContainer = getParticipantContainer(focusJid); |
|
|
|
|
|
|
|
|
|
if (oldContainer) { |
|
|
|
|
oldContainer.removeClass("videoContainerFocused"); |
|
|
|
|
} |
|
|
|
|
focusedVideoInfo = null; |
|
|
|
|
if(focusJid) { |
|
|
|
|
Avatar.showUserAvatar(focusJid); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -565,7 +598,10 @@ var VideoLayout = (function (my) { |
|
|
|
|
var videoThumb = $('#' + container.id + '>video').get(0); |
|
|
|
|
|
|
|
|
|
if (videoThumb) |
|
|
|
|
VideoLayout.handleVideoThumbClicked(RTC.getVideoSrc(videoThumb), false, peerJid); |
|
|
|
|
VideoLayout.handleVideoThumbClicked( |
|
|
|
|
RTC.getVideoSrc(videoThumb), |
|
|
|
|
false, |
|
|
|
|
Strophe.getResourceFromJid(peerJid)); |
|
|
|
|
|
|
|
|
|
event.preventDefault(); |
|
|
|
|
return false; |
|
|
|
@ -1083,17 +1119,17 @@ var VideoLayout = (function (my) { |
|
|
|
|
/** |
|
|
|
|
* Gets the selector of video thumbnail container for the user identified by |
|
|
|
|
* given <tt>userJid</tt> |
|
|
|
|
* @param userJid user's Jid for whom we want to get the video container. |
|
|
|
|
* @param resourceJid user's Jid for whom we want to get the video container. |
|
|
|
|
*/ |
|
|
|
|
function getParticipantContainer(userJid) |
|
|
|
|
function getParticipantContainer(resourceJid) |
|
|
|
|
{ |
|
|
|
|
if (!userJid) |
|
|
|
|
if (!resourceJid) |
|
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
if (userJid === connection.emuc.myroomjid) |
|
|
|
|
if (resourceJid === Strophe.getResourceFromJid(connection.emuc.myroomjid)) |
|
|
|
|
return $("#localVideoContainer"); |
|
|
|
|
else |
|
|
|
|
return $("#participant_" + Strophe.getResourceFromJid(userJid)); |
|
|
|
|
return $("#participant_" + resourceJid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -1372,7 +1408,10 @@ var VideoLayout = (function (my) { |
|
|
|
|
// We have a video src, great! Let's update the large video
|
|
|
|
|
// now.
|
|
|
|
|
|
|
|
|
|
VideoLayout.handleVideoThumbClicked(videoThumb.src, false, jid); |
|
|
|
|
VideoLayout.handleVideoThumbClicked( |
|
|
|
|
videoThumb.src, |
|
|
|
|
false, |
|
|
|
|
Strophe.getResourceFromJid(jid)); |
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
// If we don't have a video src for jid, there's absolutely
|
|
|
|
@ -1501,7 +1540,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
// Local video will not have container found, but that's ok
|
|
|
|
|
// since we don't want to switch to local video.
|
|
|
|
|
if (container && !focusedVideoSrc) |
|
|
|
|
if (container && !focusedVideoInfo) |
|
|
|
|
{ |
|
|
|
|
var video = container.getElementsByTagName("video"); |
|
|
|
|
|
|
|
|
@ -1587,7 +1626,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
// it is no longer being received. If resourceJid was being
|
|
|
|
|
// displayed in the large video we have to switch to another
|
|
|
|
|
// user.
|
|
|
|
|
var largeVideoResource = largeVideoState.userJid; |
|
|
|
|
var largeVideoResource = largeVideoState.userResourceJid; |
|
|
|
|
if (!updateLargeVideo && resourceJid === largeVideoResource) { |
|
|
|
|
updateLargeVideo = true; |
|
|
|
|
} |
|
|
|
@ -1618,7 +1657,10 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
// Don't fire the events again, they've already
|
|
|
|
|
// been fired in the contact list click handler.
|
|
|
|
|
VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false, mediaStream.peerjid); |
|
|
|
|
VideoLayout.handleVideoThumbClicked( |
|
|
|
|
$(sel).attr('src'), |
|
|
|
|
false, |
|
|
|
|
Strophe.getResourceFromJid(mediaStream.peerjid)); |
|
|
|
|
|
|
|
|
|
updateLargeVideo = false; |
|
|
|
|
} |
|
|
|
@ -1675,11 +1717,14 @@ var VideoLayout = (function (my) { |
|
|
|
|
// Update the large video to the last added video only if there's no
|
|
|
|
|
// current dominant or focused speaker or update it to the current
|
|
|
|
|
// dominant speaker.
|
|
|
|
|
if ((!focusedVideoSrc && !VideoLayout.getDominantSpeakerResourceJid()) |
|
|
|
|
if ((!focusedVideoInfo && !VideoLayout.getDominantSpeakerResourceJid()) |
|
|
|
|
|| (parentResourceJid |
|
|
|
|
&& VideoLayout.getDominantSpeakerResourceJid() |
|
|
|
|
=== parentResourceJid)) { |
|
|
|
|
VideoLayout.updateLargeVideo(RTC.getVideoSrc(videoelem[0]), 1, parentResourceJid); |
|
|
|
|
VideoLayout.updateLargeVideo( |
|
|
|
|
RTC.getVideoSrc(videoelem[0]), |
|
|
|
|
1, |
|
|
|
|
parentResourceJid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VideoLayout.showModeratorIndicator(); |
|
|
|
@ -1716,7 +1761,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
|
|
|
|
|
var msidParts = msid.split(' '); |
|
|
|
|
|
|
|
|
|
var preload = (Strophe.getResourceFromJid(ssrc2jid[primarySSRC]) == largeVideoState.userJid); |
|
|
|
|
var preload = (Strophe.getResourceFromJid(ssrc2jid[primarySSRC]) == largeVideoState.userResourceJid); |
|
|
|
|
|
|
|
|
|
if (preload) { |
|
|
|
|
if (largeVideoState.preload) |
|
|
|
@ -1777,9 +1822,9 @@ var VideoLayout = (function (my) { |
|
|
|
|
var selRemoteVideo = $(['#', 'remoteVideo_', session.sid, '_', msidParts[0]].join('')); |
|
|
|
|
|
|
|
|
|
var updateLargeVideo = (Strophe.getResourceFromJid(ssrc2jid[primarySSRC]) |
|
|
|
|
== largeVideoState.userJid); |
|
|
|
|
var updateFocusedVideoSrc = (focusedVideoSrc && focusedVideoSrc.src && focusedVideoSrc.src != '' && |
|
|
|
|
(RTC.getVideoSrc(selRemoteVideo[0]) == focusedVideoSrc.src)); |
|
|
|
|
== largeVideoState.userResourceJid); |
|
|
|
|
var updateFocusedVideoSrc = (focusedVideoInfo && focusedVideoInfo.src && focusedVideoInfo.src != '' && |
|
|
|
|
(RTC.getVideoSrc(selRemoteVideo[0]) == focusedVideoInfo.src)); |
|
|
|
|
|
|
|
|
|
var electedStreamUrl; |
|
|
|
|
if (largeVideoState.preload_ssrc == primarySSRC) |
|
|
|
@ -1807,7 +1852,7 @@ var VideoLayout = (function (my) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (updateFocusedVideoSrc) { |
|
|
|
|
focusedVideoSrc.src = RTC.getVideoSrc(selRemoteVideo[0]); |
|
|
|
|
focusedVideoInfo.src = RTC.getVideoSrc(selRemoteVideo[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var videoId; |
|
|
|
|