Merge branch 'mconf' of github.com:alexandrekreis/bigbluebutton into mconf

This commit is contained in:
Felipe Cecagno 2017-05-24 16:54:36 -03:00
commit e45fd8794a
2 changed files with 198 additions and 84 deletions

View File

@ -188,14 +188,6 @@ function isThereDeskshareVideo() {
}
}
function resyncVideos() {
if (!isThereDeskshareVideo()) return;
var currentTime = Popcorn('#video').currentTime();
var currentDeskshareVideoTime = Popcorn("#deskshare-video").currentTime();
if (Math.abs(currentTime - currentDeskshareVideoTime) >= 0.1)
Popcorn("#deskshare-video").currentTime(currentTime);
}
function handlePresentationAreaContent(time) {
var meetingDuration = parseFloat(new Popcorn("#video").duration().toFixed(1));
if(time >= meetingDuration)
@ -214,7 +206,6 @@ function handlePresentationAreaContent(time) {
sharingDesktop = false;
}
resyncVideos();
resizeDeshareVideo();
}
@ -260,15 +251,15 @@ function runPopcorn() {
var shapeelements = xmlDoc.getElementsByTagName("svg");
//get the array of values for the first shape (getDataPoints(0) is the first shape).
var array = $(shapeelements[0]).find("g").filter(function(){ //get all the lines from the svg file
var shapesArray = $(shapeelements[0]).find("g").filter(function(){ //get all the lines from the svg file
return $(this).attr('class') == 'shape';
});
//create a map from timestamp to id list
var timestampToId = {};
for (var j = 0; j < array.length; j++) {
shapeTime = array[j].getAttribute("timestamp");
shapeId = array[j].getAttribute("id");
for (var j = 0; j < shapesArray.length; j++) {
shapeTime = shapesArray[j].getAttribute("timestamp");
shapeId = shapesArray[j].getAttribute("id");
if (timestampToId[shapeTime] == undefined) {
timestampToId[shapeTime] = new Array(0);
@ -277,8 +268,8 @@ function runPopcorn() {
}
//fill the times array with the times of the svg images.
for (var j = 0; j < array.length; j++) {
times[j] = array[j].getAttribute("timestamp");
for (var j = 0; j < shapesArray.length; j++) {
times[j] = shapesArray[j].getAttribute("timestamp");
}
var times_length = times.length; //get the length of the times array.
@ -353,17 +344,17 @@ function runPopcorn() {
svgobj.style.top = "0px";
var next_shape;
var shape;
for (var j = 0; j < array.length - 1; j++) { //iterate through all the shapes and pick out the main ones
var time = array[j].getAttribute("timestamp");
shape = array[j].getAttribute("shape");
next_shape = array[j+1].getAttribute("shape");
for (var j = 0; j < shapesArray.length - 1; j++) { //iterate through all the shapes and pick out the main ones
var time = shapesArray[j].getAttribute("timestamp");
shape = shapesArray[j].getAttribute("shape");
next_shape = shapesArray[j+1].getAttribute("shape");
if(shape !== next_shape) {
main_shapes_ids.push(array[j].getAttribute("id"));
}
if(shape !== next_shape) {
main_shapes_ids.push(shapesArray[j].getAttribute("id"));
}
}
if (array.length !== 0) {
main_shapes_ids.push(array[array.length-1].getAttribute("id")); //put last value into this array always!
if (shapesArray.length !== 0) {
main_shapes_ids.push(shapesArray[shapesArray.length-1].getAttribute("id")); //put last value into this array always!
}
var get_shapes_in_time = function(t) {
@ -386,64 +377,95 @@ function runPopcorn() {
return shapes;
};
var timeThreshold = 0.5;
// Check if the update is following the playback flow.
// Otherwise is some kind of seek.
var regularPlaybackFlow = function(updateTime, lastUpdateTime) {
if (Math.abs(updateTime - lastUpdateTime) > timeThreshold) {
return false;
} else {
return true;
}
}
var drawShape = function(shapes, shapeElement, shapeTime, currentTime) {
var visibleShape = false;
if (shapeTime < currentTime) {
// Check if it is a main shape
if(main_shapes_ids.indexOf(shapeElement.getAttribute("id")) > -1) {
var undoTime = parseFloat(shapeElement.getAttribute("undo"));
// And hasn't been undone
if(undoTime === -1 || undoTime > currentTime) {
shapeElement.style.visibility = "visible";
visibleShape = true;
}
}
} else if (shapeTime == currentTime) {
// Only makes visible the last drawing of a given shape
var shape = shapeElement.getAttribute("shape");
var shapeIndex = shapes.indexOf(shape);
if (shapeIndex > -1) {
shapes.splice(shapeIndex, 1);
shapeIndex = shapes.indexOf(shape);
if (shapeIndex === -1) {
shapeElement.style.visibility = "visible";
visibleShape = true;
}
}
}
// It's not a visible shape, force it to be hidden
if (!visibleShape) {
shapeElement.style.visibility = "hidden";
}
}
var lastShapeTime = -1;
var updateShapes = function(time) {
var svgDocument = null;
var shapes = get_shapes_in_time(time);
var currentTime = parseFloat(time);
if (svgobj.contentDocument) svgDocument = svgobj.contentDocument;
else svgDocument = svgobj.getSVGDocument('svgfile');
// Abort if there is no SVG available
if (svgDocument == null) return;
if (regularPlaybackFlow(currentTime, lastShapeTime)) {
for (var i = 0; i < shapesArray.length; i++) {
var shapeTime = parseFloat(shapesArray[i].getAttribute("timestamp"));
if (shapeTime <= currentTime) {
// Draw only inside this interval
var shapeElement = svgDocument.getElementById(shapesArray[i].getAttribute("id"));
drawShape(shapes, shapeElement, shapeTime, currentTime);
} else {
break;
}
}
} else {
for (var i = 0; i < shapesArray.length; i++) {
var shapeTime = parseFloat(shapesArray[i].getAttribute("timestamp"));
var shapeElement = svgDocument.getElementById(shapesArray[i].getAttribute("id"));
drawShape(shapes, shapeElement, shapeTime, currentTime);
}
}
lastShapeTime = currentTime;
}
var p = new Popcorn("#video");
//update 60x / second the position of the next value.
p.code({
start: 1, // start time
end: p.duration(),
onFrame: function(options) {
//console.log("**Popcorn video onframe");
if(!((p.paused() === true) && (p.seeking() === false))) {
var t = p.currentTime().toFixed(1); //get the time and round to 1 decimal place
var currentTime = p.currentTime();
if ( (!p.paused() || p.seeking()) && (Math.abs(currentTime - lastFrameTime) >= 0.1) ) {
lastFrameTime = currentTime;
var t = currentTime.toFixed(1); //get the time and round to 1 decimal place
current_shapes = get_shapes_in_time(t);
//redraw everything (only way to make everything elegant)
for (var i = 0; i < array.length; i++) {
var time_s = array[i].getAttribute("timestamp");
var time_f = parseFloat(time_s);
if(svgobj.contentDocument) shape = svgobj.contentDocument.getElementById(array[i].getAttribute("id"));
else shape = svgobj.getSVGDocument('svgfile').getElementById(array[i].getAttribute("id"));
var shape_i = shape.getAttribute("shape");
if (time_f < t) {
if(current_shapes.indexOf(shape_i) > -1) { //currently drawing the same shape so don't draw the older steps
shape.style.visibility = "hidden"; //hide older steps to shape
} else if(main_shapes_ids.indexOf(shape.getAttribute("id")) > -1) { //as long as it is a main shape, it can be drawn... no intermediate steps.
if(parseFloat(shape.getAttribute("undo")) === -1) { //As long as the undo event hasn't happened yet...
shape.style.visibility = "visible";
} else if (parseFloat(shape.getAttribute("undo")) > t) {
shape.style.visibility = "visible";
} else {
shape.style.visibility = "hidden";
}
} else {
shape.style.visibility = "hidden";
}
} else if(time_s === t) { //for the shapes with the time specific to the current time
// only makes visible the last drawing of a given shape
var idx = current_shapes.indexOf(shape_i);
if (idx > -1) {
current_shapes.splice(idx, 1);
idx = current_shapes.indexOf(shape_i);
if (idx > -1) {
shape.style.visibility = "hidden";
} else {
shape.style.visibility = "visible";
}
} else {
// this is an inconsistent state, since current_shapes should have at least one drawing of this shape
shape.style.visibility = "hidden";
}
} else { //for shapes that shouldn't be drawn yet (larger time than current time), don't draw them.
shape.style.visibility = "hidden";
}
}
updateShapes(t);
var next_image = getImageAtTime(t); //fetch the name of the image at this time.
var imageXOffset = 0;
var imageYOffset = 0;
if(current_image && (current_image !== next_image) && (next_image !== undefined)){ //changing slide image
if(svgobj.contentDocument) {
@ -625,11 +647,12 @@ function defineStartTime() {
return temp_start_time;
}
var lastFrameTime = 0.0;
var deskshare_image = null;
var current_image = "image0";
var previous_image = null;
var current_canvas;
var shape;
var next_canvas;
var next_image;
var next_pgid;
@ -638,7 +661,6 @@ var svgfile;
//current time
var t;
var len;
var current_shapes = [];
//coordinates for x and y for each second
var panAndZoomTimes = [];
var viewBoxes = [];
@ -713,8 +735,12 @@ function initPopcorn() {
firstLoad = false;
generateThumbnails();
var p = Popcorn("#video");
p.currentTime(defineStartTime());
var startTime = defineStartTime();
console.log("** startTime = " + startTime);
Popcorn("#video").currentTime(startTime);
if(isThereDeskshareVideo())
Popcorn("#deskshare-video").currentTime(startTime);
}
svgobj.addEventListener('load', function() {

View File

@ -113,6 +113,11 @@ var RECORDINGS = "/presentation/" + MEETINGID;
var SLIDES_XML = RECORDINGS + '/slides_new.xml';
var SHAPES_SVG = RECORDINGS + '/shapes.svg';
var hasVideo = false;
var syncing = false;
var masterVideoSeeked = false;
var primaryMedia;
var secondaryMedias;
var allMedias;
/*
* Sets the title attribute in a thumbnail.
@ -326,7 +331,11 @@ load_video = function(){
//video.setAttribute('autoplay','autoplay');
document.getElementById("video-area").appendChild(video);
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'video'}));
Popcorn("#video").on("canplayall", function() {
console.log("==Video loaded");
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'video'}));
});
}
load_audio = function() {
@ -360,7 +369,12 @@ load_audio = function() {
//leave auto play turned off for accessiblity support
//audio.setAttribute('autoplay','autoplay');
document.getElementById("audio-area").appendChild(audio);
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'audio'}));
//remember: audio id is 'video'
Popcorn("#video").on("canplayall", function() {
console.log("==Audio loaded");
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'audio'}));
});
}
load_deskshare_video = function () {
@ -376,14 +390,88 @@ load_deskshare_video = function () {
var presentationArea = document.getElementById("presentation-area");
presentationArea.insertBefore(deskshare_video,presentationArea.childNodes[0]);
$('#video').on("play", function() {
Popcorn('#deskshare-video').play();
setSync();
Popcorn("#deskshare-video").on("canplayall", function() {
console.log("==Deskshare video loaded");
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'deskshare'}));
});
$('#video').on("pause", function() {
Popcorn('#deskshare-video').pause();
}
function setSync() {
//master video
primaryMedia = Popcorn("#video");
//slave videos
secondaryMedias = [ Popcorn("#deskshare-video") ];
allMedias = [primaryMedia].concat(secondaryMedias);
//when we play the master video, we play all other videos as well...
primaryMedia.on("play", function() {
for(i = 0; i < secondaryMedias.length ; i++)
secondaryMedias[i].play();
});
document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'deskshare'}));
//when we pause the master video, we sync
primaryMedia.on("pause", function() {
sync();
});
primaryMedia.on("seeking", function() {
if(primaryMedia.played().length != 0)
masterVideoSeeked = true;
});
//when finished seeking, we sync all medias...
primaryMedia.on("seeked", function() {
if(primaryMedia.paused())
sync();
else
primaryMedia.pause();
});
for(i = 0; i < allMedias.length ; i++) {
allMedias[i].on("waiting", function() {
//if one of the medias is 'waiting', we must sync
if(!primaryMedia.seeking() && !syncing) {
syncing = true;
//pause the master video, causing to pause and sync all videos...
console.log("syncing videos...");
primaryMedia.pause();
}
});
allMedias[i].on("canplaythrough", function() {
if(syncing || masterVideoSeeked) {
var allMediasAreReady = true;
for(i = 0; i < allMedias.length ; i++)
allMediasAreReady &= (allMedias[i].media.readyState == 4)
if(allMediasAreReady) {
syncing = false;
masterVideoSeeked = false;
//play the master video, causing to play all videos...
console.log("resuming...");
primaryMedia.play();
}
}
});
}
}
function sync() {
for(var i = 0; i < secondaryMedias.length ; i++) {
if(secondaryMedias[i].media.readyState > 1) {
secondaryMedias[i].pause();
//set the current time will fire a "canplaythrough" event to tell us that the video can be played...
secondaryMedias[i].currentTime(primaryMedia.currentTime());
}
}
}
load_script = function(file){