# HG changeset patch # User hamidouk # Date 1327334034 -3600 # Node ID 6b848824f18516fd7f643b46c9a5c59d6a171220 # Parent c464acb185d6f46a6ae1cab26fac07614c76ada4 updated player version. diff -r c464acb185d6 -r 6b848824f185 src/ldt/ldt/static/ldt/js/LdtPlayer-release.js --- a/src/ldt/ldt/static/ldt/js/LdtPlayer-release.js Thu Jan 19 10:48:06 2012 +0100 +++ b/src/ldt/ldt/static/ldt/js/LdtPlayer-release.js Mon Jan 23 16:53:54 2012 +0100 @@ -1085,7 +1085,7 @@ IriSP.annotation_template = "{{! template for an annotation displayed in a segmentWidget }}
"; IriSP.annotationWidget_template = "{{! template for the annotation widget }}
share on facebook share on twitter share on google+
"; IriSP.annotation_loading_template = "{{! template shown while the annotation widget is loading }}
 
Chargement...
"; -IriSP.annotationsListWidget_template = "{{! template for the annotation list widget }}
"; +IriSP.annotationsListWidget_template = "{{! template for the annotation list widget }}
"; IriSP.arrowWidget_template = "
"; IriSP.createAnnotationWidget_template = "{{! template for the annotation creation widget }}
Add keywords :
Submit
"; IriSP.createAnnotationWidget_festivalCinecast_template = "{{! template for the annotation creation widget specific for the cinecast festival}}
Add keywords :
Submit
"; @@ -1466,6 +1466,14 @@ return url; }; +/** Similar to substr but remove the last word if + we're breaking a word in two. + */ +IriSP.clean_substr = function(str, start, end) { + var s = str.substr(start, end).substr(start, end).split(" "); + s.pop(); + return s.join(" "); +}; /* for ie compatibility if (Object.prototype.__defineGetter__&&!Object.defineProperty) { Object.defineProperty=function(obj,prop,desc) { @@ -1584,6 +1592,7 @@ IriSP.libdir = "/mdp/src/js/libs/"; IriSP.jwplayer_swf_path = "/mdp/test/libs/player.swf"; +IriSP.platform_url = "http://localhost/pf"; IriSP.lib = { jQuery : "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js", @@ -1636,12 +1645,21 @@ }, "Main" : { autoplay: true - } - + }, + "AnnotationsListWidget" : { + ajax_mode: true, /* use ajax to get information about the annotations. + if set to false, only search in the annotations for the + current project. */ + ajax_url: IriSP.platform_url + "/ldtplatform/api/ldt/segments", /* partial + url of + where to + get the + ajax */ + ajax_granularity: 10000 /* how much ms should we look before and after the + current timecode */ + }, }; -IriSP.platform_url = "http://localhost/pf"; - IriSP.paths = { // "imgs": "/tweetlive/res/metadataplayer/src/css/imgs" "imgs": "/mdp/src/css/imgs" @@ -2237,6 +2255,8 @@ IriSP.Widget.call(this, Popcorn, config, Serializer); this.__counter = 0; this.__oldList = []; + + this.ajax_mode = IriSP.widgetsDefaults["AnnotationsListWidget"].ajax_mode; }; @@ -2257,7 +2277,7 @@ /** draw the annotation list */ IriSP.AnnotationsListWidget.prototype.drawList = function(force_redraw) { var _this = this; - + var view_type = this._serializer.getContributions(); var annotations = this._serializer._data.annotations; var currentTime = this._Popcorn.currentTime(); @@ -2308,9 +2328,8 @@ } this.__oldList = idList; /* save for next call */ - + if (typeof(force_redraw) !== "undefined") { - console.log("forced redraw"); this.do_redraw(list); } @@ -2323,11 +2342,74 @@ }; +IriSP.AnnotationsListWidget.prototype.ajaxRedraw = function(timecode) { + var pre_url = IriSP.widgetsDefaults["AnnotationsListWidget"].ajax_url; + var media_id = this._serializer.currentMedia()["id"]; + var duration = +this._serializer.currentMedia().meta["dc:duration"]; + + var begin_timecode = (Math.floor(this._Popcorn.currentTime()) - 300) * 1000; + if (begin_timecode < 0) + begin_timecode = 0; + + var end_timecode = (Math.floor(this._Popcorn.currentTime()) + 300) * 1000; + if (end_timecode > duration) + end_timecode = duration; + + var templ = Mustache.to_html("{{pre_url}}/{{media_id}}/{{begin_timecode}}/{{end_timecode}}", + {pre_url: pre_url, media_id: media_id, begin_timecode: begin_timecode, + end_timecode: end_timecode}); + + /* we create on the fly a serializer to get the ajax */ + var serializer = new IriSP.JSONSerializer(IriSP.__dataloader, templ); + serializer.sync(IriSP.wrap(this, function(json) { this.processJson(json, serializer) })); +}; + +/** process the received json - it's a bit hackish */ +IriSP.AnnotationsListWidget.prototype.processJson = function(json, serializer) { + /* FIXME: DRY the whole thing */ + var annotations = serializer._data.annotations; + if (IriSP.null_or_undefined(annotations)) + return; + + var view_types = serializer.getIds("Contributions"); + var l = []; + + for (i = 0; i < annotations.length; i++) { + var annotation = annotations[i]; + + console.log(view_types, annotation.meta["id-ref"]); + /* filter the annotations whose type is not the one we want */ + if (typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined" + && !IriSP.underscore.include(view_types, annotation.meta["id-ref"])) { + continue; + } + + var a = annotation; + var obj = {}; + + obj["id"] = a.id; + obj["title"] = a.content.title; + obj["desc"] = a.content.description; + obj["begin"] = IriSP.msToTime(annotation.begin); + obj["end"] = IriSP.msToTime(annotation.end); + + l.push(obj); + } + console.log(l); + this.do_redraw(l); +}; IriSP.AnnotationsListWidget.prototype.draw = function() { this.drawList(); - this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, function() { this.drawList(true); })); - this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.redraw)); + + if (!this.ajax_mode) { + this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, function() { this.drawList(true); })); + this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.redraw)); + } else { + this._Popcorn.listen("seeked", IriSP.wrap(this, this.ajaxRedraw)); + this._Popcorn.listen("paused", IriSP.wrap(this, this.ajaxRedraw)); + } + }; IriSP.AnnotationsListWidget.prototype.redraw = function() { @@ -2544,11 +2626,7 @@ IriSP.createAnnotationWidget.prototype.draw = function() { var _this = this; - if (this.cinecast_version) { - var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_festivalCinecast_template); - } else { - var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template); - } + var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template); this.selector.append(annotationMarkup); @@ -2761,14 +2839,21 @@ } else { this.showWaitScreen(); - this.sendLdtData(contents, function() { - if (_this.cinecast_version) { - if (_this._Popcorn.media.paused) - _this._Popcorn.play(); - } - - _this.showEndScreen(); - window.setTimeout(IriSP.wrap(_this, function() { this.showStartScreen(); }), 5000); + this.sendLdtData(contents, function(annotation) { + if (_this.cinecast_version) { + if (_this._Popcorn.media.paused) + _this._Popcorn.play(); + } + + _this.showEndScreen(annotation); + if (_this.cinecast_version) { + window.setTimeout(IriSP.wrap(_this, function() { this.showStartScreen(); }), 5000); + } + + // hide the slicer widget + if (!_this.cinecast_version) { + _this._Popcorn.trigger("IriSP.SliceWidget.hide"); + } }); } }; @@ -2784,12 +2869,17 @@ var annotation = apiJson["annotations"][0]; annotation["media"] = this._serializer.currentMedia()["id"]; + var duration_part = Math.round(this._serializer.currentMedia().meta["dc:duration"] / 20); - if (this.cinecast_version) { - if (typeof(this._currentAnnotation) !== "undefined") { - annotation["begin"] = this._currentAnnotation.begin; - annotation["end"] = this._currentAnnotation.end; - } + if (this.cinecast_version) { + annotation["begin"] = Math.round(this._Popcorn.currentTime() * 1000 - duration_part); + annotation["end"] = Math.round(this._Popcorn.currentTime() * 1000 + duration_part); + if (annotation["begin"] < 0) + annotation["begin"] = 0; + + if (annotation["end"] > this._serializer.currentMedia().meta["dc:duration"]) + annotation["end"] = this._serializer.currentMedia().meta["dc:duration"]; + } else { var duration = +this._serializer.currentMedia().meta["dc:duration"]; annotation["begin"] = +((duration * (this.sliceLeft / 100)).toFixed(0)); @@ -3632,7 +3722,7 @@ /* the last segment has no segment following it */ var pxWidth = endPixel - startPixel; - var divTitle = (annotation.content.title + " - " + annotation.content.description).substr(0,55); + var divTitle = IriSP.clean_substr(annotation.content.title + " -
" + annotation.content.description, 0, 132) + "..."; if (typeof(annotation.content.color) !== "undefined") var color = annotation.content.color; @@ -3819,41 +3909,44 @@ */ var currentX = this.leftHandle.position()["left"]; - var rightHandleX = this.rightHandle.position()["left"]; + var rightHandleX = Math.floor(this.rightHandle.position()["left"]); - if (currentX >= rightHandleX - 7 && ui.position.left >= this._leftHandleOldLeft) { + if (Math.floor(ui.position.left) >= rightHandleX - 7) { /* prevent the handle from moving past the right handle */ - ui.position.left = this._leftHandleOldLeft; + ui.position.left = rightHandleX - 7; } - - var increment = this.zoneLeft - (currentX + 7); + + this.zoneWidth = rightHandleX - Math.floor(ui.position.left) - 7; + this.zoneLeft = Math.floor(ui.position.left) + 8; - this.zoneWidth += increment; - this.zoneLeft = currentX + 7; this.sliceZone.css("width", this.zoneWidth); this.sliceZone.css("left", this.zoneLeft + "px"); + this._leftHandleOldLeft = Math.floor(this._leftHandleOldLeft); this.broadcastChanges(); - - this._leftHandleOldLeft = ui.position.left; + }; /** handle a dragging of the right handle */ IriSP.SliceWidget.prototype.rightHandleDragged = function(event, ui) { - var currentX = this.rightHandle.position()["left"]; - var leftHandleX = this.leftHandle.position()["left"]; + /* we have a special variable, this._leftHandleOldLeft, to keep the + previous position of the handle. We do that to know in what direction + is the handle being dragged + */ - if (currentX <= leftHandleX + 7 && ui.position.left <= this._rightHandleOldLeft) { - /* prevent the handle from moving past the right handle */ - ui.position.left = this._rightHandleOldLeft; - } + var currentX = this.leftHandle.position()["left"]; + var leftHandleX = Math.floor(this.leftHandle.position()["left"]); - var increment = currentX - (this.zoneLeft + this.zoneWidth); - - this.zoneWidth += increment; + if (Math.floor(ui.position.left) < leftHandleX + 7) { + /* prevent the handle from moving past the right handle */ + ui.position.left = leftHandleX + 7; + } + + this.zoneWidth = Math.floor(ui.position.left) - (leftHandleX + 7); + this.sliceZone.css("width", this.zoneWidth); + //this.sliceZone.css("left", this.zoneLeft + "px"); + this._rightHandleOldLeft = Math.floor(this._rightHandleOldLeft); this.broadcastChanges(); - - this._rightHandleOldLeft = ui.position.left; }; /** tell to the world that the coordinates of the slice have @@ -4058,35 +4151,57 @@ and the third is a div to react to clicks */ - var num_columns = (this.selector.width()) / IriSP.widgetsDefaults["SparklineWidget"].column_width; - var duration = +this._serializer.currentMedia().meta["dc:duration"]; - var time_step = duration / num_columns; /* the time interval between two columns */ - var results = []; - var i = 0; /* the index in the loop */ - - /* this algorithm makes one assumption : that the array is sorted - (it's done for us by the JSONSerializer). We go through the array - and count how many comments fall within a peculiar time piece. - As i is preserved between each iteration, it's O(n). - */ + var views = this._serializer._data.views; + var stat_view; + if (!IriSP.null_or_undefined(views)) { + + var i; + for (i = 0; i < views.length; i++) { + var view = views[i]; + if (view.id === "stat") { + stat_view = view; + break; + } + } + } - for(var j = 0; j < num_columns && i < this._serializer._data.annotations.length; j++) { - var count = 0; - var annotation_begin = +(this._serializer._data.annotations[i].begin); + // If we've found the correct view, feed the directly the data from the view + // to jquery sparkline. Otherwise, compute it ourselves. + if (!IriSP.null_or_undefined(stat_view)) { + console.log("sparklinewidget : using stats embedded in the json"); + var results = stat_view.meta.stat.split(","); + } else { + console.log("sparklinewidget : computing stats ourselves"); + var num_columns = (this.selector.width()) / IriSP.widgetsDefaults["SparklineWidget"].column_width; + var duration = +this._serializer.currentMedia().meta["dc:duration"]; + var time_step = duration / num_columns; /* the time interval between two columns */ + var results = []; + var i = 0; /* the index in the loop */ + + /* this algorithm makes one assumption : that the array is sorted + (it's done for us by the JSONSerializer). We go through the array + and count how many comments fall within a peculiar time piece. + As i is preserved between each iteration, it's O(n). + */ - while(annotation_begin >= j * time_step && annotation_begin <= (j + 1) * time_step ) { - count++; - i++; - if (i >= this._serializer._data.annotations.length) - break; + for(var j = 0; j < num_columns && i < this._serializer._data.annotations.length; j++) { + var count = 0; + var annotation_begin = +(this._serializer._data.annotations[i].begin); + + while(annotation_begin >= j * time_step && annotation_begin <= (j + 1) * time_step ) { + count++; + i++; + if (i >= this._serializer._data.annotations.length) + break; + + annotation_begin = +(this._serializer._data.annotations[i].begin); - annotation_begin = +(this._serializer._data.annotations[i].begin); + } + results.push(count); } - - results.push(count); } - + // save the results in an array so that we can re-use them when a new annotation // is added. this._results = results; @@ -4127,15 +4242,14 @@ var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000; var newTime = ((relX / width) * duration).toFixed(2); - - + this._Popcorn.trigger("IriSP.SparklineWidget.clicked", newTime); this._Popcorn.currentTime(newTime); }; /** react when a new annotation is added */ IriSP.SparklineWidget.prototype.handleNewAnnotation = function(annotation) { - var num_columns = (this.selector.width()) / IriSP.widgetsDefaults["SparklineWidget"].column_width; + var num_columns = this._results.length; var duration = +this._serializer.currentMedia().meta["dc:duration"]; var time_step = Math.round(duration / num_columns); /* the time interval between two columns */ var begin = +annotation.begin; @@ -4147,7 +4261,7 @@ width: this.width, height: this.height}); };IriSP.StackGraphWidget = function(Popcorn, config, Serializer) { IriSP.Widget.call(this, Popcorn, config, Serializer); -}; +} IriSP.StackGraphWidget.prototype = new IriSP.Widget(); @@ -4175,10 +4289,10 @@ }, ], _defaultDefColor = "#585858"; - this.height = (this._config.height ? this._config.height : 50); + this.height = this._config.height || 50; this.width = this.selector.width(); - this.isStreamGraph = (this._config.streamgraph ? this._config.streamgraph : false); - this.sliceCount = (this._config.slices ? this._config.slices : ~~(this.width/(this.isStreamGraph ? 20 : 5))); + this.isStreamGraph = this._config.streamgraph || false; + this.sliceCount = this._config.slices || ~~(this.width/(this.isStreamGraph ? 20 : 5)); this.tagconf = (this._config.tags ? this._config.tags : _defaultTags); @@ -4196,17 +4310,19 @@ var _annotationType = this._serializer.getTweets(), _sliceDuration = ~~ ( this.duration / this.sliceCount), - _annotations = IriSP._(this._serializer._data.annotations).filter(function(_a) { - return ( _a.meta && _a.meta["id-ref"] && ( _a.meta["id-ref"] == _annotationType ) ); - }), - _groupedAnnotations = IriSP._(_annotations).groupBy(function(_a) { - return ~~ (_a.begin / _sliceDuration); + _annotations = this._serializer._data.annotations, + _groupedAnnotations = IriSP._.range(this.sliceCount).map(function(_i) { + return _annotations.filter(function(_a){ + return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration) + }); }), _max = IriSP._(_groupedAnnotations).max(function(_g) { return _g.length }).length, _scale = this.height / _max, - _width = this.width / this.sliceCount; + _width = this.width / this.sliceCount + _showTitle = !this._config.excludeTitle, + _showDescription = !this._config.excludeDescription; var _paths = this.tagconf.map(function() { @@ -4221,7 +4337,7 @@ return 0; }); for (var j = 0; j < _group.length; j++){ - var _txt = _group[j].content.description; + var _txt = (_showTitle ? _group[j].content.title : '') + ' ' + (_showDescription ? _group[j].content.description : '') var _tags = this.tagconf.map(function(_tag) { return (_txt.search(_tag.regexp) == -1 ? 0 : 1) }), @@ -4301,11 +4417,16 @@ this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler)); var _this = this; this.selector - .click(function(_e) { - _this.clickHandler(_e); - }) - .mousemove(function(_e) { - _this.updateTooltip(_e); + .click(IriSP.wrap(this, this.clickHandler)) + .mousemove(function(event) { + _this.updateTooltip(event); + + // Also tell the world where the mouse is hovering. + var relX = event.pageX - _this.selector.offset().left; + var duration = _this._serializer.currentMedia().meta["dc:duration"]; + var Time = ((relX / _this.width) * duration).toFixed(2); + _this._Popcorn.trigger("IriSP.StackGraphWidget.mouseOver", Time); + }) .mouseout(function() { _this.TooltipWidget.hide(); @@ -4313,7 +4434,7 @@ "opacity" : 0, }) }) -}; +} IriSP.StackGraphWidget.prototype.timeUpdateHandler = function() { var _currentTime = this._Popcorn.currentTime(), @@ -4324,7 +4445,7 @@ this.ligneProgress.attr({ "path" : "M" + _x + " 0L" + _x + " " + this.height, }) -}; +} IriSP.StackGraphWidget.prototype.clickHandler = function(event) { /* Ctrl-C Ctrl-V'ed from another widget @@ -4356,8 +4477,78 @@ "x" : _segment * _width, "opacity" : .4, }) -}; - +} + +IriSP.TagCloudWidget = function(Popcorn, config, Serializer) { + IriSP.Widget.call(this, Popcorn, config, Serializer); +} + +IriSP.TagCloudWidget.prototype = new IriSP.Widget(); + +IriSP.TagCloudWidget.prototype.draw = function() { + + var _stopwords = [ + 'aussi', 'and', 'avec', 'aux', 'car', 'cette', 'comme', 'dans', 'donc', 'des', 'elle', 'est', + 'être', 'eux', 'fait', 'ici', 'ils', 'les', 'leur', 'leurs', 'mais', 'mes', 'même', 'mon', 'notre', + 'nos', 'nous', 'ont', 'par', 'pas', 'peu', 'pour', 'que', 'qui', 'ses' ,'son', 'sont', 'sur', + 'tes', 'très', 'the', 'ton', 'tous', 'tout', 'une', 'votre', 'vos', 'vous' + ], + _regexpword = /[^\s\.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g, + _words = {}, + _showTitle = !this._config.excludeTitle, + _showDescription = !this._config.excludeDescription, + _tagCount = this._config.tagCount || 30; + + IriSP._(this._serializer._data.annotations).each(function(_annotation) { + if (_annotation.content && _annotation.content.description) { + var _txt = (_showTitle ? _annotation.content.title : '') + ' ' + (_showDescription ? _annotation.content.description : '') + IriSP._(_txt.toLowerCase().match(_regexpword)).each(function(_mot) { + if (_stopwords.indexOf(_mot) == -1) { + _words[_mot] = 1 + (_words[_mot] || 0); + } + }) + } + }); + + _words = IriSP._(_words) + .chain() + .map(function(_v, _k) { + return { + "word" : _k, + "count" : _v, + } + }) + .filter(function(_v) { + return _v.count > 2; + }) + .sortBy(function(_v) { + return - _v.count; + }) + .first(_tagCount) + .value(); + var _max = _words[0].count, + _min = Math.min(_words[_words.length - 1].count, _max - 1), + _scale = 16 / Math.sqrt(_max - _min), + _html = ''; + this.selector + .addClass("Ldt-TagCloud") + .html(_html); + +} /* this widget displays a small tooltip */ IriSP.TooltipWidget = function(Popcorn, config, Serializer) { IriSP.Widget.call(this, Popcorn, config, Serializer); @@ -4379,7 +4570,7 @@ }; IriSP.TooltipWidget.prototype.clear = function() { - this.selector.find(".tiptext").text(""); + this.selector.find(".tiptext").html(""); }; IriSP.TooltipWidget.prototype.show = function(text, color, x, y) { @@ -4389,7 +4580,7 @@ this.selector.find(".tipcolor").css("background-color", color); this._displayedText = text; - this.selector.find(".tiptext").text(text); + this.selector.find(".tiptext").html(text); if (x < 0) x = 0; @@ -4912,7 +5103,7 @@ @param name of the ligne de temps */ IriSP.JSONSerializer.prototype.getId = function(name) { - if (typeof(this._data.lists) === "undefined" || this._data.lists === null) + if (IriSP.null_or_undefined(this._data["annotation-types"])) return; name = name.toUpperCase(); @@ -4928,6 +5119,20 @@ return id; }; +/** return the list of id's of the ligne de temps which contains name + @param name of the ligne de temps +*/ +IriSP.JSONSerializer.prototype.getIds = function(name) { + if (IriSP.null_or_undefined(this._data["annotation-types"])) + return; + + name = name.toUpperCase(); + var e = []; + e = IriSP.underscore.filter(this._data["annotation-types"], + function(entry) { return (entry["dc:title"].toUpperCase().indexOf(name) !== -1) }); + return IriSP.underscore.pluck(e, "id"); +}; + /** return the id of the ligne de temps named "Chapitrage" */ IriSP.JSONSerializer.prototype.getChapitrage = function() { var val = this.getId("Chapitrage");