Merge branch 'mconf' of github.com:alexandrekreis/bigbluebutton into mconf
This commit is contained in:
commit
e45fd8794a
@ -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() {
|
||||
|
@ -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){
|
||||
|
Loading…
Reference in New Issue
Block a user