diff -r 4f1b7aa04ec7 -r ed1126cd2b80 metadataplayer edwin/metadataplayer/LdtPlayer-core.js --- a/metadataplayer edwin/metadataplayer/LdtPlayer-core.js Tue Jun 26 15:53:42 2012 +0200 +++ b/metadataplayer edwin/metadataplayer/LdtPlayer-core.js Fri Jun 29 12:12:38 2012 +0200 @@ -77,8 +77,13 @@ .script(IriSP.getLib("underscore")) .script(IriSP.getLib("Mustache")) .script(IriSP.getLib("jQuery")) - .script(IriSP.getLib("swfObject")) - .wait() + .script(IriSP.getLib("swfObject")); + + if (typeof JSON == "undefined") { + $L.script(IriSP.getLib("json")); + } + + $L.wait() .script(IriSP.getLib("jQueryUI")); if (this.config.player.type === "jwplayer" || this.config.player.type === "auto") { @@ -147,8 +152,32 @@ 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") { + + var _media; + + if (typeof this.videoData.mainMedia !== "undefined") { + _media = this.videoData.getElement(this.videoData.mainMedia); + } + + if (this.config.player.type === "mashup" || this.config.player.type === "mashup-html") { + if (typeof _media === "undefined" || _media.elementType !== "mashup") { + var _mashups = this.videoData.getMashups(); + if (_mashups.length) { + _media = _mashups[0]; + } + } + } else { + if (typeof _media === "undefined" || _media.elementType !== "media") { + var _medias = this.videoData.getMedias(); + if (_medias.length) { + _media = _medias[0]; + } + } + } + + this.videoData.currentMedia = _media; + + if (typeof _media !== "undefined" && typeof _media.video !== "undefined") { this.config.player.video = _media.video; if (typeof _media.streamer !== "undefined") { this.config.player.streamer = _media.streamer; @@ -197,7 +226,7 @@ IriSP.Metadataplayer.prototype.configurePopcorn = function() { IriSP.log("IriSP.Metadataplayer.prototype.configurePopcorn"); var pop, - ret = this.layoutDivs("video"), + ret = this.layoutDivs("video",this.config.player.height || undefined), containerDiv = ret[0], spacerDiv = ret[1], _this = this, @@ -307,6 +336,10 @@ pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, this.config.player); break; + case "mashup-html": + pop = new IriSP.PopcornReplacement.htmlMashup("#" + containerDiv, this.config.player, this.videoData); + break; + default: pop = undefined; }; @@ -318,7 +351,7 @@ @param widgetName the name of the widget. @return an array of the form [createdivId, spacerdivId]. */ -IriSP.Metadataplayer.prototype.layoutDivs = function(_name) { +IriSP.Metadataplayer.prototype.layoutDivs = function(_name, _height) { if (typeof(_name) === "undefined") { _name = ""; } @@ -339,6 +372,9 @@ position: "relative", clear: "both" }); + if (typeof _height !== "undefined") { + divHtml.css("height", _height); + } this.$.append(divHtml); this.$.append(spacerHtml); @@ -384,60 +420,47 @@ /* wrapper that simulates popcorn.js because popcorn is a bit unstable at the time */ +/* Popcorn.code replacement has been disabled. It didn't work properly and was not even used */ + 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.media = { + "paused": true, + "muted": false + }; - 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; - + this.container = container.replace(/^#/,''); //remove '#' at beginning + this.msgPump = {}; /* dictionnary used to receive and send messages */ + this._options = options; + }; IriSP.PopcornReplacement.player.prototype.listen = function(msg, callback) { - if (!this.msgPump.hasOwnProperty(msg)) - this.msgPump[msg] = []; + if (!this.msgPump.hasOwnProperty(msg)) { + this.msgPump[msg] = []; + } + this.msgPump[msg].push(callback); +}; - this.msgPump[msg].push(callback); -}; +IriSP.PopcornReplacement.player.prototype.on = IriSP.PopcornReplacement.player.prototype.listen; 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); - } - + 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.emit = IriSP.PopcornReplacement.player.prototype.trigger; +/* 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); @@ -449,12 +472,12 @@ /** 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 */ + /* 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]; @@ -466,7 +489,9 @@ c.onEnd(); } } + }; +*/ IriSP.PopcornReplacement.player.prototype.currentTime = function(time) { if (typeof(time) === "undefined") { @@ -481,16 +506,13 @@ 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.trigger("pause"); this.playerFns.pause(); -// } }; IriSP.PopcornReplacement.player.prototype.muted = function(val) { @@ -530,89 +552,47 @@ 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.mute = function() { + this.muted(true); +} -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]; +IriSP.PopcornReplacement.player.prototype.unmute = function() { + this.muted(false); +} - 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 */ +};/* TODO: Separate Project-specific data from Source */ + +/* 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, + _ID_BASE : (function(_d) { + function pad(n){return n<10 ? '0'+n : n} + function fillrand(n) { + var _res = '' + for (var i=0; i 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); @@ -1291,34 +1223,7 @@ } 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; + return this.directory.getElement(_elId); } IriSP.Model.Source.prototype.get = function() { @@ -1427,14 +1332,12 @@ 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) { + if (typeof _properties !== "object" || typeof _properties.url === "undefined") { + throw "Error : IriSP.Model.Directory.remoteSource(configuration): configuration.url is undefined"; + } var _config = IriSP._({ directory: this }).extend(_properties); if (typeof this.remoteSources[_properties.url] === "undefined") { this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config); @@ -1478,7 +1381,8 @@ jwplayer : "jwplayer.js", raphael : "raphael-min.js", tracemanager : "tracemanager.js", - jwPlayerSWF : "player.swf" + jwPlayerSWF : "player.swf", + json : "json2.js" }, locations : { // use to define locations outside defautl_dir @@ -1584,7 +1488,15 @@ } } - this.l10n = (typeof this.messages[IriSP.language] !== "undefined" ? this.messages[IriSP.language] : this.messages["en"]); + this.l10n = ( + typeof this.messages[IriSP.language] !== "undefined" + ? this.messages[IriSP.language] + : ( + IriSP.language.length > 2 && typeof this.messages[IriSP.language.substr(0,2)] !== "undefined" + ? this.messages[IriSP.language.substr(0,2)] + : this.messages["en"] + ) + ); }; @@ -1707,13 +1619,11 @@ this.player = document.getElementById(this.container); this.player.addEventListener("onStateChange", "onAllocineStateChange"); this.player.cueVideoByUrl(this._options.video); - this.callbacks.onReady(); + this.trigger("loadedmetadata"); }; IriSP.PopcornReplacement.allocine.prototype.progressHandler = function(progressInfo) { - this.callbacks.onTime({ - position: progressInfo.mediaTime - }); + this.trigger("timeupdate"); } @@ -1735,27 +1645,18 @@ } IriSP.PopcornReplacement.allocine.prototype.stateHandler = function(state) { - console.log("stateHandler"); switch(state) { case 1: - this.callbacks.onPlay(); + this.trigger("play"); break; case 2: - this.callbacks.onPause(); + this.trigger("pause"); break; case 3: - this.callbacks.onSeek({ - position: this.player.getCurrentTime() - }); + this.trigger("seeked"); break; - - /* - case 5: - this.callbacks.onReady(); - break; - */ } };/* To wrap a player the develop should create a new class derived from @@ -1869,31 +1770,26 @@ this.player.addEventListener("onVideoProgress", "onDailymotionVideoProgress"); this.player.cueVideoByUrl(this._options.video); - this.callbacks.onReady(); + this.trigger("loadedmetadata"); }; IriSP.PopcornReplacement.dailymotion.prototype.onProgress = function(progressInfo) { - - this.callbacks.onTime({ - position: progressInfo.mediaTime - }); + this.trigger("timeupdate"); } IriSP.PopcornReplacement.dailymotion.prototype.onStateChange = function(state) { switch(state) { case 1: - this.callbacks.onPlay(); + this.trigger("play"); break; case 2: - this.callbacks.onPause(); + this.trigger("pause"); break; case 3: - this.callbacks.onSeek({ - position: this.player.getCurrentTime() - }); + this.trigger("seeked"); break; } @@ -1907,12 +1803,13 @@ this.media.duration = options.duration; /* optional */ - var _player = jwplayer(this.container); + var _player = jwplayer(this.container), + _this = this; /* Définition des fonctions de l'API - */ this.playerFns = { - play: function() { return _player.play(); }, - pause: function() { return _player.pause(); }, + play: function() { return _player.play(true); }, + pause: function() { return _player.pause(true); }, getPosition: function() { return _player.getPosition(); }, seek: function(pos) { return _player.seek(pos); }, getMute: function() { return _player.getMute() }, @@ -1921,12 +1818,209 @@ setVolume: function(p) { return _player.setVolume(Math.floor(100*p)); } } - options.events = this.callbacks; + options.events = { + onReady: function() { + _this.trigger("loadedmetadata"); + }, + onTime: function() { + _this.trigger("timeupdate"); + }, + onPlay: function() { + _this.trigger("play"); + }, + onPause: function() { + _this.trigger("pause"); + }, + onSeek: function() { + _this.trigger("seeked"); + } + }; _player.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.htmlMashup = function(container, options, metadata) { + /* appel du parent pour initialiser les structures communes à tous les players */ + IriSP.PopcornReplacement.player.call(this, container, options); + + this.mashup = metadata.currentMedia; + this.$ = IriSP.jQuery(container); + + var _w = this.$.width(), + _h = this.$.height(), + _this = this; + + IriSP._(metadata.currentMedia.medias).each(function(_media) { + var _tmpId = Popcorn.guid("video"), + _videoEl = IriSP.jQuery('