--- a/web/res/metadataplayer/LdtPlayer-core.js Fri Jun 22 15:36:11 2012 +0200
+++ b/web/res/metadataplayer/LdtPlayer-core.js Tue Jun 26 19:06:09 2012 +0200
@@ -152,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;
@@ -396,64 +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] = [];
-
- this.msgPump[msg].push(callback);
+ if (!this.msgPump.hasOwnProperty(msg)) {
+ this.msgPump[msg] = [];
+ }
+ 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);
@@ -465,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];
@@ -482,7 +489,9 @@
c.onEnd();
}
}
+
};
+*/
IriSP.PopcornReplacement.player.prototype.currentTime = function(time) {
if (typeof(time) === "undefined") {
@@ -502,7 +511,7 @@
IriSP.PopcornReplacement.player.prototype.pause = function() {
this.media.paused = true;
- this.trigger( "pause" );
+ this.trigger("pause");
this.playerFns.pause();
};
@@ -551,74 +560,6 @@
this.muted(false);
}
-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();
@@ -1285,18 +1226,6 @@
return this.directory.getElement(_elId);
}
-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.get = function() {
this.status = IriSP.Model._SOURCE_STATUS_WAITING;
this.handleCallbacks();
@@ -1690,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");
}
@@ -1718,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
@@ -1852,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;
}
@@ -1890,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() },
@@ -1904,7 +1818,23 @@
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);
};
@@ -1927,11 +1857,15 @@
IriSP._(metadata.currentMedia.medias).each(function(_media) {
var _tmpId = Popcorn.guid("video"),
- _videoEl = IriSP.jQuery('<video>');
-
+ _videoEl = IriSP.jQuery('<video>'),
+ _videoUrl = _media.video;
+ if (typeof options.url_transform === "function") {
+ _videoUrl = options.url_transform(_videoUrl);
+ }
+
_videoEl
.attr({
- src : _media.video,
+ src : _videoUrl,
id : _tmpId,
width : _w,
height : _h
@@ -1945,27 +1879,39 @@
_this.$.append(_videoEl);
_media.videoEl = _videoEl;
_media.popcorn = Popcorn("#" + _tmpId);
+ _media.loadedMetadata = false;
+ _media.popcorn.on("loadedmetadata", function() {
+ _media.loadedMetadata = true;
+ var _allLoaded = true;
+ for (var _i = 0; _i < metadata.currentMedia.medias.length; _i++) {
+ _allLoaded = _allLoaded && metadata.currentMedia.medias[_i].loadedMetadata;
+ }
+ if (_allLoaded) {
+ _this.changeCurrentAnnotation();
+ _this.trigger("loadedmetadata");
+ }
+ });
_media.popcorn.on("timeupdate", function() {
if (!_this.media.paused && _media === _this.currentMedia) {
- var _time = _media.popcorn.currentTime();
- // var _status = "Timeupdate from " + _media.id + " at time " + _time;
+ var _time = Math.round( 1000 * _media.popcorn.currentTime() );
+// var _status = "Timeupdate from " + _media.id + " at time " + _time;
if ( _time < _this.segmentEnd ) {
if ( _time >= _this.segmentBegin ) {
_this.timecode = _time - _this.timedelta;
- // _status += " within segment";
+// _status += " within segment";
} else {
_this.timecode = _this.segmentBegin - _this.timedelta;
- _media.popcorn.currentTime(_this.segmentBegin);
- // _status += " before segment begin";
+ _media.popcorn.currentTime(_this.segmentBegin / 1000);
+// _status += " before segment";
}
} else {
_this.timecode = _this.segmentEnd - _this.timedelta;
_media.popcorn.pause();
_this.changeCurrentAnnotation();
- // _status += " after segment end";
+// _status += " after segment";
}
- /* _status += ", translated to " + _this.timecode;
- console.log(_status); */
+// _status += " (" + _this.segmentBegin + " to " + _this.segmentEnd + ")" + ", translated to " + _this.timecode;
+// console.log(_status);
_this.trigger("timeupdate");
}
});
@@ -1982,17 +1928,19 @@
_this.currentMedia.popcorn.pause();
},
getPosition: function() {
- return _this.timecode;
+ return _this.timecode / 1000;
},
seek: function(pos) {
- _this.timecode = pos;
+ _this.timecode = Math.round(pos * 1000);
_this.changeCurrentAnnotation();
},
getMute: function() {
- return
+ var _res = (
typeof _this.currentMedia !== "undefined"
? _this.currentMedia.popcorn.muted()
- : false;
+ : false
+ );
+ return _res;
},
setMute: function(p) {
var _mute = !!p;
@@ -2001,10 +1949,12 @@
}
},
getVolume: function() {
- return
+ var _res = (
typeof _this.currentMedia !== "undefined"
? _this.currentMedia.popcorn.volume()
- : .5;
+ : .5
+ );
+ return _res;
},
setVolume: function(_vol) {
for (var _i = 0; _i < _this.mashup.medias.length; _i++) {
@@ -2012,29 +1962,28 @@
}
}
}
-/*
- options.events = this.callbacks;
-
- _player.setup(options);
- */
+
};
IriSP.PopcornReplacement.htmlMashup.prototype = new IriSP.PopcornReplacement.player("", {});
IriSP.PopcornReplacement.htmlMashup.prototype.changeCurrentAnnotation = function() {
- var _annotation = this.mashup.getAnnotationAtTime( 1000 * this.timecode );
+ var _annotation = this.mashup.getAnnotationAtTime( this.timecode );
if (typeof _annotation == "undefined") {
if (typeof this.currentMedia !== "undefined") {
this.currentMedia.popcorn.pause();
- this.media.paused = true;
+ if (!this.media.paused) {
+ this.media.paused = true;
+ this.trigger("pause");
+ }
}
return;
}
if (_annotation !== this.currentAnnotation) {
this.currentAnnotation = _annotation;
- this.segmentBegin = this.currentAnnotation.annotation.begin.getSeconds();
- this.segmentEnd = this.currentAnnotation.annotation.end.getSeconds();
- this.timedelta = this.segmentBegin - this.currentAnnotation.begin.getSeconds();
+ this.segmentBegin = this.currentAnnotation.annotation.begin.milliseconds;
+ this.segmentEnd = this.currentAnnotation.annotation.end.milliseconds;
+ this.timedelta = this.segmentBegin - this.currentAnnotation.begin.milliseconds;
this.currentMedia = this.currentAnnotation.getMedia();
for (var _i = 0; _i < this.mashup.medias.length; _i++) {
@@ -2045,9 +1994,28 @@
this.mashup.medias[_i].videoEl.show();
}
}
+/* PRELOADING */
+ var _this = this,
+ _preloadedMedias = [],
+ _toPreload = this.mashup.getAnnotations().filter(function(_a) {
+ return (_a.begin >= _this.currentAnnotation.end && _a.getMedia().id !== _this.currentMedia.id);
+ });
+ IriSP._(_toPreload).each(function(_a) {
+ var _media = _a.getMedia();
+ if (IriSP._(_preloadedMedias).indexOf(_media.id) === -1) {
+ _preloadedMedias.push(_media.id);
+ _media.popcorn.currentTime(_a.annotation.begin.getSeconds());
+ //console.log("Preloading ", _media.id, " at t=", _a.annotation.begin.getSeconds());
+ }
+ });
+
+// console.log("Changed segment: media="+ this.currentMedia.id + ", from=" + this.segmentBegin + " to=" + this.segmentEnd +", timedelta = ", this.timedelta)
+// } else {
+// console.log("changeCurrentAnnotation called, but segment hasn't changed");
}
if (this.currentMedia.popcorn.readyState()) {
- this.currentMedia.popcorn.currentTime(this.timecode + this.timedelta);
+ this.currentMedia.popcorn.currentTime( (this.timecode + this.timedelta) / 1000);
+ this.trigger("timeupdate");
}
if (!this.media.paused) {
this.currentMedia.popcorn.play();
@@ -2060,7 +2028,7 @@
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 :
@@ -2163,37 +2131,30 @@
IriSP.PopcornReplacement.mashup.prototype = new IriSP.PopcornReplacement.player("", {});
IriSP.PopcornReplacement.mashup.prototype.onReady = function() {
-
this.player = document.getElementById(this.container);
-
- this.callbacks.onReady();
+ this.trigger("loadedmetadata");
};
IriSP.PopcornReplacement.mashup.prototype.onProgress = function(progressInfo) {
-
- this.callbacks.onTime({
- position: progressInfo.mediaTime
- });
+ this.trigger("timeupdate");
}
IriSP.PopcornReplacement.mashup.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;
}
-
+
};/* LDT Platform Serializer */
if (typeof IriSP.serializers === "undefined") {
@@ -2330,23 +2291,30 @@
}
},
mashup : {
- serialized_name : "mashups",
+ serialized_name : "lists",
deserializer : function(_data, _source) {
+ if (typeof _data.meta !== "object" || typeof _data.meta.listtype !== "string" || _data.meta.listtype !== "mashup") {
+ return undefined;
+ }
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]);
+ for (var _i = 0; _i < _data.items.length; _i++) {
+ _res.addSegmentById(_data.items[_i]);
}
return _res;
},
serializer : function(_data, _source) {
return {
- "dc:title": _data.title,
- "dc:description": _data.description,
- segments: _data.segments.map(function(_annotation) {
+ meta : {
+ "dc:title": _data.title,
+ "dc:description": _data.description,
+ listtype: "mashup"
+ },
+ items: _data.segments.map(function(_annotation) {
return _id;
- })
+ }),
+ id: _data.id
}
}
}
@@ -2377,10 +2345,16 @@
if (_listdata.hasOwnProperty("length")) {
var _l = _listdata.length;
for (var _i = 0; _i < _l; _i++) {
- _list.push(_type.deserializer(_listdata[_i], _source));
+ var _element = _type.deserializer(_listdata[_i], _source);
+ if (typeof _element !== "undefined" && _element) {
+ _list.push(_element);
+ }
}
} else {
- _list.push(_type.deserializer(_listdata, _source));
+ var _element = _type.deserializer(_listdata, _source);
+ if (typeof _element !== "undefined" && _element) {
+ _list.push(_element);
+ }
}
}
_source.addList(_typename, _list);
@@ -2391,9 +2365,8 @@
}
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.mainMedia = _data.meta.main_media["id-ref"];
}
- _source.setDefaultCurrentMedia();
}
}