Make it possible to pin a participant from the contact list, even if he's not in the lastN set.
This commit is contained in:
parent
71e290a8ad
commit
7da0fd6794
19
app.js
19
app.js
|
@ -238,6 +238,25 @@ function doJoin() {
|
|||
}
|
||||
|
||||
function waitForRemoteVideo(selector, ssrc, stream) {
|
||||
|
||||
// XXX(gp) so, every call to this function is *always* preceded by a call
|
||||
// to the RTC.attachMediaStream() function but that call is *not* followed
|
||||
// by an update to the videoSrcToSsrc map!
|
||||
//
|
||||
// The above way of doing things results in video SRCs that don't correspond
|
||||
// to any SSRC for a short period of time (to be more precise, for as long
|
||||
// the waitForRemoteVideo takes to complete). This causes problems (see
|
||||
// bellow).
|
||||
//
|
||||
// I'm wondering why we need to do that; i.e. why call RTC.attachMediaStream()
|
||||
// a second time in here and only then update the videoSrcToSsrc map? Why
|
||||
// not simply update the videoSrcToSsrc map when the RTC.attachMediaStream()
|
||||
// is called the first time? I actually do that in the lastN changed event
|
||||
// handler because the "orphan" video SRC is causing troubles there. The
|
||||
// purpose of this method would then be to fire the "videoactive.jingle".
|
||||
//
|
||||
// Food for though I guess :-)
|
||||
|
||||
if (selector.removed || !selector.parent().is(":visible")) {
|
||||
console.warn("Media removed before had started", selector);
|
||||
return;
|
||||
|
|
|
@ -41,17 +41,13 @@ var ContactList = (function (my) {
|
|||
var contactlist = $('#contactlist>ul');
|
||||
|
||||
var newContact = document.createElement('li');
|
||||
// XXX(gp) contact click event handling is now in videolayout.js. Is the
|
||||
// following statement (newContact.id = resourceJid) still relevant?
|
||||
newContact.id = resourceJid;
|
||||
newContact.className = "clickable";
|
||||
newContact.onclick = function(event) {
|
||||
if(event.currentTarget.className === "clickable") {
|
||||
var jid = event.currentTarget.id;
|
||||
var videoContainer = $("#participant_" + jid);
|
||||
if (videoContainer.length > 0) {
|
||||
videoContainer.click();
|
||||
} else if (jid == Strophe.getResourceFromJid(connection.emuc.myroomjid)) {
|
||||
$("#localVideoContainer").click();
|
||||
}
|
||||
$(ContactList).trigger('contactclicked', [peerJid]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<script src="app.js?v=20"></script><!-- application logic -->
|
||||
<script src="commands.js?v=1"></script><!-- application logic -->
|
||||
<script src="chat.js?v=14"></script><!-- chat logic -->
|
||||
<script src="contact_list.js?v=5"></script><!-- contact list logic -->
|
||||
<script src="contact_list.js?v=6"></script><!-- contact list logic -->
|
||||
<script src="util.js?v=6"></script><!-- utility functions -->
|
||||
<script src="etherpad.js?v=9"></script><!-- etherpad plugin -->
|
||||
<script src="prezi.js?v=6"></script><!-- prezi plugin -->
|
||||
|
@ -47,7 +47,7 @@
|
|||
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
||||
<script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
|
||||
<script src="local_sts.js?v=2"></script><!-- Local stats processing -->
|
||||
<script src="videolayout.js?v=27"></script><!-- video ui -->
|
||||
<script src="videolayout.js?v=28"></script><!-- video ui -->
|
||||
<script src="connectionquality.js?v=1"></script>
|
||||
<script src="toolbar.js?v=6"></script><!-- toolbar ui -->
|
||||
<script src="toolbar_toggler.js?v=2"></script>
|
||||
|
|
130
videolayout.js
130
videolayout.js
|
@ -4,6 +4,7 @@ var VideoLayout = (function (my) {
|
|||
var localLastNCount = config.channelLastN;
|
||||
var localLastNSet = [];
|
||||
var lastNEndpointsCache = [];
|
||||
var lastNPickupJid = null;
|
||||
var largeVideoState = {
|
||||
updateInProgress: false,
|
||||
newSrc: ''
|
||||
|
@ -238,7 +239,7 @@ var VideoLayout = (function (my) {
|
|||
}
|
||||
};
|
||||
|
||||
my.handleVideoThumbClicked = function(videoSrc) {
|
||||
my.handleVideoThumbClicked = function(videoSrc, noPinnedEndpointChangedEvent) {
|
||||
// Restore style for previously focused video
|
||||
var focusJid = getJidFromVideoSrc(focusedVideoSrc);
|
||||
var oldContainer = getParticipantContainer(focusJid);
|
||||
|
@ -263,7 +264,9 @@ var VideoLayout = (function (my) {
|
|||
}
|
||||
}
|
||||
|
||||
$(document).trigger("pinnedendpointchanged");
|
||||
if (!noPinnedEndpointChangedEvent) {
|
||||
$(document).trigger("pinnedendpointchanged");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -277,7 +280,13 @@ var VideoLayout = (function (my) {
|
|||
var container = getParticipantContainer(userJid);
|
||||
container.addClass("videoContainerFocused");
|
||||
|
||||
$(document).trigger("pinnedendpointchanged", [userJid]);
|
||||
if (!noPinnedEndpointChangedEvent) {
|
||||
$(document).trigger("pinnedendpointchanged", [userJid]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($('#largeVideo').attr('src') == videoSrc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Triggers a "video.selected" event. The "false" parameter indicates
|
||||
|
@ -599,7 +608,9 @@ var VideoLayout = (function (my) {
|
|||
VideoLayout.resizeThumbnails();
|
||||
}
|
||||
|
||||
ContactList.setClickable(resourceJid, !isHide);
|
||||
// We want to be able to pin a participant from the contact list, even
|
||||
// if he's not in the lastN set!
|
||||
// ContactList.setClickable(resourceJid, !isHide);
|
||||
|
||||
};
|
||||
|
||||
|
@ -1271,6 +1282,48 @@ var VideoLayout = (function (my) {
|
|||
popupmenuElement.appendChild(paddingSpan);
|
||||
}
|
||||
|
||||
/**
|
||||
* On contact list item clicked.
|
||||
*/
|
||||
$(ContactList).bind('contactclicked', function(event, jid) {
|
||||
if (!jid) {
|
||||
return;
|
||||
}
|
||||
|
||||
var resource = Strophe.getResourceFromJid(jid);
|
||||
var videoContainer = $("#participant_" + resource);
|
||||
if (videoContainer.length > 0) {
|
||||
var videoThumb = $('video', videoContainer).get(0);
|
||||
// It is not always the case that a videoThumb exists (if there is
|
||||
// no actual video).
|
||||
if (videoThumb) {
|
||||
if (videoThumb.src && videoThumb.src != '') {
|
||||
|
||||
// We have a video src, great! Let's update the large video
|
||||
// now.
|
||||
|
||||
VideoLayout.handleVideoThumbClicked(videoThumb.src);
|
||||
} else {
|
||||
|
||||
// If we don't have a video src for jid, there's absolutely
|
||||
// no point in calling handleVideoThumbClicked; Quite
|
||||
// simply, it won't work because it needs an src to attach
|
||||
// to the large video.
|
||||
//
|
||||
// Instead, we trigger the pinned endpoint changed event to
|
||||
// let the bridge adjust its lastN set for myjid and store
|
||||
// the pinned user in the lastNPickupJid variable to be
|
||||
// picked up later by the lastN changed event handler.
|
||||
|
||||
lastNPickupJid = jid;
|
||||
$(document).trigger("pinnedendpointchanged", [jid]);
|
||||
}
|
||||
} else if (jid == connection.emuc.myroomjid) {
|
||||
$("#localVideoContainer").click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* On audio muted event.
|
||||
*/
|
||||
|
@ -1430,6 +1483,8 @@ var VideoLayout = (function (my) {
|
|||
|
||||
localLastNSet = nextLocalLastNSet;
|
||||
|
||||
var updateLargeVideo = false;
|
||||
|
||||
// Handle LastN/local LastN changes.
|
||||
$('#remoteVideos>span').each(function( index, element ) {
|
||||
var resourceJid = VideoLayout.getPeerContainerResourceJid(element);
|
||||
|
@ -1455,28 +1510,8 @@ var VideoLayout = (function (my) {
|
|||
// displayed in the large video we have to switch to another
|
||||
// user.
|
||||
var largeVideoResource = VideoLayout.getLargeVideoResource();
|
||||
if (resourceJid === largeVideoResource) {
|
||||
var resource, container, src;
|
||||
var myResource
|
||||
= Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
||||
|
||||
// Find out which endpoint to show in the large video.
|
||||
for (var i = 0; i < lastNEndpoints.length; i++) {
|
||||
resource = lastNEndpoints[i];
|
||||
if (!resource || resource === myResource)
|
||||
continue;
|
||||
|
||||
container = $("#participant_" + resource);
|
||||
if (container.length == 0)
|
||||
continue;
|
||||
|
||||
src = $('video', container).attr('src');
|
||||
if (!src)
|
||||
continue;
|
||||
|
||||
VideoLayout.updateLargeVideo(src);
|
||||
break;
|
||||
}
|
||||
if (!updateLargeVideo && resourceJid === largeVideoResource) {
|
||||
updateLargeVideo = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1501,6 +1536,18 @@ var VideoLayout = (function (my) {
|
|||
|
||||
var videoStream = simulcast.getReceivingVideoStream(mediaStream.stream);
|
||||
RTC.attachMediaStream(sel, videoStream);
|
||||
videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
|
||||
if (lastNPickupJid == mediaStream.peerjid) {
|
||||
// Clean up the lastN pickup jid.
|
||||
lastNPickupJid = null;
|
||||
|
||||
// Don't fire the events again, they've already
|
||||
// been fired in the contact list click handler.
|
||||
VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
|
||||
|
||||
updateLargeVideo = false;
|
||||
}
|
||||
|
||||
waitForRemoteVideo(
|
||||
sel,
|
||||
mediaStream.ssrc,
|
||||
|
@ -1511,6 +1558,37 @@ var VideoLayout = (function (my) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// The endpoint that was being shown in the large video has dropped out
|
||||
// of the lastN set and there was no lastN pickup jid. We need to update
|
||||
// the large video now.
|
||||
|
||||
if (updateLargeVideo) {
|
||||
|
||||
var resource, container, src;
|
||||
var myResource
|
||||
= Strophe.getResourceFromJid(connection.emuc.myroomjid);
|
||||
|
||||
// Find out which endpoint to show in the large video.
|
||||
for (var i = 0; i < lastNEndpoints.length; i++) {
|
||||
resource = lastNEndpoints[i];
|
||||
if (!resource || resource === myResource)
|
||||
continue;
|
||||
|
||||
container = $("#participant_" + resource);
|
||||
if (container.length == 0)
|
||||
continue;
|
||||
|
||||
src = $('video', container).attr('src');
|
||||
if (!src)
|
||||
continue;
|
||||
|
||||
// videoSrcToSsrc needs to be update for this call to succeed.
|
||||
VideoLayout.updateLargeVideo(src);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).bind('videoactive.jingle', function (event, videoelem) {
|
||||
|
|
Loading…
Reference in New Issue