1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 |
- /**
- * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
- *
- * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
- *
- * This program is free software; you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation; either version 3.0 of the License, or (at your option) any later
- * version.
- *
- * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along
- * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-
- // - - - START OF GLOBAL VARIABLES - - - //
-
- function getUrlParameters() {
- console.log("** Getting url params");
- var map = {};
- window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) { map[key] = value; });
- return map;
- }
-
- // - - - END OF GLOBAL VARIABLES - - - //
-
- // - - - START OF JAVASCRIPT FUNCTIONS - - - //
-
- // Draw the cursor at a specific point
- function drawCursor(scaledX, scaledY) {
- var containerObj = $("#slide > object");
-
- // the offsets of the container that has the image inside it
- var imageOffsetX = containerObj.offset().left;
- var imageOffsetY = containerObj.offset().top;
-
- // position of the cursor relative to the container
- var cursorXInImage = scaledX * containerObj.width();
- var cursorYInImage = scaledY * containerObj.height();
-
- // absolute position of the cursor in the page
- var cursorLeft = parseInt(imageOffsetX + cursorXInImage, 10);
- var cursorTop = parseInt(imageOffsetY + cursorYInImage, 10);
- if (cursorLeft < 0) {
- cursorLeft = 0;
- }
- if (cursorTop < 0) {
- cursorTop = 0;
- }
- var cursorStyle = document.getElementById("cursor").style;
- cursorStyle.left = cursorLeft + "px";
- cursorStyle.top = cursorTop + "px";
- }
-
- function showCursor(show) {
- if (show) {
- document.getElementById("cursor").style.visibility = 'visible';
- } else {
- document.getElementById("cursor").style.visibility = 'hidden';
- }
- };
-
- function setViewBox(time) {
- var vboxVal = getViewboxAtTime(time);
- if(vboxVal !== undefined) {
- setTransform(time);
- if(svgobj.contentDocument) svgfile = svgobj.contentDocument.getElementById("svgfile");
- else svgfile = svgobj.getSVGDocument('svgfile').getElementById("svgfile");
- svgfile.setAttribute('viewBox', vboxVal);
- }
- }
-
- function getImageAtTime(time) {
- var curr_t = parseFloat(time);
- var key;
- for (key in imageAtTime) {
- if(imageAtTime.hasOwnProperty(key)) {
- var arry = key.split(",");
- if ((parseFloat(arry[0]) <= curr_t) && (parseFloat(arry[1]) >= curr_t)) {
- return imageAtTime[key];
- }
- }
- }
- }
-
- function getViewboxAtTime(time) {
- var curr_t = parseFloat(time);
- var key;
- var isDeskshare = mustShowDesktopVideo(time);
- for (key in vboxValues) {
- if(vboxValues.hasOwnProperty(key)) {
- var arry = key.split(",");
- if(arry[1] == "end") {
- return isDeskshare ? adaptViewBoxToDeskshare(time) : vboxValues[key];
- }
- else if ((parseFloat(arry[0]) <= curr_t) && (parseFloat(arry[1]) >= curr_t)) {
- return isDeskshare ? adaptViewBoxToDeskshare(time) : vboxValues[key];
- }
- }
- }
- }
-
- function setSlideAspect(time, imageWidth, imageHeight) {
- var isDeskshare = mustShowDesktopVideo(time);
- var aspectAtTime = getAspectAtTime(time);
- if (aspectAtTime != undefined && aspectAtTime != 0 && !isDeskshare) {
- currentSlideAspect = aspectAtTime;
- } else {
- currentSlideAspect = parseFloat((imageWidth/imageHeight));
- }
- }
-
- function getAspectAtTime(time) {
- var curr_t = parseFloat(time);
- var key;
- for (key in slideAspectValues) {
- if(slideAspectValues.hasOwnProperty(key)) {
- var arry = key.split(",");
- if(arry[1] == "end") {
- return slideAspectValues[key];
- }
- else if ((parseFloat(arry[0]) <= curr_t) && (parseFloat(arry[1]) >= curr_t)) {
- return slideAspectValues[key];
- }
- }
- }
- }
-
- function getCursorAtTime(time) {
- var coords = cursorValues[time];
- if(coords) return coords.split(' ');
- }
-
- function removeSlideChangeAttribute() {
- $('#video').removeAttr('slide-change');
- Popcorn('#video').unlisten(Popcorn.play, 'removeSlideChangeAttribute');
- }
-
- function mustShowDesktopVideo(time) {
- var canShow = false;
- if (isThereDeskshareVideo()) {
- for (var m = 0; m < deskshareTimes.length; m++) {
- var start_timestamp = deskshareTimes[m][0];
- var stop_timestamp = deskshareTimes[m][1];
-
- if(time >= start_timestamp && time <= stop_timestamp)
- canShow = true;
- }
- }
-
- return canShow;
- }
-
- function getDeskshareDimension(time) {
- var start_timestamp = 0.0;
- var stop_timestamp = 0.0;
- var width = deskshareWidth;
- var height = deskshareHeight;
- if (isThereDeskshareVideo()) {
- for (var m = 0; m < deskshareTimes.length; m++) {
- start_timestamp = deskshareTimes[m][0];
- stop_timestamp = deskshareTimes[m][1];
- if(time >= start_timestamp && time <= stop_timestamp) {
- width = deskshareTimes[m][2];
- height = deskshareTimes[m][3];
- break;
- }
- }
- }
-
- return {
- width: width,
- height: height
- };
- }
-
- function isThereDeskshareVideo() {
- var deskshareVideo = document.getElementById("deskshare-video");
- if (deskshareVideo != null) {
- return true;
- } else {
- return false;
- }
- }
-
- function handlePresentationAreaContent(time) {
- if(time >= meetingDuration)
- return;
-
- var mustShow = mustShowDesktopVideo(time);
- if(!sharingDesktop && mustShow) {
- console.log("Showing deskshare video...");
- document.getElementById("deskshare-video").style.visibility = "visible";
- $('#slide').addClass('no-background');
- sharingDesktop = true;
- } else if(sharingDesktop && !mustShow) {
- console.log("Hiding deskshare video...");
- document.getElementById("deskshare-video").style.visibility = "hidden";
- $('#slide').removeClass('no-background');
- sharingDesktop = false;
- }
-
- resizeDeshareVideo();
- }
-
- // - - - END OF JAVASCRIPT FUNCTIONS - - - //
-
-
- function startLoadingBar() {
- console.log("==Hide playback content");
- $("#playback-content").css('visibility', 'hidden');
- Pace.once('done', function() {
- $("#loading-error").css('height','0');
- console.log("==Show playback content");
- $("#playback-content").css('visibility', 'visible');
- });
- Pace.start();
- }
-
- function runPopcorn() {
- console.log("** Running popcorn");
-
- getMetadata();
-
- if(svgobj.contentDocument) svgfile = svgobj.contentDocument.getElementById("svgfile");
- else svgfile = svgobj.getSVGDocument('svgfile');
-
- //making the object for requesting the read of the XML files.
- if (window.XMLHttpRequest) {
- // code for IE7+, Firefox, Chrome, Opera, Safari
- var xmlhttp = new XMLHttpRequest();
- } else {
- // code for IE6, IE5
- var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
-
- // PROCESS SHAPES.SVG (in XML format).
- console.log("** Getting shapes_svg");
- xmlhttp.open("GET", shapes_svg, false);
- xmlhttp.send();
- var xmlDoc = xmlhttp.responseXML;
-
- console.log("** Processing shapes_svg");
- //getting all the event tags
- var shapeelements = xmlDoc.getElementsByTagName("svg");
-
- //get the array of values for the first shape (getDataPoints(0) is the first shape).
- 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 < shapesArray.length; j++) {
- shapeTime = shapesArray[j].getAttribute("timestamp");
- shapeId = shapesArray[j].getAttribute("id");
-
- if (timestampToId[shapeTime] == undefined) {
- timestampToId[shapeTime] = new Array(0);
- }
- timestampToId[shapeTime].push(shapeId);
- }
-
- //fill the times array with the times of the svg images.
- 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.
-
-
- // PROCESS PANZOOMS.XML
- console.log("** Getting panzooms.xml");
- xmlhttp.open("GET", events_xml, false);
- xmlhttp.send();
- xmlDoc = xmlhttp.responseXML;
- //getting all the event tags
- console.log("** Processing panzooms.xml");
- var panelements = xmlDoc.getElementsByTagName("recording");
- var panZoomArray = panelements[0].getElementsByTagName("event");
- viewBoxes = xmlDoc.getElementsByTagName("viewBox");
-
- var pzlen = panZoomArray.length;
- var second_val;
- //fill the times array with the times of the svg images.
- for (var k = 0;k < pzlen; k++) {
- if(panZoomArray[k+1] == undefined) {
- second_val = "end";
- }
- else second_val = panZoomArray[k+1].getAttribute("timestamp");
- vboxValues[[panZoomArray[k].getAttribute("timestamp"), second_val]] = viewBoxes[k].childNodes[0].data;
- }
-
- getPresentationText();
-
- // PROCESS CURSOR.XML
- console.log("** Getting cursor.xml");
- xmlhttp.open("GET", cursor_xml, false);
- xmlhttp.send();
- xmlDoc = xmlhttp.responseXML;
- //getting all the event tags
- console.log("** Processing cursor.xml");
- var curelements = xmlDoc.getElementsByTagName("recording");
- var cursorArray = curelements[0].getElementsByTagName("event");
- coords = xmlDoc.getElementsByTagName("cursor");
-
- var clen = cursorArray.length;
- //fill the times array with the times of the svg images.
- if(cursorArray.length != 0) cursorValues["0"] = "0 0";
- for (var m = 0; m < clen; m++) {
- cursorValues[cursorArray[m].getAttribute("timestamp")] = coords[m].childNodes[0].data;
- }
-
-
- // PROCESS DESKSHARE.XML
- console.log("** Getting deskshare.xml");
- xmlhttp.open("GET", deskshare_xml, false);
- xmlhttp.send();
- xmlDoc = xmlhttp.responseXML;
- if (xmlDoc) {
- //getting all the event tags
- console.log("** Processing deskshare.xml");
- var deskelements = xmlDoc.getElementsByTagName("recording");
- var deskshareArray = deskelements[0].getElementsByTagName("event");
-
- if(deskshareArray != null && deskshareArray.length != 0) {
- for (var m = 0; m < deskshareArray.length; m++) {
- var deskTimes = [parseFloat(deskshareArray[m].getAttribute("start_timestamp")),
- parseFloat(deskshareArray[m].getAttribute("stop_timestamp")),
- parseFloat(deskshareArray[m].getAttribute("video_width")),
- parseFloat(deskshareArray[m].getAttribute("video_height"))];
- deskshareTimes[m] = deskTimes;
- }
- }
- }
-
- svgobj.style.left = document.getElementById("slide").offsetLeft + "px";
- svgobj.style.top = "0px";
- var next_shape;
- var 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(shapesArray[j].getAttribute("id"));
- }
- }
- 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) {
- // console.log("** Getting shapes in time");
- var shapes_in_time = timestampToId[t];
- var shapes = [];
- if (shapes_in_time != undefined) {
- var shape = null;
- for (var i = 0; i < shapes_in_time.length; i++) {
- var id = shapes_in_time[i];
- if(svgobj.contentDocument) shape = svgobj.contentDocument.getElementById(id);
- else shape = svgobj.getSVGDocument('svgfile').getElementById(id);
-
- if (shape !== null) { //if there is actually a new shape to be displayed
- shape = shape.getAttribute("shape"); //get actual shape tag for this specific time of playback
- shapes.push(shape);
- }
- }
- }
- return shapes;
- };
-
- 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) {
- 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 < shapesArray.length; i++) {
- var time_s = shapesArray[i].getAttribute("timestamp");
- var time_f = parseFloat(time_s);
-
- if(svgobj.contentDocument) shape = svgobj.contentDocument.getElementById(shapesArray[i].getAttribute("id"));
- else shape = svgobj.getSVGDocument('svgfile').getElementById(shapesArray[i].getAttribute("id"));
-
- if(shape != null) {
- 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";
- }
- }
- }
-
- var next_image = getImageAtTime(t); //fetch the name of the image at this time.
-
- if(current_image && (current_image !== next_image) && (next_image !== undefined)){ //changing slide image
- if(svgobj.contentDocument) {
- var img = svgobj.contentDocument.getElementById(current_image);
- if (img) {
- img.style.visibility = "hidden";
- }
- var ni = svgobj.contentDocument.getElementById(next_image);
- }
- else {
- var img = svgobj.getSVGDocument('svgfile').getElementById(current_image);
- if (img) {
- img.style.visibility = "hidden";
- }
- var ni = svgobj.getSVGDocument('svgfile').getElementById(next_image);
- }
- document.getElementById("slideText").innerHTML = ""; //destroy old plain text
-
- ni.style.visibility = "visible";
- document.getElementById("slideText").innerHTML = slidePlainText[next_image] + next_image; //set new plain text
-
- if ($("#accEnabled").is(':checked')) {
- //pause the playback on slide change
- p.pause();
- $('#video').attr('slide-change', 'slide-change');
- p.listen(Popcorn.play, removeSlideChangeAttribute);
- }
-
- current_canvas = getCanvasFromImage(current_image);
- if(current_canvas !== null) {
- current_canvas.setAttribute("display", "none");
- }
-
- next_canvas = getCanvasFromImage(next_image);
- if((next_canvas !== undefined) && (next_canvas != null)) {
- next_canvas.setAttribute("display", "");
- }
-
- previous_image = current_image;
- current_image = next_image;
- }
-
- if(svgobj.contentDocument) var thisimg = svgobj.contentDocument.getElementById(current_image);
- else var thisimg = svgobj.getSVGDocument('svgfile').getElementById(current_image);
-
- if (thisimg) {
- var imageWidth = parseFloat(thisimg.getAttribute("width"));
- var imageHeight = parseFloat(thisimg.getAttribute("height"));
-
- setViewBox(t);
- setSlideAspect(t,imageWidth,imageHeight);
-
- if (getCursorAtTime(t) != null && getCursorAtTime(t) != undefined && !$('#slide').hasClass('no-background')) {
- currentCursorVal = getCursorAtTime(t);
- cursorShownAt = new Date().getTime();
- showCursor(true);
- // width and height are divided by 2 because that's the value used as a reference
- // when positions in cursor.xml is calculated
- var cursorX = parseFloat(currentCursorVal[0]) / (imageWidth/2);
- var cursorY = parseFloat(currentCursorVal[1]) / (imageHeight/2);
- drawCursor(cursorX, cursorY);
-
- // hide the cursor after 3s of inactivity
- } else if (cursorShownAt < new Date().getTime() - 3000) {
- showCursor(false);
- }
-
- // store the current slide and adjust the size of the slides
- currentImage = thisimg;
- resizeSlides();
- }
-
- handlePresentationAreaContent(t);
- }
- }
- });
- };
-
- // Deskshare's whiteboard variables
- var deskshareWidth = 1280.0;
- var deskshareHeight = 720.0;
- var widthScale = 1;
- var heightScale = 1;
- var widthTranslate = 0;
- var heightTranslate = 0;
-
- function clearTransform() {
- widthScale = 1;
- heightScale = 1;
- widthTranslate = 0;
- heightTranslate = 0;
- }
-
- function setDeskshareScale(originalVideoWidth, originalVideoHeight) {
- widthScale = originalVideoWidth / deskshareWidth;
- heightScale = originalVideoHeight / deskshareHeight;
- }
-
- function setDeskshareTranslate(originalVideoWidth, originalVideoHeight) {
- widthTranslate = (deskshareWidth - originalVideoWidth) / 2;
- heightTranslate = (deskshareHeight - originalVideoHeight) / 2;
- }
-
- // Deskshare viewBox has the information to transform the canvas to place it above the video
- function adaptViewBoxToDeskshare(time) {
- var dimension = getDeskshareDimension(time);
- setDeskshareScale(dimension.width, dimension.height);
- setDeskshareTranslate(dimension.width, dimension.height);
-
- var viewBox = "0.0 0.0 " + deskshareWidth + " " + deskshareHeight;
- return viewBox;
- }
-
- function getCanvasFromImage(image) {
- var canvasId = "canvas" + image.substr(5);
- var canvas = svgobj.contentDocument ? svgobj.contentDocument.getElementById(canvasId) : svgobj.getSVGDocument('svgfile').getElementById(canvasId);
- return canvas;
- }
-
- function getDeskshareImage() {
- var images = svgobj.contentDocument ? svgobj.contentDocument.getElementsByTagName("image") : svgobj.getSVGDocument('svgfile').getElementsByTagName("image");
- for(var i = 0; i < images.length; i++) {
- var element = images[i];
- var id = element.getAttribute("id");
- var href = element.getAttribute("xlink:href");
- if (href != null && href.indexOf("deskshare") !=-1) {
- return id;
- }
- }
- return "image0";
- }
-
- // Transform canvas to fit the different deskshare video sizes
- function setTransform(time) {
- if (deskshare_image == null) {
- deskshare_image = getDeskshareImage();
- }
- if (mustShowDesktopVideo(time)) {
- var canvas = getCanvasFromImage(deskshare_image);
- if (canvas !== null) {
- var scale = "scale(" + widthScale.toString() + ", " + heightScale.toString() + ")";
- var translate = "translate(" + widthTranslate.toString() + ", " + heightTranslate.toString() + ")";
- var transform = translate + " " + scale;
- canvas.setAttribute('transform', transform);
- }
- } else {
- clearTransform();
- }
- }
-
- function defineStartTime() {
- console.log("** Defining start time");
-
- if (params.t === undefined)
- return 1;
-
- var extractNumber = /\d+/g;
- var extractUnit = /\D+/g;
- var temp_start_time = 0;
-
- while (true) {
- var param1 = extractUnit.exec(params.t);
- var param2 = extractNumber.exec(params.t);
- if (param1 == null || param2 == null)
- break;
-
- var unit = String(param1).toLowerCase();
- var value = parseInt(String(param2));
-
- if (unit == "h")
- value *= 3600;
- else if (unit == "m")
- value *= 60;
-
- temp_start_time += value;
- }
-
- console.log("Start time: " + temp_start_time);
- return temp_start_time;
- }
-
- var lastFrameTime = 0.0;
-
- var shape;
- var current_shapes = [];
-
- var deskshare_image = null;
- var current_image = "image0";
- var previous_image = null;
- var current_canvas;
- var next_canvas;
- var next_image;
- var next_pgid;
- var curr_pgid;
- var svgfile;
- //current time
- var t;
- var len;
- var meetingDuration;
- //coordinates for x and y for each second
- var panAndZoomTimes = [];
- var viewBoxes = [];
- var coords = [];
- var times = [];
- // timestamp and id for drawings
- var shapeTime;
- var shapeId;
- var clearTimes = [];
- var main_shapes_ids = [];
- var vboxValues = {};
- var slideAspectValues = {};
- var currentSlideAspect = 0;
- var cursorValues = {};
- var currentCursorVal;
- var imageAtTime = {};
- var slidePlainText = {}; //holds slide plain text for retrieval
- var cursorStyle;
- var cursorShownAt = 0;
- var deskshareTimes = [];
- var sharingDesktop = false;
-
- var params = getUrlParameters();
- var MEETINGID = params.meetingId;
- // var HOST = window.location.host;
- // var url = "http://" + HOST + "/presentation/" + MEETINGID;
- var url = "/presentation/" + MEETINGID;
- var shapes_svg = url + '/shapes.svg';
- var events_xml = url + '/panzooms.xml';
- var cursor_xml = url + '/cursor.xml';
- var metadata_xml = url + '/metadata.xml';
- var deskshare_xml = url + '/deskshare.xml';
- var presentation_text_json = url + '/presentation_text.json';
-
- var firstLoad = true;
- var svgReady = false;
- var videoReady = false;
- var audioReady = false;
- var deskshareReady = false;
-
- var svgobj = document.createElement('object');
- svgobj.setAttribute('data', shapes_svg);
- svgobj.setAttribute('height', '100%');
- svgobj.setAttribute('width', '100%');
-
- // It's important to verify if all medias are ready before running Popcorn
- document.addEventListener('media-ready', function(event) {
- switch(event.detail) {
- case 'video':
- videoReady = true;
- break;
- case 'audio':
- audioReady = true;
- break;
- case 'deskshare':
- deskshareReady = true;
- break;
- case 'svg':
- svgReady = true;
- break;
- default:
- console.log('unhandled media-ready event: ' + event.detail);
- }
-
- if ((audioReady || videoReady) && deskshareReady && svgReady) {
- runPopcorn();
-
- if (firstLoad) initPopcorn();
- }
- }, false);
-
- function initPopcorn() {
- firstLoad = false;
- generateThumbnails();
-
- var startTime = defineStartTime();
- console.log("** startTime = " + startTime);
-
- Popcorn("#video").currentTime(startTime);
- if(isThereDeskshareVideo())
- Popcorn("#deskshare-video").currentTime(startTime);
-
- //Popcorn documentation suggests this way to get the duration, since this information does not come with 'loadedmetadata' event.
- Popcorn("#video").cue(2, function() {
- meetingDuration = parseFloat(Popcorn("#video").duration().toFixed(1));
- console.log("** Meeting duration (seconds): " + meetingDuration);
- });
- }
-
- svgobj.addEventListener('load', function() {
- console.log("got svgobj 'load' event");
- document.dispatchEvent(new CustomEvent('media-ready', {'detail': 'svg'}));
- }, false);
-
- svgobj.addEventListener('error', function() {
- console.log("got svgobj 'error' event");
- onSVGLoadingError();
- }, false);
-
- function onSVGLoadingError() {
- Pace.off('done');
- Pace.stop();
- $("#loading-error").css('visibility', 'visible');
- }
-
- // Fetches the metadata associated with the recording and uses it to configure
- // the playback page
- var getMetadata = function() {
- var xmlhttp;
- if (window.XMLHttpRequest) {// code for IE7, Firefox, Chrome, Opera, Safari
- xmlhttp = new XMLHttpRequest();
- } else {// code for IE6, IE5
- xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
- xmlhttp.open("GET", metadata_xml, false);
- xmlhttp.send(null);
-
- if (xmlhttp.responseXML)
- var xmlDoc = xmlhttp.responseXML;
- else {
- var parser = new DOMParser();
- var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
- }
-
- var metadata = xmlDoc.getElementsByTagName("meta");
- if (metadata.length > 0) {
- metadata = metadata[0];
-
- var meetingName = metadata.getElementsByTagName("meetingName");
- if (meetingName.length > 0) {
- $("#recording-title").text(meetingName[0].textContent);
- $("#recording-title").attr("title", meetingName[0].textContent);
- }
- }
- };
-
- function setPresentationTextFromJSON(images, presentationText) {
- for (var m = 0; m < images.length; m++) {
- len = images[m].getAttribute("in").split(" ").length;
- for (var n = 0; n < len; n++) {
- imageAtTime[[images[m].getAttribute("in").split(" ")[n], images[m].getAttribute("out").split(" ")[n]]] = images[m].getAttribute("id");
- }
- // The logo at the start has no text attribute
- if (images[m].getAttribute("text")) {
- var imgId = images[m].getAttribute("id"); // Have to save the value because images array might go out of scope
- var imgTxt = images[m].getAttribute("text").split("/"); // Text format: presentation/PRESENTATION_ID/textfiles/SLIDE_ID.txt
- var presentationId = imgTxt[1];
- var slideId = imgTxt[3].split(".")[0];
- if (presentationText[presentationId] && presentationText[presentationId][slideId]) {
- slidePlainText[imgId] = $('<div/>').text(presentationText[presentationId][slideId]).html();
- } else {
- slidePlainText[imgId] = $('<div/>')
- }
- }
- }
- }
-
- function setPresentationTextFromTxt(images) {
- for (var m = 0; m < images.length; m++) {
- len = images[m].getAttribute("in").split(" ").length;
- for (var n = 0; n < len; n++) {
- imageAtTime[[images[m].getAttribute("in").split(" ")[n], images[m].getAttribute("out").split(" ")[n]]] = images[m].getAttribute("id");
- }
- // The logo at the start has no text attribute
- if (images[m].getAttribute("text")) {
- var txtFile = false;
- if (window.XMLHttpRequest) {
- // Code for IE7+, Firefox, Chrome, Opera, Safari
- txtFile = new XMLHttpRequest();
- } else {
- // Code for IE6, IE5
- txtFile = new ActiveXObject("Microsoft.XMLHTTP");
- }
- var imgId = images[m].getAttribute("id"); // Have to save the value because images array might go out of scope
- txtFile.open("GET", url + "/" + images[m].getAttribute("text"), false);
- txtFile.onreadystatechange = function() {
- if (txtFile.readyState === 4) {
- if (txtFile.status === 200) {
- slidePlainText[imgId] = $('<div/>').text(txtFile.responseText).html();
- }
- }
- };
- txtFile.send(null);
- }
- }
- }
-
- function processPresentationText(response) {
- // Making the object for requesting the read of the XML files.
- if (window.XMLHttpRequest) {
- // Code for IE7+, Firefox, Chrome, Opera, Safari
- var xmlhttp = new XMLHttpRequest();
- } else {
- // Code for IE6, IE5
- var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
- xmlhttp.open("GET", shapes_svg, false);
- xmlhttp.send();
- var xmlDoc = xmlhttp.responseXML;
-
- // Getting all the event tags
- var shapeelements = xmlDoc.getElementsByTagName("svg");
-
- // Newer recordings have slide images identified by class="slide"
- // because they might include images in shapes
- var images = shapeelements[0].getElementsByClassName("slide");
- // To handle old recordings, fetch a list of all images instead
- if (images.length == 0) {
- images = shapeelements[0].getElementsByTagName("image");
- }
-
- if (response !== undefined) {
- setPresentationTextFromJSON(images, response);
- } else {
- setPresentationTextFromTxt(images);
- }
-
- //at this point, we're sure that the array 'imageAtTime' is ready. Now, we need to set the aspects times to resize the slide div during the playback.
- processSlideAspectTimes();
- }
-
- function processSlideAspectTimes() {
- var key;
- var lastAspectValue = 0;
- for (key in vboxValues) {
- if (vboxValues.hasOwnProperty(key)) {
- var start_timestamp = key.split(",")[0];
- var stop_timestamp = key.split(",")[1];
- var vboxWidth = parseFloat(vboxValues[key].split(" ")[2]);
- var vboxHeight = parseFloat(vboxValues[key].split(" ")[3]);
- var aspectValue = processAspectValue(vboxWidth,vboxHeight,start_timestamp,lastAspectValue);
- slideAspectValues[[start_timestamp, stop_timestamp]] = aspectValue;
- lastAspectValue = aspectValue;
- }
- }
- }
-
- function processAspectValue(vboxWidth, vboxHeight, time, lastAspectValue) {
- var imageId;
- if (time == "0.0") {
- //a little hack 'cause function getImageAtTime with time = 0.0 returns the background image...
- //we need the first slide instead
- imageId = "image1";
- }
- else {
- imageId = getImageAtTime(time);
- }
-
- if (imageId !== undefined) {
- var image;
- if (svgobj.contentDocument) {
- image = svgobj.contentDocument.getElementById(imageId);
- }
- else {
- image = svgobj.getSVGDocument('svgfile').getElementById(imageId);
- }
-
- if (image) {
- if(mustShowDesktopVideo(parseFloat(time))) {
- return lastAspectValue;
- }
-
- var imageWidth = parseFloat(image.getAttribute("width"));
- var imageHeight = parseFloat(image.getAttribute("height"));
-
- //fit-to-width: returning vbox aspect
- if(vboxWidth == imageWidth && vboxHeight < imageHeight) {
- return parseFloat(vboxWidth/vboxHeight);
- }
- //fit-to-page: returning image aspect
- else if(vboxWidth == imageWidth && vboxHeight == imageHeight) {
- return parseFloat(imageWidth/imageHeight);
- }
- //if it's not fit-to-width neither fit-to-page we return the previous aspect
- else {
- return lastAspectValue;
- }
- } else {
- console.log("processAspectValue: there is no image for the id = " + imageId);
- return lastAspectValue;
- }
- } else {
- console.log("processAspectValue: imageId undefined");
- return lastAspectValue;
- }
- }
-
- function getPresentationText() {
- console.log("** Getting text files");
- loadJSON(processPresentationText, presentation_text_json);
- }
-
- function loadJSON(callback, url) {
- var xobj;
- if (window.XMLHttpRequest) {
- // Code for IE7+, Firefox, Chrome, Opera, Safari
- xobj = new XMLHttpRequest();
- } else {
- // Code for IE6, IE5
- xobj = new ActiveXObject("Microsoft.XMLHTTP");
- }
- xobj.overrideMimeType("application/json");
- xobj.open('GET', url, true);
- xobj.onreadystatechange = function () {
- if (xobj.readyState == 4) {
- // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
- if (xobj.status == "200") {
- callback(JSON.parse(xobj.responseText));
- } else {
- console.log("Could not get JSON file");
- callback(undefined);
- }
- }
- };
- xobj.send(null);
- }
-
- document.getElementById('slide').appendChild(svgobj);
-
- var currentImage;
-
- // A small hack to hide the cursor when resizing the window, so it's not
- // misplaced while the window is being resized
- window.onresize = function(event) {
- showCursor(false);
- resizeSlides();
- resizeDeshareVideo();
- };
-
- // Resize the container that has the slides (and whiteboard) to be the maximum
- // size possible but still maintaining the aspect ratio of the slides.
- //
- // This is done here only because of pan and zoom. Pan/zoom is done by modifiyng
- // the svg's viewBox, and that requires the container that has the svg to be the
- // exact size we want to display the slides so that parts of the svg that are outside
- // of its parent's area are hidden. If we let the svg occupy all presentation area
- // (letting the svg do the image resizing), the slides will move and zoom around the
- // entire area when pan/zoom is activated, usually displaying more of the slide
- // than we want to (i.e. more than was displayed in the conference).
- var resizeSlides = function() {
- if (currentImage) {
- var $slide = $("#slide");
- var maxWidth = currentSlideAspect * $slide.parent().outerHeight();
- $slide.css("max-width", maxWidth);
- var maxHeight = $slide.parent().width() / currentSlideAspect;
- $slide.css("max-height", maxHeight);
- }
- };
-
- var resizeDeshareVideo = function() {
- if (!isThereDeskshareVideo()) return;
- var deskshareVideo = document.getElementById("deskshare-video");
- var $deskhareVideo = $("#deskshare-video");
-
- var videoWidth = parseInt(deskshareVideo.videoWidth, 10);
- var videoHeight = parseInt(deskshareVideo.videoHeight, 10);
-
- var aspectRatio = videoWidth/videoHeight;
- var max = aspectRatio * $deskhareVideo.parent().outerHeight();
- $deskhareVideo.css("max-width", max);
-
- var height = $deskhareVideo.parent().width() / aspectRatio;
- $deskhareVideo.css("max-height", height);
- };
|