Front IDILL :
Config file added dor the Front
Random play at the beginning (when no user is detected)
Pointers added
Curves added (search and filter modes)
Mosaic completion added (depletion to come later)
State of the Front : just before the communication module creation
/*
*
* Copyright 2010-2012 Institut de recherche et d'innovation
* contributor(s) : Karim Hamidou, Samuel Huron, Raphael Velt, Thibaut Cavalie
*
* contact@iri.centrepompidou.fr
* http://www.iri.centrepompidou.fr
*
* This software is a computer program whose purpose is to show and add annotations on a video .
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
v2.0.3 (c) Kyle Simpson
MIT License
*/
(function(o){var K=o.$LAB,y="UseLocalXHR",z="AlwaysPreserveOrder",u="AllowDuplicates",A="CacheBust",B="BasePath",C=/^[^?#]*\//.exec(location.href)[0],D=/^\w+\:\/\/\/?[^\/]+/.exec(C)[0],i=document.head||document.getElementsByTagName("head"),L=(o.opera&&Object.prototype.toString.call(o.opera)=="[object Opera]")||("MozAppearance"in document.documentElement.style),q=document.createElement("script"),E=typeof q.preload=="boolean",r=E||(q.readyState&&q.readyState=="uninitialized"),F=!r&&q.async===true,M=!r&&!F&&!L;function G(a){return Object.prototype.toString.call(a)=="[object Function]"}function H(a){return Object.prototype.toString.call(a)=="[object Array]"}function N(a,c){var b=/^\w+\:\/\//;if(/^\/\/\/?/.test(a)){a=location.protocol+a}else if(!b.test(a)&&a.charAt(0)!="/"){a=(c||"")+a}return b.test(a)?a:((a.charAt(0)=="/"?D:C)+a)}function s(a,c){for(var b in a){if(a.hasOwnProperty(b)){c[b]=a[b]}}return c}function O(a){var c=false;for(var b=0;b<a.scripts.length;b++){if(a.scripts[b].ready&&a.scripts[b].exec_trigger){c=true;a.scripts[b].exec_trigger();a.scripts[b].exec_trigger=null}}return c}function t(a,c,b,d){a.onload=a.onreadystatechange=function(){if((a.readyState&&a.readyState!="complete"&&a.readyState!="loaded")||c[b])return;a.onload=a.onreadystatechange=null;d()}}function I(a){a.ready=a.finished=true;for(var c=0;c<a.finished_listeners.length;c++){a.finished_listeners[c]()}a.ready_listeners=[];a.finished_listeners=[]}function P(d,f,e,g,h){setTimeout(function(){var a,c=f.real_src,b;if("item"in i){if(!i[0]){setTimeout(arguments.callee,25);return}i=i[0]}a=document.createElement("script");if(f.type)a.type=f.type;if(f.charset)a.charset=f.charset;if(h){if(r){e.elem=a;if(E){a.preload=true;a.onpreload=g}else{a.onreadystatechange=function(){if(a.readyState=="loaded")g()}}a.src=c}else if(h&&c.indexOf(D)==0&&d[y]){b=new XMLHttpRequest();b.onreadystatechange=function(){if(b.readyState==4){b.onreadystatechange=function(){};e.text=b.responseText+"\n//@ sourceURL="+c;g()}};b.open("GET",c);b.send()}else{a.type="text/cache-script";t(a,e,"ready",function(){i.removeChild(a);g()});a.src=c;i.insertBefore(a,i.firstChild)}}else if(F){a.async=false;t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}else{t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}},0)}function J(){var l={},Q=r||M,n=[],p={},m;l[y]=true;l[z]=false;l[u]=false;l[A]=false;l[B]="";function R(a,c,b){var d;function f(){if(d!=null){d=null;I(b)}}if(p[c.src].finished)return;if(!a[u])p[c.src].finished=true;d=b.elem||document.createElement("script");if(c.type)d.type=c.type;if(c.charset)d.charset=c.charset;t(d,b,"finished",f);if(b.elem){b.elem=null}else if(b.text){d.onload=d.onreadystatechange=null;d.text=b.text}else{d.src=c.real_src}i.insertBefore(d,i.firstChild);if(b.text){f()}}function S(c,b,d,f){var e,g,h=function(){b.ready_cb(b,function(){R(c,b,e)})},j=function(){b.finished_cb(b,d)};b.src=N(b.src,c[B]);b.real_src=b.src+(c[A]?((/\?.*$/.test(b.src)?"&_":"?_")+~~(Math.random()*1E9)+"="):"");if(!p[b.src])p[b.src]={items:[],finished:false};g=p[b.src].items;if(c[u]||g.length==0){e=g[g.length]={ready:false,finished:false,ready_listeners:[h],finished_listeners:[j]};P(c,b,e,((f)?function(){e.ready=true;for(var a=0;a<e.ready_listeners.length;a++){e.ready_listeners[a]()}e.ready_listeners=[]}:function(){I(e)}),f)}else{e=g[0];if(e.finished){j()}else{e.finished_listeners.push(j)}}}function v(){var e,g=s(l,{}),h=[],j=0,w=false,k;function T(a,c){a.ready=true;a.exec_trigger=c;x()}function U(a,c){a.ready=a.finished=true;a.exec_trigger=null;for(var b=0;b<c.scripts.length;b++){if(!c.scripts[b].finished)return}c.finished=true;x()}function x(){while(j<h.length){if(G(h[j])){try{h[j++]()}catch(err){}continue}else if(!h[j].finished){if(O(h[j]))continue;break}j++}if(j==h.length){w=false;k=false}}function V(){if(!k||!k.scripts){h.push(k={scripts:[],finished:true})}}e={script:function(){for(var f=0;f<arguments.length;f++){(function(a,c){var b;if(!H(a)){c=[a]}for(var d=0;d<c.length;d++){V();a=c[d];if(G(a))a=a();if(!a)continue;if(H(a)){b=[].slice.call(a);b.unshift(d,1);[].splice.apply(c,b);d--;continue}if(typeof a=="string")a={src:a};a=s(a,{ready:false,ready_cb:T,finished:false,finished_cb:U});k.finished=false;k.scripts.push(a);S(g,a,k,(Q&&w));w=true;if(g[z])e.wait()}})(arguments[f],arguments[f])}return e},wait:function(){if(arguments.length>0){for(var a=0;a<arguments.length;a++){h.push(arguments[a])}k=h[h.length-1]}else k=false;x();return e}};return{script:e.script,wait:e.wait,setOptions:function(a){s(a,g);return e}}}m={setGlobalDefaults:function(a){s(a,l);return m},setOptions:function(){return v().setOptions.apply(null,arguments)},script:function(){return v().script.apply(null,arguments)},wait:function(){return v().wait.apply(null,arguments)},queueScript:function(){n[n.length]={type:"script",args:[].slice.call(arguments)};return m},queueWait:function(){n[n.length]={type:"wait",args:[].slice.call(arguments)};return m},runQueue:function(){var a=m,c=n.length,b=c,d;for(;--b>=0;){d=n.shift();a=a[d.type].apply(null,d.args)}return a},noConflict:function(){o.$LAB=K;return m},sandbox:function(){return J()}};return m}o.$LAB=J();(function(a,c,b){if(document.readyState==null&&document[a]){document.readyState="loading";document[a](c,b=function(){document.removeEventListener(c,b,false);document.readyState="complete"},false)}})("addEventListener","DOMContentLoaded")})(this);/* init.js - initialization and configuration of Popcorn and the widgets
*/
if (typeof window.IriSP === "undefined") {
IriSP = {};
}
/* The Metadataplayer Object, single point of entry, replaces IriSP.init_player */
IriSP.Metadataplayer = function(config, video_metadata) {
IriSP.log("IriSP.Metadataplayer constructor");
for (var key in IriSP.guiDefaults) {
if (IriSP.guiDefaults.hasOwnProperty(key) && !config.gui.hasOwnProperty(key)) {
config.gui[key] = IriSP.guiDefaults[key]
}
}
var _container = document.getElementById(config.gui.container);
_container.innerHTML = '<h3 class="Ldt-Loader">Loading... Chargement...</h3>';
this.video_metadata = video_metadata;
this.sourceManager = new IriSP.Model.Directory();
this.config = config;
this.callbackQueue = [];
this.isLoaded = false;
this.loadLibs();
}
IriSP.Metadataplayer.prototype.toString = function() {
return 'Metadataplayer in #' + this.config.gui.container;
}
IriSP.Metadataplayer.prototype.deferCallback = function(_callback) {
var _this = this;
IriSP._.defer(function() {
_callback.call(_this);
});
}
IriSP.Metadataplayer.prototype.handleCallbacks = function() {
this.isLoaded = true;
while (this.callbackQueue.length) {
this.deferCallback(this.callbackQueue.splice(0,1)[0]);
}
}
IriSP.Metadataplayer.prototype.onLoad = function(_callback) {
if (this.isLoaded) {
this.deferCallback(_callback);
} else {
this.callbackQueue.push(_callback);
}
}
IriSP.Metadataplayer.prototype.loadLibs = function() {
IriSP.log("IriSP.Metadataplayer.prototype.loadLibs");
var $L = $LAB
.script(IriSP.getLib("underscore"))
.script(IriSP.getLib("Mustache"))
.script(IriSP.getLib("jQuery"))
.script(IriSP.getLib("swfObject"))
.wait()
.script(IriSP.getLib("jQueryUI"));
if (this.config.player.type === "jwplayer" || this.config.player.type === "auto") {
$L.script(IriSP.getLib("jwplayer"));
}
if (this.config.player.type !== "jwplayer" && this.config.player.type !== "allocine" && this.config.player.type !== "dailymotion") {
$L.script(IriSP.getLib("popcorn"));
}
/* widget specific requirements */
for(var _i = 0; _i < this.config.gui.widgets.length; _i++) {
var _t = this.config.gui.widgets[_i].type;
if (typeof IriSP.widgetsRequirements[_t] !== "undefined" && typeof IriSP.widgetsRequirements[_t].requires !== "undefined") {
$L.script(IriSP.getLib(IriSP.widgetsRequirements[_t].requires));
}
}
var _this = this;
IriSP.log($L);
$L.wait(function() {
_this.onLibsLoaded();
});
}
IriSP.Metadataplayer.prototype.onLibsLoaded = function() {
IriSP.log("IriSP.Metadataplayer.prototype.onLibsLoaded");
if (typeof IriSP.jQuery === "undefined" && typeof window.jQuery !== "undefined") {
IriSP.jQuery = window.jQuery.noConflict();
}
if (typeof IriSP._ === "undefined" && typeof window._ !== "undefined") {
IriSP._ = window._.noConflict();
}
IriSP.loadCss(IriSP.getLib("cssjQueryUI"));
IriSP.loadCss(this.config.gui.css);
this.videoData = this.loadMetadata(this.video_metadata);
this.$ = IriSP.jQuery('#' + this.config.gui.container);
this.$.css({
"width": this.config.gui.width,
"clear": "both"
});
if (typeof this.config.gui.height !== "undefined") {
this.$.css("height", this.config.gui.height);
}
var _this = this;
this.videoData.onLoad(function() {
_this.onVideoDataLoaded();
});
}
IriSP.Metadataplayer.prototype.loadMetadata = function(_metadataInfo) {
if (typeof _metadataInfo.serializer === "undefined" && typeof _metadataInfo.format !== "undefined") {
_metadataInfo.serializer = IriSP.serializers[_metadataInfo.format];
}
if (typeof _metadataInfo.url === "undefined" && typeof _metadataInfo.src !== "undefined") {
_metadataInfo.url = _metadataInfo.src;
}
if (typeof _metadataInfo.url !== "undefined" && typeof _metadataInfo.serializer !== "undefined") {
return this.sourceManager.remoteSource(_metadataInfo);
} else {
return this.sourceManager.newLocalSource(_metadataInfo);
}
}
IriSP.Metadataplayer.prototype.onVideoDataLoaded = function() {
if (typeof this.videoData !== "undefined" && typeof this.config.player.video === "undefined") {
var _media = this.videoData.currentMedia;
if (typeof _media !== "undefined") {
this.config.player.video = _media.video;
if (typeof _media.streamer !== "undefined") {
this.config.player.streamer = _media.streamer;
this.config.player.video = _media.video.replace(_media.streamer,'');
}
}
}
this.configurePopcorn();
this.widgets = [];
var _this = this;
for(var i = 0; i < this.config.gui.widgets.length; i++) {
this.loadWidget(this.config.gui.widgets[i], function(_widget) {
_this.widgets.push(_widget)
});
};
this.$.find('.Ldt-Loader').detach();
this.handleCallbacks();
}
IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) {
/* Creating containers if needed */
if (typeof _widgetConfig.container === "undefined") {
var _divs = this.layoutDivs(_widgetConfig.type);
_widgetConfig.container = _divs[0];
}
var _this = this;
if (typeof IriSP.Widgets[_widgetConfig.type] !== "undefined") {
IriSP._.defer(function() {
_callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig));
});
} else {
/* Loading Widget CSS */
if (typeof IriSP.widgetsRequirements[_widgetConfig.type] === "undefined" || typeof IriSP.widgetsRequirements[_widgetConfig.type].noCss === "undefined" || !IriSP.widgetsRequirements[_widgetConfig.type].noCss) {
IriSP.loadCss(IriSP.widgetsDir + '/' + _widgetConfig.type + '.css');
}
/* Loading Widget JS */
$LAB.script(IriSP.widgetsDir + '/' + _widgetConfig.type + '.js').wait(function() {
_callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig));
});
}
}
IriSP.Metadataplayer.prototype.configurePopcorn = function() {
IriSP.log("IriSP.Metadataplayer.prototype.configurePopcorn");
var pop,
ret = this.layoutDivs("video"),
containerDiv = ret[0],
spacerDiv = ret[1],
_this = this,
_types = {
"html5" : /\.(ogg|ogv|webm)$/,
"youtube" : /^(https?:\/\/)?(www\.)?youtube\.com/,
"dailymotion" : /^(https?:\/\/)?(www\.)?dailymotion\.com/
};
if (this.config.player.type === "auto") {
this.config.player.type = "jwplayer";
IriSP._(_types).each(function(_v, _k) {
if (_v.test(_this.config.player.video)) {
_this.config.player.type = _k
}
});
}
switch(this.config.player.type) {
/*
todo : dynamically create the div/video tag which
will contain the video.
*/
case "html5":
var _tmpId = Popcorn.guid("video"),
_videoEl = IriSP.jQuery('<video>');
_videoEl.attr({
"src" : this.config.player.video,
"id" : _tmpId
})
if(this.config.player.hasOwnProperty("width")) {
_videoEl.attr("width", this.config.player.width);
}
if(this.config.player.hasOwnProperty("height")) {
_videoEl.attr("height", this.config.player.height);
}
IriSP.jQuery("#" + containerDiv).append(_videoEl);
pop = Popcorn("#" + _tmpId);
break;
case "jwplayer":
var opts = IriSP.jQuery.extend({}, this.config.player);
delete opts.container;
delete opts.type;
opts.file = opts.video;
delete opts.video;
if(!opts.hasOwnProperty("flashplayer")) {
opts.flashplayer = IriSP.jwplayer_swf_path;
}
if(!opts.hasOwnProperty("controlbar.position")) {
opts["controlbar.position"] = "none";
}
pop = new IriSP.PopcornReplacement.jwplayer("#" + containerDiv, opts);
break;
case "youtube":
// Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
IriSP.jQuery("#" + containerDiv).css({
width : this.config.player.width + "px",
height : this.config.player.height + "px"
});
var _urlparts = this.config.player.video.split(/[?&]/),
_params = {};
for (var _j = 1; _j < _urlparts.length; _j++) {
var _ppart = _urlparts[_j].split('=');
_params[_ppart[0]] = decodeURIComponent(_ppart[1]);
}
_params.controls = 0;
_params.modestbranding = 1;
_url = _urlparts[0] + '?' + IriSP.jQuery.param(_params);
pop = Popcorn.youtube("#" + containerDiv, _url);
break;
case "dailymotion":
pop = new IriSP.PopcornReplacement.dailymotion("#" + containerDiv, this.config.player);
break;
case "mashup":
pop = new IriSP.PopcornReplacement.mashup("#" + containerDiv, this.config.player);
break;
case "allocine":
/* pass the options as-is to the allocine player and let it handle everything */
pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, this.config.player);
break;
default:
pop = undefined;
};
this.popcorn = pop;
}
/** create a subdiv with an unique id, and a spacer div as well.
@param widgetName the name of the widget.
@return an array of the form [createdivId, spacerdivId].
*/
IriSP.Metadataplayer.prototype.layoutDivs = function(_name) {
if (typeof(_name) === "undefined") {
_name = "";
}
var newDiv = IriSP._.uniqueId(this.config.gui.container + "_widget_" + _name + "_"),
spacerDiv = IriSP._.uniqueId("LdtPlayer_spacer_"),
divHtml = IriSP.jQuery('<div>')
.attr("id",newDiv)
.css({
width: this.config.gui.width + "px",
position: "relative",
clear: "both"
}),
spacerHtml = IriSP.jQuery('<div>')
.attr("id",spacerDiv)
.css({
width: this.config.gui.width + "px",
height: this.config.gui.spacer_div_height + "px",
position: "relative",
clear: "both"
});
this.$.append(divHtml);
this.$.append(spacerHtml);
return [newDiv, spacerDiv];
};
/* utils.js - various utils that don't belong anywhere else */
IriSP.jqEscape = function(_text) {
return _text.replace(/(:|\.)/g,'\\$1');
}
IriSP.getLib = function(lib) {
if (IriSP.libFiles.useCdn && typeof IriSP.libFiles.cdn[lib] == "string") {
return IriSP.libFiles.cdn[lib];
}
if (typeof IriSP.libFiles.locations[lib] == "string") {
return IriSP.libFiles.locations[lib];
}
if (typeof IriSP.libFiles.inDefaultDir[lib] == "string") {
return IriSP.libFiles.defaultDir + '/' + IriSP.libFiles.inDefaultDir[lib];
}
}
IriSP._cssCache = [];
IriSP.loadCss = function(_cssFile) {
if (IriSP._(IriSP._cssCache).indexOf(_cssFile) === -1) {
IriSP.jQuery("<link>", {
rel : "stylesheet",
type : "text/css",
href : _cssFile
}).appendTo('head');
IriSP._cssCache.push(_cssFile);
}
}
IriSP.log = function() {
if (typeof console !== "undefined" && typeof IriSP.logging !== "undefined" && IriSP.logging) {
console.log.apply(console, arguments);
}
}
/* wrapper that simulates popcorn.js because
popcorn is a bit unstable at the time */
IriSP.PopcornReplacement = {
};
/** base class for our popcorn-compatible players.
*/
IriSP.PopcornReplacement.player = function(container, options) {
/* the jwplayer calls the callbacks in the global space so we need to
preserve them this way */
if (typeof IriSP._ === "undefined") {
return;
}
this.callbacks = {
onReady: IriSP._.bind(this.__initApi, this),
onTime: IriSP._.bind(this.__timeHandler, this),
onPlay: IriSP._.bind(this.__playHandler, this),
onPause: IriSP._.bind(this.__pauseHandler, this),
onSeek: IriSP._.bind(this.__seekHandler, this)
};
this.media = {
"paused": true,
"muted": false
};
this.container = container.replace(/^#/,''); //eschew the '#'
this.msgPump = {}; /* dictionnary used to receive and send messages */
this.__codes = []; /* used to schedule the execution of a piece of code in
a segment (similar to the popcorn.code plugin). */
this._options = options;
};
IriSP.PopcornReplacement.player.prototype.listen = function(msg, callback) {
if (!this.msgPump.hasOwnProperty(msg))
this.msgPump[msg] = [];
this.msgPump[msg].push(callback);
};
IriSP.PopcornReplacement.player.prototype.trigger = function(msg, params) {
if (!this.msgPump.hasOwnProperty(msg))
return;
var d = this.msgPump[msg];
for(var i = 0; i < d.length; i++) {
d[i].call(window, params);
}
};
IriSP.PopcornReplacement.player.prototype.guid = function(prefix) {
var str = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
return prefix + str;
};
/** init the api after that flash player has been setup - called by the callback
defined by the embedded flash player
*/
IriSP.PopcornReplacement.player.prototype.__initApi = function() {
this.trigger("loadedmetadata"); // we've done more than loading metadata of course,
// but popcorn doesn't need to know more.
this.media.muted = this.playerFns.getMute();
/* some programmed segments are supposed to be run at the beginning */
var i = 0;
for(i = 0; i < this.__codes.length; i++) {
var c = this.__codes[i];
if (0 == c.start) {
c.onStart();
}
if (0 == c.end) {
c.onEnd();
}
}
};
IriSP.PopcornReplacement.player.prototype.currentTime = function(time) {
if (typeof(time) === "undefined") {
return this.playerFns.getPosition();
} else {
var currentTime = +time;
this.playerFns.seek(currentTime);
return currentTime;
}
};
IriSP.PopcornReplacement.player.prototype.play = function() {
this.media.paused = false;
this.trigger("play");
//IriSP.PopcornReplacement.trigger("playing");
this.playerFns.play();
};
IriSP.PopcornReplacement.player.prototype.pause = function() {
// if ( !this.media.paused ) {
this.media.paused = true;
this.trigger( "pause" );
this.playerFns.pause();
// }
};
IriSP.PopcornReplacement.player.prototype.muted = function(val) {
if (typeof(val) !== "undefined") {
if (this.playerFns.getMute() !== val) {
if (val) {
this.playerFns.setMute(true);
this.media.muted = true;
} else {
this.playerFns.setMute(false);
this.media.muted = false;
}
this.trigger( "volumechange" );
}
return this.playerFns.getMute();
} else {
return this.playerFns.getMute();
}
};
IriSP.PopcornReplacement.player.prototype.volume = function(val) {
if (typeof this.playerFns.getVolume == "undefined" || typeof this.playerFns.setVolume == "undefined") {
return false;
}
var _vol = this.playerFns.getVolume();
if (typeof(val) !== "undefined" && parseFloat(val) !== NaN) {
val = Math.max(0, Math.min(1, val));
if (parseFloat(val) != parseFloat(_vol)) {
this.playerFns.setVolume(val);
this.trigger("volumechange");
_vol = this.playerFns.getVolume();
}
}
return _vol;
};
IriSP.PopcornReplacement.player.prototype.mute = IriSP.PopcornReplacement.player.prototype.muted;
IriSP.PopcornReplacement.player.prototype.code = function(options) {
this.__codes.push(options);
return this;
};
/* called everytime the player updates itself
(onTime event)
*/
IriSP.PopcornReplacement.player.prototype.__timeHandler = function(event) {
var pos = event.position;
var i = 0;
for(i = 0; i < this.__codes.length; i++) {
var c = this.__codes[i];
if (pos >= c.start && pos < c.end &&
pos - 1 <= c.start) {
c.onStart();
}
if (pos > c.start && pos > c.end &&
pos - 1 <= c.end) {
c.onEnd();
}
}
this.trigger("timeupdate");
};
IriSP.PopcornReplacement.player.prototype.__seekHandler = function(event) {
var i = 0;
for(i = 0; i < this.__codes.length; i++) {
var c = this.__codes[i];
if (event.position >= c.start && event.position < c.end) {
c.onEnd();
}
}
for(i = 0; i < this.__codes.length; i++) {
var c = this.__codes[i];
if (typeof(event.offset) === "undefined")
event.offset = 0;
if (event.offset >= c.start && event.offset < c.end) {
c.onStart();
}
}
/* this signal sends as an extra argument the position in the video.
As far as I know, this argument is not provided by popcorn */
this.trigger("seeked", event.offset);
};
IriSP.PopcornReplacement.player.prototype.__playHandler = function(event) {
this.media.paused = false;
this.trigger("play");
};
IriSP.PopcornReplacement.player.prototype.__pauseHandler = function(event) {
this.media.paused = true;
this.trigger("pause");
};
IriSP.PopcornReplacement.player.prototype.roundTime = function() {
var currentTime = this.currentTime();
return Math.round(currentTime);
};/* model.js is where data is stored in a standard form, whatever the serializer */
IriSP.Model = {
_SOURCE_STATUS_EMPTY : 0,
_SOURCE_STATUS_WAITING : 1,
_SOURCE_STATUS_READY : 2,
_ID_AUTO_INCREMENT : 0,
getUID : function() {
return "autoid-" + (++this._ID_AUTO_INCREMENT);
},
regexpFromTextOrArray : function(_textOrArray) {
function escapeText(_text) {
return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
}
return new RegExp( '('
+ (
typeof _textOrArray === "string"
? escapeText(_textOrArray)
: IriSP._(_textOrArray).map(escapeText).join("|")
)
+ ')',
'gim'
);
},
isoToDate : function(_str) {
// http://delete.me.uk/2005/03/iso8601.html
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = _str.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); }
if (d[5]) { date.setDate(d[5]); }
if (d[7]) { date.setHours(d[7]); }
if (d[8]) { date.setMinutes(d[8]); }
if (d[10]) { date.setSeconds(d[10]); }
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
var _res = new Date();
_res.setTime(Number(time));
return _res;
},
dateToIso : function(d) {
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'
}
}
/*
* IriSP.Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID)
*/
IriSP.Model.List = function(_directory) {
Array.call(this);
this.directory = _directory;
this.idIndex = [];
if (typeof _directory == "undefined") {
console.trace();
throw "Error : new IriSP.Model.List(directory): directory is undefined";
}
}
IriSP.Model.List.prototype = new Array();
IriSP.Model.List.prototype.getElement = function(_id) {
return this[_id];
}
IriSP.Model.List.prototype.hasId = function(_id) {
return (IriSP._(this.idIndex).indexOf(_id) !== -1);
}
/* On recent browsers, forEach and map are defined and do what we want.
* Otherwise, we'll use the Underscore.js functions
*/
if (typeof Array.prototype.forEach === "undefined") {
IriSP.Model.List.prototype.forEach = function(_callback) {
var _this = this;
IriSP._(this).forEach(function(_value, _key) {
_callback(_value, _key, _this);
});
}
}
if (typeof Array.prototype.map === "undefined") {
IriSP.Model.List.prototype.map = function(_callback) {
var _this = this;
return IriSP._(this).map(function(_value, _key) {
return _callback(_value, _key, _this);
});
}
}
IriSP.Model.List.prototype.pluck = function(_key) {
return this.map(function(_value) {
return _value[_key];
});
}
/* We override Array's filter function because it doesn't return an IriSP.Model.List
*/
IriSP.Model.List.prototype.filter = function(_callback) {
var _this = this,
_res = new IriSP.Model.List(this.directory);
_res.addElements(IriSP._(this).filter(function(_value, _key) {
return _callback(_value, _key, _this);
}));
return _res;
}
IriSP.Model.List.prototype.slice = function(_start, _end) {
var _res = new IriSP.Model.List(this.directory);
_res.addElements(Array.prototype.slice.call(this, _start, _end));
return _res;
}
IriSP.Model.List.prototype.splice = function(_start, _end) {
var _res = new IriSP.Model.List(this.directory);
_res.addElements(Array.prototype.splice.call(this, _start, _end));
this.idIndex.splice(_start, _end);
return _res;
}
/* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
* and won't return a new IriSP.Model.List
*/
IriSP.Model.List.prototype.sortBy = function(_callback) {
var _this = this,
_res = new IriSP.Model.List(this.directory);
_res.addElements(IriSP._(this).sortBy(function(_value, _key) {
return _callback(_value, _key, _this);
}));
return _res;
}
/* Title and Description are basic information for (almost) all element types,
* here we can search by these criteria
*/
IriSP.Model.List.prototype.searchByTitle = function(_text) {
var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
return this.filter(function(_element) {
return _rgxp.test(_element.title);
});
}
IriSP.Model.List.prototype.searchByDescription = function(_text) {
var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
return this.filter(function(_element) {
return _rgxp.test(_element.description);
});
}
IriSP.Model.List.prototype.searchByTextFields = function(_text) {
var _rgxp = IriSP.Model.regexpFromTextOrArray(_text);
return this.filter(function(_element) {
return _rgxp.test(_element.description) || _rgxp.test(_element.title);
});
}
IriSP.Model.List.prototype.getTitles = function() {
return this.map(function(_el) {
return _el.title;
});
}
IriSP.Model.List.prototype.addId = function(_id) {
var _el = this.directory.getElement(_id)
if (!this.hasId(_id) && typeof _el !== "undefined") {
this.idIndex.push(_id);
Array.prototype.push.call(this, _el);
}
}
IriSP.Model.List.prototype.push = function(_el) {
if (typeof _el === "undefined") {
return;
}
var _index = (IriSP._(this.idIndex).indexOf(_el.id));
if (_index === -1) {
this.idIndex.push(_el.id);
Array.prototype.push.call(this, _el);
} else {
this[_index] = _el;
}
}
IriSP.Model.List.prototype.addIds = function(_array) {
var _l = _array.length,
_this = this;
IriSP._(_array).forEach(function(_id) {
_this.addId(_id);
});
}
IriSP.Model.List.prototype.addElements = function(_array) {
var _this = this;
IriSP._(_array).forEach(function(_el) {
_this.push(_el);
});
}
IriSP.Model.List.prototype.removeId = function(_id) {
var _index = (IriSP._(this.idIndex).indexOf(_id));
if (_index !== -1) {
this.splice(_index,1);
}
}
IriSP.Model.List.prototype.removeElement = function(_el) {
this.removeId(_el.id);
}
IriSP.Model.List.prototype.removeIds = function(_list) {
var _this = this;
IriSP._(_list).forEach(function(_id) {
_this.removeId(_id);
});
}
IriSP.Model.List.prototype.removeElements = function(_list) {
var _this = this;
IriSP._(_list).forEach(function(_el) {
_this.removeElement(_el);
});
}
/* A simple time management object, that helps converting millisecs to seconds and strings,
* without the clumsiness of the original Date object.
*/
IriSP.Model.Time = function(_milliseconds) {
this.milliseconds = 0;
this.setMilliseconds(_milliseconds);
}
IriSP.Model.Time.prototype.setMilliseconds = function(_milliseconds) {
var _ante = _milliseconds;
switch(typeof _milliseconds) {
case "string":
this.milliseconds = parseFloat(_milliseconds);
break;
case "number":
this.milliseconds = _milliseconds;
break;
case "object":
this.milliseconds = parseFloat(_milliseconds.valueOf());
break;
default:
this.milliseconds = 0;
}
if (this.milliseconds === NaN) {
this.milliseconds = _ante;
}
}
IriSP.Model.Time.prototype.setSeconds = function(_seconds) {
this.milliseconds = 1000 * _seconds;
}
IriSP.Model.Time.prototype.getSeconds = function() {
return Math.floor(this.milliseconds / 1000);
}
IriSP.Model.Time.prototype.getHMS = function() {
var _totalSeconds = Math.abs(this.getSeconds());
return {
hours : Math.floor(_totalSeconds / 3600),
minutes : (Math.floor(_totalSeconds / 60) % 60),
seconds : _totalSeconds % 60
}
}
IriSP.Model.Time.prototype.add = function(_milliseconds) {
this.milliseconds += new IriSP.Model.Time(_milliseconds).milliseconds;
}
IriSP.Model.Time.prototype.valueOf = function() {
return this.milliseconds;
}
IriSP.Model.Time.prototype.toString = function() {
function pad(_n) {
var _res = _n.toString();
while (_res.length < 2) {
_res = '0' + _res;
}
return _res;
}
var _hms = this.getHMS(),
_res = '';
if (_hms.hours) {
_res += pad(_hms.hours) + ':'
}
_res += pad(_hms.minutes) + ':' + pad(_hms.seconds);
return _res;
}
/* IriSP.Model.Reference handles references between elements
*/
IriSP.Model.Reference = function(_source, _idRef) {
this.source = _source;
if (typeof _idRef === "object") {
this.isList = true;
this.id = IriSP._(_idRef).map(function(_id) {
return _source.getNamespaced(_id).fullname;
});
} else {
this.isList = false;
this.id = _source.getNamespaced(_idRef).fullname;
}
this.refresh();
}
IriSP.Model.Reference.prototype.refresh = function() {
if (this.isList) {
this.contents = new IriSP.Model.List(this.source.directory);
this.contents.addIds(this.id);
} else {
this.contents = this.source.directory.getElement(this.id);
}
}
IriSP.Model.Reference.prototype.getContents = function() {
if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) {
this.refresh();
}
return this.contents;
}
IriSP.Model.Reference.prototype.isOrHasId = function(_idRef) {
if (this.isList) {
return (IriSP._(this.id).indexOf(_idRef) !== -1)
} else {
return (this.id == _idRef);
}
}
/* */
IriSP.Model.Element = function(_id, _source) {
this.elementType = 'element';
if (typeof _source === "undefined") {
return;
}
if (typeof _id === "undefined" || !_id) {
_id = IriSP.Model.getUID();
}
this.source = _source;
this.namespacedId = _source.getNamespaced(_id)
this.id = this.namespacedId.fullname;
this.title = "";
this.description = "";
this.source.directory.addElement(this);
}
IriSP.Model.Element.prototype.toString = function() {
return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
}
IriSP.Model.Element.prototype.setReference = function(_elementType, _idRef) {
this[_elementType] = new IriSP.Model.Reference(this.source, _idRef);
}
IriSP.Model.Element.prototype.getReference = function(_elementType) {
if (typeof this[_elementType] !== "undefined") {
return this[_elementType].getContents();
}
}
IriSP.Model.Element.prototype.getRelated = function(_elementType, _global) {
_global = (typeof _global !== "undefined" && _global);
var _this = this;
return this.source.getList(_elementType, _global).filter(function(_el) {
var _ref = _el[_this.elementType];
return _ref.isOrHasId(_this.id);
});
}
/* */
IriSP.Model.Media = function(_id, _source) {
IriSP.Model.Element.call(this, _id, _source);
this.elementType = 'media';
this.duration = new IriSP.Model.Time();
this.video = '';
}
IriSP.Model.Media.prototype = new IriSP.Model.Element();
IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
this.duration.setMilliseconds(_durationMs);
}
IriSP.Model.Media.prototype.getAnnotations = function() {
return this.getRelated("annotation");
}
IriSP.Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) {
var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
if (_annTypes.length) {
return this.getAnnotations().filter(function(_annotation) {
return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
});
} else {
return new IriSP.Model.List(this.source.directory)
}
}
/* */
IriSP.Model.Tag = function(_id, _source) {
IriSP.Model.Element.call(this, _id, _source);
this.elementType = 'tag';
}
IriSP.Model.Tag.prototype = new IriSP.Model.Element();
IriSP.Model.Tag.prototype.getAnnotations = function() {
return this.getRelated("annotation");
}
/* */
IriSP.Model.AnnotationType = function(_id, _source) {
IriSP.Model.Element.call(this, _id, _source);
this.elementType = 'annotationType';
}
IriSP.Model.AnnotationType.prototype = new IriSP.Model.Element();
IriSP.Model.AnnotationType.prototype.getAnnotations = function() {
return this.getRelated("annotation");
}
/* Annotation
* */
IriSP.Model.Annotation = function(_id, _source) {
IriSP.Model.Element.call(this, _id, _source);
this.elementType = 'annotation';
this.begin = new IriSP.Model.Time();
this.end = new IriSP.Model.Time();
}
IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
this.begin.setMilliseconds(_beginMs);
}
IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
this.end.setMilliseconds(_beginMs);
}
IriSP.Model.Annotation.prototype.setMedia = function(_idRef) {
this.setReference("media", _idRef);
}
IriSP.Model.Annotation.prototype.getMedia = function() {
return this.getReference("media");
}
IriSP.Model.Annotation.prototype.setAnnotationType = function(_idRef) {
this.setReference("annotationType", _idRef);
}
IriSP.Model.Annotation.prototype.getAnnotationType = function() {
return this.getReference("annotationType");
}
IriSP.Model.Annotation.prototype.setTags = function(_idRefs) {
this.setReference("tag", _idRefs);
}
IriSP.Model.Annotation.prototype.getTags = function() {
return this.getReference("tag");
}
IriSP.Model.Annotation.prototype.getTagTexts = function() {
return this.getTags().getTitles();
}
IriSP.Model.Annotation.prototype.getDuration = function() {
return new IriSP.Model.Time(this.end.milliseconds - this.begin.milliseconds)
}
/* */
IriSP.Model.MashedAnnotation = function(_mashup, _annotation) {
IriSP.Model.Element.call(this, _mashup.namespacedId.name + "_" + _annotation.namespacedId.name, _annotation.source);
this.elementType = 'mashedAnnotation';
this.annotation = _annotation;
this.begin = new IriSP.Model.Time(_mashup.duration);
this.end = new IriSP.Model.Time(_mashup.duration + _annotation.getDuration());
this.title = this.annotation.title;
this.description = this.annotation.description;
this.color = this.annotation.color;
}
IriSP.Model.MashedAnnotation.prototype = new IriSP.Model.Element(null);
IriSP.Model.MashedAnnotation.prototype.getMedia = function() {
return this.annotation.getReference("media");
}
IriSP.Model.MashedAnnotation.prototype.getAnnotationType = function() {
return this.annotation.getReference("annotationType");
}
IriSP.Model.MashedAnnotation.prototype.getTags = function() {
return this.annotation.getReference("tag");
}
IriSP.Model.MashedAnnotation.prototype.getTagTexts = function() {
return this.annotation.getTags().getTitles();
}
/* */
IriSP.Model.Mashup = function(_id, _source) {
IriSP.Model.Element.call(this, _id, _source);
this.elementType = 'mashup';
this.duration = new IriSP.Model.Time();
this.segments = new IriSP.Model.List(_source.directory);
this.medias = new IriSP.Model.List(_source.directory);
}
IriSP.Model.Mashup.prototype = new IriSP.Model.Element();
IriSP.Model.Mashup.prototype.addSegment = function(_annotation) {
var _mashedAnnotation = new IriSP.Model.MashedAnnotation(this, _annotation);
this.duration.setMilliseconds(_mashedAnnotation.end);
this.segments.push(_mashedAnnotation);
this.medias.push(_annotation.getMedia());
}
IriSP.Model.Mashup.prototype.addSegmentById = function(_elId) {
var _annotation = this.source.getElement(_elId);
if (typeof _annotation !== "undefined") {
this.addSegment(_annotation);
}
}
IriSP.Model.Mashup.prototype.getAnnotations = function() {
return this.segments;
}
IriSP.Model.Mashup.prototype.getMedias = function() {
return this.medias;
}
IriSP.Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) {
var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
if (_annTypes.length) {
return this.getAnnotations().filter(function(_annotation) {
return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
});
} else {
return new IriSP.Model.List(this.source.directory)
}
}
IriSP.Model.Mashup.prototype.getAnnotationAtTime = function(_time) {
var _list = this.segments.filter(function(_annotation) {
return _annotation.begin <= _time && _annotation.end > _time;
});
if (_list.length) {
return _list[0];
} else {
return undefined;
}
}
IriSP.Model.Mashup.prototype.getMediaAtTime = function(_time) {
var _annotation = this.getAnnotationAtTime(_time);
if (typeof _annotation !== "undefined") {
return _annotation.getMedia();
} else {
return undefined;
}
}
/* */
IriSP.Model.Source = function(_config) {
this.status = IriSP.Model._SOURCE_STATUS_EMPTY;
if (typeof _config !== "undefined") {
var _this = this;
IriSP._(_config).forEach(function(_v, _k) {
_this[_k] = _v;
})
this.callbackQueue = [];
this.contents = {};
if (typeof this.namespace === "undefined") {
this.namespace = "metadataplayer";
} else {
if (typeof this.namespaceUrl === "undefined" && typeof this.url !== "undefined") {
var _matches = this.url.match(/(^[^?&]+|[^?&][a-zA-Z0-9_%=?]+)/g),
_url = _matches[0];
if (_matches.length > 1) {
_matches = IriSP._(_matches.slice(1)).reject(function(_txt) {
return /\?$/.test(_txt);
});
}
if (_matches.length > 0) {
_url += '?' + _matches.join('&');
}
this.namespaceUrl = _url;
}
}
if (typeof this.namespaceUrl === "undefined") {
this.namespaceUrl = "http://ldt.iri.centrepompidou.fr/";
}
this.directory.addNamespace(this.namespace, this.namespaceUrl);
this.get();
}
}
IriSP.Model.Source.prototype.getNamespaced = function(_id) {
var _tab = _id.split(':');
if (_tab.length > 1) {
return {
namespace : _tab[0],
name : _tab[1],
fullname : _id
}
} else {
return {
namespace : this.namespace,
name : _id,
fullname : this.namespace + ':' + _id
}
}
}
IriSP.Model.Source.prototype.unNamespace = function(_id) {
if (typeof _id !== "undefined") {
return _id.replace(this.namespace + ':', '');
}
}
IriSP.Model.Source.prototype.addList = function(_listId, _contents) {
if (typeof this.contents[_listId] === "undefined") {
this.contents[_listId] = new IriSP.Model.List(this.directory);
}
this.contents[_listId].addElements(_contents);
}
IriSP.Model.Source.prototype.getList = function(_listId, _global) {
_global = (typeof _global !== "undefined" && _global);
if (_global || typeof this.contents[_listId] === "undefined") {
return this.directory.getGlobalList().filter(function(_e) {
return (_e.elementType === _listId);
});
} else {
return this.contents[_listId];
}
}
IriSP.Model.Source.prototype.forEach = function(_callback) {
var _this = this;
IriSP._(this.contents).forEach(function(_value, _key) {
_callback.call(_this, _value, _key);
})
}
IriSP.Model.Source.prototype.getElement = function(_elId) {
return this.directory.getElement(this.getNamespaced(_elId).fullname);
}
IriSP.Model.Source.prototype.setCurrentMediaId = function(_idRef) {
if (typeof _idRef !== "undefined") {
this.currentMedia = this.getElement(_idRef);
}
}
IriSP.Model.Source.prototype.setDefaultCurrentMedia = function() {
if (typeof this.currentMedia === "undefined" && this.getMedias().length) {
this.currentMedia = this.getMedias()[0];
}
}
IriSP.Model.Source.prototype.listNamespaces = function(_excludeSelf) {
var _this = this,
_nsls = [],
_excludeSelf = (typeof _excludeSelf !== "undefined" && _excludeSelf);
this.forEach(function(_list) {
IriSP._(_list).forEach(function(_el) {
var _ns = _el.id.replace(/:.*$/,'');
if (IriSP._(_nsls).indexOf(_ns) === -1 && (!_excludeSelf || _ns !== _this.namespace)) {
_nsls.push(_ns);
}
})
});
return _nsls;
}
IriSP.Model.Source.prototype.get = function() {
this.status = IriSP.Model._SOURCE_STATUS_WAITING;
this.handleCallbacks();
}
/* We defer the callbacks calls so they execute after the queue is cleared */
IriSP.Model.Source.prototype.deferCallback = function(_callback) {
var _this = this;
IriSP._.defer(function() {
_callback.call(_this);
});
}
IriSP.Model.Source.prototype.handleCallbacks = function() {
this.status = IriSP.Model._SOURCE_STATUS_READY;
while (this.callbackQueue.length) {
this.deferCallback(this.callbackQueue.splice(0,1)[0]);
}
}
IriSP.Model.Source.prototype.onLoad = function(_callback) {
if (this.status === IriSP.Model._SOURCE_STATUS_READY) {
this.deferCallback(_callback);
} else {
this.callbackQueue.push(_callback);
}
}
IriSP.Model.Source.prototype.serialize = function() {
return this.serializer.serialize(this);
}
IriSP.Model.Source.prototype.deSerialize = function(_data) {
this.serializer.deSerialize(_data, this);
}
IriSP.Model.Source.prototype.getAnnotations = function(_global) {
_global = (typeof _global !== "undefined" && _global);
return this.getList("annotation", _global);
}
IriSP.Model.Source.prototype.getMedias = function(_global) {
_global = (typeof _global !== "undefined" && _global);
return this.getList("media", _global);
}
IriSP.Model.Source.prototype.getTags = function(_global) {
_global = (typeof _global !== "undefined" && _global);
return this.getList("tag", _global);
}
IriSP.Model.Source.prototype.getMashups = function(_global) {
_global = (typeof _global !== "undefined" && _global);
return this.getList("mashup", _global);
}
IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
_global = (typeof _global !== "undefined" && _global);
return this.getList("annotationType", _global);
}
IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) {
_global = (typeof _global !== "undefined" && _global);
var _res = new IriSP.Model.List(this.directory),
_annTypes = this.getAnnotationTypes(_global).searchByTitle(_title);
_annTypes.forEach(function(_annType) {
_res.addElements(_annType.getAnnotations(_global));
})
return _res;
}
IriSP.Model.Source.prototype.getDuration = function() {
var _m = this.currentMedia;
if (typeof _m !== "undefined") {
return this.currentMedia.duration;
}
}
/* */
IriSP.Model.RemoteSource = function(_config) {
IriSP.Model.Source.call(this, _config);
}
IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source();
IriSP.Model.RemoteSource.prototype.get = function() {
this.status = IriSP.Model._SOURCE_STATUS_WAITING;
var _this = this;
this.serializer.loadData(this.url, function(_result) {
_this.deSerialize(_result);
_this.handleCallbacks();
});
}
/* */
IriSP.Model.Directory = function() {
this.remoteSources = {};
this.elements = {};
this.namespaces = {};
}
IriSP.Model.Directory.prototype.addNamespace = function(_namespace, _url) {
this.namespaces[_namespace] = _url;
}
IriSP.Model.Directory.prototype.remoteSource = function(_properties) {
var _config = IriSP._({ directory: this }).extend(_properties);
if (typeof this.remoteSources[_properties.url] === "undefined") {
this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config);
}
return this.remoteSources[_properties.url];
}
IriSP.Model.Directory.prototype.newLocalSource = function(_properties) {
var _config = IriSP._({ directory: this }).extend(_properties),
_res = new IriSP.Model.Source(_config);
return _res;
}
IriSP.Model.Directory.prototype.getElement = function(_id) {
return this.elements[_id];
}
IriSP.Model.Directory.prototype.addElement = function(_element) {
this.elements[_element.id] = _element;
}
IriSP.Model.Directory.prototype.getGlobalList = function() {
var _res = new IriSP.Model.List(this);
_res.addIds(IriSP._(this.elements).keys());
return _res;
}
/* */
IriSP.language = 'en';
IriSP.libFiles = {
defaultDir : "js/libs/",
inDefaultDir : {
underscore : "underscore-min.js",
Mustache : "mustache.js",
jQuery : "jquery.min.js",
jQueryUI : "jquery-ui.min.js",
swfObject : "swfobject.js",
cssjQueryUI : "jquery-ui.css",
popcorn : "popcorn-complete.min.js",
jwplayer : "jwplayer.js",
raphael : "raphael-min.js",
tracemanager : "tracemanager.js"
},
locations : {
// use to define locations outside defautl_dir
},
cdn : {
jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.js",
swfObject : "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js",
cssjQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css"
},
useCdn : false
}
IriSP.widgetsDir = 'widgets';
IriSP.widgetsRequirements = {
Sparkline: {
noCss: true,
requires: "raphael"
},
Arrow: {
noCss: true,
requires: "raphael"
},
Mediafragment: {
noCss: true
},
Trace : {
noCss: true,
requires: "tracemanager"
}
}
IriSP.guiDefaults = {
width : 640,
container : 'LdtPlayer',
spacer_div_height : 0
}
/* Definition of an ancestor for the Widget classes */
if (typeof IriSP.Widgets === "undefined") {
IriSP.Widgets = {}
}
/**
* @class IriSP.Widget is an "abstract" class. It's mostly used to define some properties common to every widget.
*
* Note that widget constructors are never called directly by the user. Instead, the widgets are instantiated by functions
* defined in init.js
*
* @constructor
* @param player - a reference to the player widget
* @param config - configuration options for the widget
*/
IriSP.Widgets.Widget = function(player, config) {
if( typeof player === "undefined") {
/* Probably an abstract call of the class when
* individual widgets set their prototype */
return;
}
/* Setting all the configuration options */
var _type = config.type,
_config = IriSP._.defaults({}, config, player.config.gui.default_options, this.defaults),
_this = this;
IriSP._(_config).forEach(function(_value, _key) {
_this[_key] = _value;
});
if (typeof this.width === "undefined") {
this.width = player.config.gui.width;
}
/* Setting this.player at the end in case it's been overriden
* by a configuration option of the same name :-(
*/
this.player = player;
/* Getting metadata */
this.source = player.loadMetadata(this.metadata);
/* Call draw when loaded */
this.source.onLoad(function() {
_this.draw();
});
/* Adding classes and html attributes */
this.$ = IriSP.jQuery('#' + this.container);
this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type);
/* Does the widget require other widgets ? */
if (typeof this.requires !== "undefined") {
for (var _i = 0; _i < this.requires.length; _i++) {
var _subconfig = this.requires[_i];
_subconfig.container = IriSP._.uniqueId(this.container + '_' + _subconfig.type + '_');
this.$.append(IriSP.jQuery('<div>').attr("id",_subconfig.container));
this.player.loadWidget(_subconfig, function(_widget) {
_this[_subconfig.type.replace(/^./,function(_s){return _s.toLowerCase();})] = _widget
});
}
}
this.l10n = (typeof this.messages[IriSP.language] !== "undefined" ? this.messages[IriSP.language] : this.messages["en"]);
};
IriSP.Widgets.Widget.prototype.defaults = {}
IriSP.Widgets.Widget.prototype.template = '';
IriSP.Widgets.Widget.prototype.messages = {"en":{}};
IriSP.Widgets.Widget.prototype.templateToHtml = function(_template) {
return Mustache.to_html(_template, this);
}
IriSP.Widgets.Widget.prototype.renderTemplate = function() {
this.$.append(this.templateToHtml(this.template));
}
IriSP.Widgets.Widget.prototype.functionWrapper = function(_name) {
var _this = this,
_function = this[_name];
if (typeof _function !== "undefined") {
return function() {
return _function.apply(_this, Array.prototype.slice.call(arguments, 0));
}
} else {
console.log("Error, Unknown function IriSP." + this.type + "." + _name)
}
}
IriSP.Widgets.Widget.prototype.bindPopcorn = function(_popcornEvent, _functionName) {
this.player.popcorn.listen(_popcornEvent, this.functionWrapper(_functionName))
}
IriSP.Widgets.Widget.prototype.getWidgetAnnotations = function() {
var _curmedia = this.source.currentMedia;
return typeof this.annotation_type !== "undefined" && this.annotation_type ? _curmedia.getAnnotationsByTypeTitle(this.annotation_type) : _curmedia.getAnnotations();
}
/**
* This method responsible of drawing a widget on screen.
*/
IriSP.Widgets.Widget.prototype.draw = function() {
/* implemented by "sub-classes" */
};
/**
* Optional method if you want your widget to support redraws.
*/
IriSP.Widgets.Widget.prototype.redraw = function() {
/* implemented by "sub-classes" */
};
/* To wrap a player the develop should create a new class derived from
the IriSP.PopcornReplacement.player and defining the correct functions */
/** allocine player wrapper */
IriSP.PopcornReplacement.allocine = function(container, options) {
// console.log("Calling allocine player");
/* appel du parent pour initialiser les structures communes à tous les players */
IriSP.PopcornReplacement.player.call(this, container, options);
var _this = this;
/* Définition des fonctions de l'API - */
this.playerFns = {
play : function() {
return _this.apiCall("play");
},
pause : function() {
return _this.apiCall("pause");
},
getPosition : function() {
return _this.apiCall("getSeek","return") || 0;
},
seek : function(pos) {
return _this.apiCall("seek",pos);
},
getMute : function() {
return _this.apiCall("getMute","return");
},
setMute : function(p) {
return _this.apiCall("setMute", p);
}
}
window.onReady = function() {
_this.ready();
};
window.onAllocineStateChange = function(_state) {
_this.stateHandler(_state)
}
window.onTime = function(_progress) {
_this.progressHandler(_progress)
};
var _flashVars = {
"streamFMS" : true,
"adVast" : false,
"lg" : "fr_cinecast",
"autoPlay" : options.autoPlay,
"directVideoTitle" : "",
"urlAcData" : options.urlAcData,
"directVideoPath" : options.video,
"host" : "http://allocine.fr"
}
if (typeof IriSP.__jsonMetadata["medias"][0].meta == "object" && typeof IriSP.__jsonMetadata["medias"][0].meta.subtitles == "string") {
_flashVars.subTitlePath = IriSP.__jsonMetadata["medias"][0].meta.subtitles;
}
var params = {
"allowScriptAccess" : "always",
"wmode": "opaque",
"flashvars" : IriSP.jQuery.param(_flashVars),
"allowfullscreen" : true
};
var atts = {
id : this.container
};
swfobject.embedSWF(options.acPlayerUrl, this.container, options.width, options.height, "10", null, null, params, atts);
};
IriSP.PopcornReplacement.allocine.prototype = new IriSP.PopcornReplacement.player("", {});
IriSP.PopcornReplacement.allocine.prototype.ready = function() {
this.player = document.getElementById(this.container);
this.player.addEventListener("onStateChange", "onAllocineStateChange");
this.player.cueVideoByUrl(this._options.video);
this.callbacks.onReady();
};
IriSP.PopcornReplacement.allocine.prototype.progressHandler = function(progressInfo) {
this.callbacks.onTime({
position: progressInfo.mediaTime
});
}
IriSP.PopcornReplacement.allocine.prototype.apiCall = function(_method, _arg) {
if (this.player) {
try {
if (typeof _arg == "undefined") {
return this.player.sendToActionScript(_method);
} else {
return this.player.sendToActionScript(_method, _arg);
}
} catch(e) {
console.error('Exception while requesting AcPlayer for "' + _method + (typeof _arg == "undefined" ? '' : '" with argument "' + _arg ) + '"\n', e);
return false;
}
} else {
return false;
}
}
IriSP.PopcornReplacement.allocine.prototype.stateHandler = function(state) {
console.log("stateHandler");
switch(state) {
case 1:
this.callbacks.onPlay();
break;
case 2:
this.callbacks.onPause();
break;
case 3:
this.callbacks.onSeek({
position: this.player.getCurrentTime()
});
break;
/*
case 5:
this.callbacks.onReady();
break;
*/
}
};/* To wrap a player the develop should create a new class derived from
the IriSP.PopcornReplacement.player and defining the correct functions */
/** jwplayer player wrapper */
IriSP.PopcornReplacement.dailymotion = function(container, options) {
/* Appel du constructeur de la classe parente */
IriSP.PopcornReplacement.player.call(this, container, options);
var _this = this;
/* Définition des fonctions de commande :
this.playerFns.play, .pause, .getPosition, .seek,
.getMute, .setMute, .getVolume, .setVolume
doivent être rattachés aux fonctions du player
* */
this.playerFns = {
play : function() {
if (_this.player) {
return _this.player.playVideo();
} else {
return false;
}
},
pause : function() {
if (_this.player) {
return _this.player.pauseVideo();
} else {
return false;
}
},
getPosition : function() {
if (_this.player) {
return _this.player.getCurrentTime();
} else {
return 0;
}
},
seek : function(pos) {
if (_this.player) {
return _this.player.seekTo(pos);
} else {
return false;
}
},
getMute : function() {
if (_this.player) {
return _this.player.isMuted();
} else {
return false;
}
},
setMute : function(p) {
if (_this.player) {
if (p) {
_this.player.mute();
}
else {
_this.player.unMute();
}
}
},
getVolume : function() {
if (_this.player) {
return _this.player.getVolume() / 100;
} else {
return false;
}
},
setVolume : function(p) {
if (_this.player) {
_this.player.setVolume(Math.floor(100 * p));
}
},
}
/* Dailymotion utilise un système de fonctions référencées dans
* des variables globales pour la gestion des événements.
*/
window.onDailymotionPlayerReady = function() {
_this.onReady();
};
window.onDailymotionStateChange = function(_state) {
_this.onStateChange(_state);
}
window.onDailymotionVideoProgress = function(_progress) {
_this.onProgress(_progress);
}
var params = {
"allowScriptAccess" : "always",
"wmode": "opaque"
};
var atts = {
id : this.container
};
swfobject.embedSWF("http://www.dailymotion.com/swf?chromeless=1&enableApi=1", this.container, options.width, options.height, "8", null, null, params, atts);
};
IriSP.PopcornReplacement.dailymotion.prototype = new IriSP.PopcornReplacement.player("", {});
IriSP.PopcornReplacement.dailymotion.prototype.onReady = function() {
this.player = document.getElementById(this.container);
this.player.addEventListener("onStateChange", "onDailymotionStateChange");
this.player.addEventListener("onVideoProgress", "onDailymotionVideoProgress");
this.player.cueVideoByUrl(this._options.video);
this.callbacks.onReady();
};
IriSP.PopcornReplacement.dailymotion.prototype.onProgress = function(progressInfo) {
this.callbacks.onTime({
position: progressInfo.mediaTime
});
}
IriSP.PopcornReplacement.dailymotion.prototype.onStateChange = function(state) {
switch(state) {
case 1:
this.callbacks.onPlay();
break;
case 2:
this.callbacks.onPause();
break;
case 3:
this.callbacks.onSeek({
position: this.player.getCurrentTime()
});
break;
}
};/* To wrap a player the develop should create a new class derived from
the IriSP.PopcornReplacement.player and defining the correct functions */
/** jwplayer player wrapper */
IriSP.PopcornReplacement.jwplayer = function(container, options) {
/* appel du parent pour initialiser les structures communes à tous les players */
IriSP.PopcornReplacement.player.call(this, container, options);
this.media.duration = options.duration; /* optional */
/* Définition des fonctions de l'API - */
this.playerFns = {
play: function() { return jwplayer(this.container).play(); },
pause: function() { return jwplayer(this.container).pause(); },
getPosition: function() { return jwplayer(this.container).getPosition(); },
seek: function(pos) { return jwplayer(this.container).seek(pos); },
getMute: function() { return jwplayer(this.container).getMute() },
setMute: function(p) { return jwplayer(this.container).setMute(p); },
getVolume: function() { return jwplayer(this.container).getVolume() / 100; },
setVolume: function(p) { return jwplayer(this.container).setVolume(Math.floor(100*p)); }
}
options.events = this.callbacks;
jwplayer(this.container).setup(options);
};
IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
/* To wrap a player the develop should create a new class derived from
the IriSP.PopcornReplacement.player and defining the correct functions */
/** jwplayer player wrapper */
IriSP.PopcornReplacement.mashup = function(container, options) {
/* Appel du constructeur de la classe parente */
IriSP.PopcornReplacement.player.call(this, container, options);
var _this = this;
/* Définition des fonctions de commande :
this.playerFns.play, .pause, .getPosition, .seek,
.getMute, .setMute, .getVolume, .setVolume
doivent être rattachés aux fonctions du player
* */
this.playerFns = {
play : function() {
if (_this.player) {
return _this.player.playVideo();
} else {
return false;
}
},
pause : function() {
if (_this.player) {
return _this.player.pauseVideo();
} else {
return false;
}
},
getPosition : function() {
if (_this.player) {
return _this.player.getCurrentTime();
} else {
return 0;
}
},
seek : function(pos) {
if (_this.player) {
return _this.player.seekTo(pos);
} else {
return false;
}
},
getMute : function() {
if (_this.player) {
return _this.player.isMuted();
} else {
return false;
}
},
setMute : function(p) {
if (_this.player) {
if (p) {
_this.player.mute();
}
else {
_this.player.unMute();
}
}
},
getVolume : function() {
if (_this.player) {
return _this.player.getVolume() / 2;
} else {
return false;
}
},
setVolume : function(p) {
if (_this.player) {
_this.player.setVolume(Math.floor(2 * p));
}
},
}
/* Dailymotion utilise un système de fonctions référencées dans
* des variables globales pour la gestion des événements.
*/
window.onBabPlayerReady = function() {
_this.onReady();
};
window.onBabStateChange = function(_state) {
_this.onStateChange(_state);
}
window.onBabVideoProgress = function(_progress) {
_this.onProgress(_progress);
}
var params = {
allowScriptAccess : "always",
wmode: "transparent",
quality: "high",
menu: true,
bgcolor: "#869ca7"
};
var atts = {
id : this.container
};
var flashvars = {
urlData: options.mashup_xml
};
swfobject.embedSWF(options.mashup_swf, this.container, options.width, options.height, "8", null, flashvars, params, atts);
};
IriSP.PopcornReplacement.mashup.prototype = new IriSP.PopcornReplacement.player("", {});
IriSP.PopcornReplacement.mashup.prototype.onReady = function() {
this.player = document.getElementById(this.container);
this.callbacks.onReady();
};
IriSP.PopcornReplacement.mashup.prototype.onProgress = function(progressInfo) {
this.callbacks.onTime({
position: progressInfo.mediaTime
});
}
IriSP.PopcornReplacement.mashup.prototype.onStateChange = function(state) {
switch(state) {
case 1:
this.callbacks.onPlay();
break;
case 2:
this.callbacks.onPause();
break;
case 3:
this.callbacks.onSeek({
position: this.player.getCurrentTime()
});
break;
}
};/* Used when Putting annotations on the platform */
if (typeof IriSP.serializers === "undefined") {
IriSP.serializers = {}
}
IriSP.serializers.ldt_annotate = {
types : {
annotation : {
serialized_name : "annotations",
serializer : function(_data, _source) {
return {
begin: _data.begin.milliseconds,
end: _data.end.milliseconds,
content: {
data: _data.description
},
tags: _data.getTagTexts(),
media: _source.unNamespace(_data.getMedia().id),
title: _data.title,
type_title: _data.getAnnotationType().title,
type: _source.unNamespace(_data.getAnnotationType().id)
}
}
}
},
serialize : function(_source) {
var _res = {},
_this = this;
_source.forEach(function(_list, _typename) {
if (typeof _this.types[_typename] !== "undefined") {
_res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
return _this.types[_typename].serializer(_el, _source);
});
}
});
_res.meta = {
creator: _source.creator,
created: _source.created
}
return JSON.stringify(_res);
}
}/* LDT Platform Serializer */
if (typeof IriSP.serializers === "undefined") {
IriSP.serializers = {}
}
IriSP.serializers.ldt = {
types : {
media : {
serialized_name : "medias",
deserializer : function(_data, _source) {
var _res = new IriSP.Model.Media(_data.id, _source);
_res.video = (
typeof _data.url !== "undefined"
? _data.url
: (
typeof _data.href !== "undefined"
? _data.href
: null
)
);
if (typeof _data.meta.item !== "undefined" && _data.meta.item.name === "streamer") {
_res.streamer = _data.meta.item.value;
}
_res.title = _data.meta["dc:title"];
_res.description = _data.meta["dc:description"];
_res.setDuration(_data.meta["dc:duration"]);
return _res;
},
serializer : function(_data, _source) {
return {
id : _source.unNamespace(_data.id),
url : _data.video,
meta : {
"dc:title" : _data.title,
"dc:description" : _data.description,
"dc:duration" : _data.duration.milliseconds
}
}
}
},
tag : {
serialized_name : "tags",
model_name : "tag",
deserializer : function(_data, _source) {
var _res = new IriSP.Model.Tag(_data.id, _source);
_res.title = _data.meta["dc:title"];
return _res;
},
serializer : function(_data, _source) {
return {
id : _source.unNamespace(_data.id),
meta : {
"dc:title" : _data.title
}
}
}
},
annotationType : {
serialized_name : "annotation-types",
deserializer : function(_data, _source) {
var _res = new IriSP.Model.AnnotationType(_data.id, _source);
_res.title = _data["dc:title"];
_res.description = _data["dc:description"];
return _res;
},
serializer : function(_data, _source) {
return {
id : _source.unNamespace(_data.id),
"dc:title" : _data.title,
"dc:description" : _data.description
}
}
},
annotation : {
serialized_name : "annotations",
deserializer : function(_data, _source) {
var _res = new IriSP.Model.Annotation(_data.id, _source);
_res.title = _data.content.title || "";
_res.description = _data.content.description || "";
if (typeof _data.content.img !== "undefined" && _data.content.img.src !== "undefined") {
_res.thumbnail = _data.content.img.src;
}
_res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]);
if (typeof _data.color !== "undefined") {
var _c = parseInt(_data.color).toString(16);
while (_c.length < 6) {
_c = '0' + _c;
}
_res.color = '#' + _c;
}
_res.setMedia(_data.media, _source);
_res.setAnnotationType(_data.meta["id-ref"]);
_res.setTags(IriSP._(_data.tags).pluck("id-ref"));
_res.setBegin(_data.begin);
_res.setEnd(_data.end);
_res.creator = _data.meta["dc:creator"] || "";
_res.project = _data.meta.project || "";
if (typeof _data.meta["dc:source"] !== "undefined" && typeof _data.meta["dc:source"].content !== "undefined") {
_res.source = JSON.parse(_data.meta["dc:source"].content);
}
return _res;
},
serializer : function(_data, _source) {
return {
id : _source.unNamespace(_data.id),
begin : _data.begin.milliseconds,
end : _data.end.milliseconds,
content : {
title : _data.title,
description : _data.description
},
media : _source.unNamespace(_data.media.id),
meta : {
"id-ref" : _source.unNamespace(_data.annotationType.id),
"dc:created" : IriSP.Model.dateToIso(_data.created),
"dc:creator" : _data.creator,
project : _source.projectId
},
tags : IriSP._(_data.tag.id).map(function(_id) {
return {
"id-ref" : _source.unNamespace(_id)
}
})
}
}
},
mashup : {
serialized_name : "mashups",
deserializer : function(_data, _source) {
var _res = new IriSP.Model.Mashup(_data.id, _source);
_res.title = _data.meta["dc:title"];
_res.description = _data.meta["dc:description"];
for (var _i = 0; _i < _data.segments.length; _i++) {
_res.addSegmentById(_data.segments[_i]);
}
return _res;
},
serializer : function(_data, _source) {
return {
"dc:title": _data.title,
"dc:description": _data.description,
segments: _data.segments.map(function(_annotation) {
return _source.unNamespace(_id);
})
}
}
}
},
serialize : function(_source) {
var _res = {},
_this = this;
_source.forEach(function(_list, _typename) {
if (typeof _this.types[_typename] !== "undefined") {
_res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
return _this.types[_typename].serializer(_el, _source);
});
}
});
return JSON.stringify(_res);
},
loadData : function(_url, _callback) {
IriSP.jQuery.getJSON(_url, _callback)
},
deSerialize : function(_data, _source) {
if (typeof _data !== "object" || _data === null) {
return;
}
IriSP._(this.types).forEach(function(_type, _typename) {
var _listdata = _data[_type.serialized_name];
if (typeof _listdata !== "undefined" && _listdata !== null) {
var _list = new IriSP.Model.List(_source.directory);
if (_listdata.hasOwnProperty("length")) {
var _l = _listdata.length;
for (var _i = 0; _i < _l; _i++) {
_list.push(_type.deserializer(_listdata[_i], _source));
}
} else {
_list.push(_type.deserializer(_listdata, _source));
}
_source.addList(_typename, _list);
}
});
if (typeof _data.meta !== "undefined") {
_source.projectId = _data.meta.id;
}
if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
_source.setCurrentMediaId(_data.meta.main_media["id-ref"]);
}
_source.setDefaultCurrentMedia();
}
}