# HG changeset patch # User hamidouk # Date 1327938374 -3600 # Node ID 3372a86f02b2f2ea43c9e39f17205e26914c97ea # Parent 5cc5afa71d7efc4efc79e90ca52464a5d1e78b18 new player version with a different configuration. changed the player embed method to suit it. diff -r 5cc5afa71d7e -r 3372a86f02b2 src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html --- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html Fri Jan 27 17:21:56 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html Mon Jan 30 16:46:14 2012 +0100 @@ -8,25 +8,10 @@ IriSP.jwplayer_swf_path = "{{WEB_URL}}{{LDT_MEDIA_PREFIX}}swf/player.swf"; IriSP.libdir = "{{WEB_URL}}{{LDT_MEDIA_PREFIX}}js/"; - IriSP.lib = { - jQuery : IriSP.libdir + "jquery.min.js", - jQueryUI : IriSP.libdir + "jquery-ui.min.js", - jQueryToolTip : IriSP.libdir + "jquery.tools.min.js", - swfObject : IriSP.libdir + "swfobject.js", - cssjQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css", - popcorn : IriSP.libdir + "popcorn.js", - jwplayer : IriSP.libdir + "jwplayer.js", - popcornReplacement: IriSP.libdir + "pop.js", - raphael: IriSP.libdir + "raphael.js", - jquery_sparkline: IriSP.libdir + "jquery.sparkline.js", - "popcorn.mediafragment" : IriSP.libdir + "popcorn.mediafragment.js", - "popcorn.code" : IriSP.libdir + "popcorn.code.js", - "popcorn.jwplayer": IriSP.libdir + "popcorn.jwplayer.js", - "popcorn.youtube": IriSP.libdir + "popcorn.youtube.js", - }; - IriSP.paths["imgs"] = "{{WEB_URL}}{{LDT_MEDIA_PREFIX}}css/imgs"; IriSP.default_templates_vars["img_dir"] = IriSP.paths.imgs; + + IriSP.widgetsDefaults["createAnnotationWidget"] = {}; IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version = false; IriSP.platform_url = "{{WEB_URL}}{{BASE_URL}}"; @@ -156,15 +141,8 @@ }] }; - - IriSP.loadLibs(IriSP.lib, config, "{{ json_url }}", - function() { - var layoutManager = new IriSP.LayoutManager(config.gui); - var pop = IriSP.configurePopcorn(layoutManager, config.player); - - var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); - var modules = IriSP.configureModules(pop, config.modules); - }); + debugger; + IriSP.initPlayer(config, "{{ json_url }}"); {% endspaceless %} diff -r 5cc5afa71d7e -r 3372a86f02b2 src/ldt/ldt/static/ldt/js/LdtPlayer-release.js --- a/src/ldt/ldt/static/ldt/js/LdtPlayer-release.js Fri Jan 27 17:21:56 2012 +0100 +++ b/src/ldt/ldt/static/ldt/js/LdtPlayer-release.js Mon Jan 30 16:46:14 2012 +0100 @@ -1009,6 +1009,13 @@ __IriSP = IriSP; } +/* underscore comes bundled with the player and we need + it ASAP, so load it that way +*/ + +IriSP._ = window._.noConflict(); +IriSP.underscore = IriSP._; + IriSP.loadLibs = function( libs, config, metadata_url, callback ) { // Localize jQuery variable IriSP.jQuery = null; @@ -1052,8 +1059,6 @@ $L.wait(function() { IriSP.jQuery = window.jQuery.noConflict( true ); - IriSP._ = window._.noConflict(); - IriSP.underscore = IriSP._; var css_link_jquery = IriSP.jQuery( "", { rel: "stylesheet", @@ -1605,28 +1610,52 @@ }; /* site.js - all our site-dependent config : player chrome, cdn locations, etc...*/ +IriSP.defaults = {}; + +/* these objects are filled by configureDefaults. The function doesn't overwrite + defaults that were originally defined by the user. +*/ +IriSP.lib = {}; + +/* We need to define those so that the individual settings can be overwritten */ +IriSP.widgetsDefaults = {}; + +IriSP.paths = {}; + 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", - jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.js", - jQueryToolTip : "http://cdn.jquerytools.org/1.2.4/all/jquery.tools.min.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", - popcorn : IriSP.libdir + "popcorn.js", - jwplayer : IriSP.libdir + "jwplayer.js", - popcornReplacement: IriSP.libdir + "pop.js", - raphael: IriSP.libdir + "raphael.js", - jquery_sparkline: IriSP.libdir + "jquery.sparkline.js", - "popcorn.mediafragment" : IriSP.libdir + "popcorn.mediafragment.js", - "popcorn.code" : IriSP.libdir + "popcorn.code.js", - "popcorn.jwplayer": IriSP.libdir + "popcorn.jwplayer.js", - "popcorn.youtube": IriSP.libdir + "popcorn.youtube.js" +IriSP.default_templates_vars = { }; + +/** ugly ugly ugly ugly - returns an object defining + the paths to the libs + We need it that way cause it's called at runtime by + IriSP.configureDefaults. +*/ +IriSP.defaults.lib = function(libdir) { + if (IriSP.null_or_undefined(libdir)) + libdir = IriSP.libdir; + + return { + jQuery : "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js", + jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.js", + jQueryToolTip : "http://cdn.jquerytools.org/1.2.4/all/jquery.tools.min.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", + popcorn : libdir + "popcorn.js", + jwplayer : libdir + "jwplayer.js", + popcornReplacement: libdir + "pop.js", + raphael: libdir + "raphael.js", + jquery_sparkline: libdir + "jquery.sparkline.js", + "popcorn.mediafragment" : libdir + "popcorn.mediafragment.js", + "popcorn.code" : libdir + "popcorn.code.js", + "popcorn.jwplayer": libdir + "popcorn.jwplayer.js", + "popcorn.youtube": libdir + "popcorn.youtube.js" + }; }; //Configuration for the player and utility functions. +// No need to have them configured at runtime IriSP.config = {}; IriSP.config.shortener = { @@ -1634,63 +1663,73 @@ //shortening_function : IriSP.platform_shorten_url }; -IriSP.widgetsDefaults = { - "LayoutManager" : {spacer_div_height : "0px" }, - "PlayerWidget" : {}, - "AnnotationsWidget": { - "share_text" : "I'm watching ", - "fb_link" : "http://www.facebook.com/share.php?u=", - "tw_link" : "http://twitter.com/home?status=", - "gplus_link" : "" +IriSP.defaults.widgetsDefaults = function(platform_url) { + if (IriSP.null_or_undefined(platform_url)) + platform_url = IriSP.platform_url; + + return { + "LayoutManager" : {spacer_div_height : "0px" }, + "PlayerWidget" : {}, + "AnnotationsWidget": { + "share_text" : "I'm watching ", + "fb_link" : "http://www.facebook.com/share.php?u=", + "tw_link" : "http://twitter.com/home?status=", + "gplus_link" : "" + }, + + "TweetsWidget" : { + default_profile_picture : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png", + tweet_display_period: 10000 // how long do we show a tweet ? + + }, + "SliderWidget" : { + minimize_period: 850 // how long does the slider stays maximized after the user leaves the zone ? }, - "TweetsWidget" : { - default_profile_picture : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png", - tweet_display_period: 10000, // how long do we show a tweet ? - - }, - "SliderWidget" : { - minimize_period: 850 // how long does the slider stays maximized after the user leaves the zone ? - }, - "createAnnotationWidget" : { - keywords: ["#faux-raccord", "#mot-clef"], - polemic_mode: true, /* enable polemics ? */ - /* polemics - the corresponding class names defined in the css should be for instance : - Ldt-createAnnotation-polemic-positive for positive - Ldt-createAnnotation-polemic-reference for reference, etc. - */ - polemics: {"++" : "positive", "--" : "negative", "==" : "reference", "??" : "question"}, - cinecast_version: true /* put to false to enable the platform version, true for the festival cinecast one. */ - }, - "SparklineWidget" : { - column_width: 10 // the width of a column in pixels. - }, - "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 */ - project_url: IriSP.platform_url + "/ldtplatform/ldt/front/player/" /* the beginning - of a link to the - new front */ - }, + "createAnnotationWidget" : { + keywords: ["#faux-raccord", "#mot-clef"], + polemic_mode: true, /* enable polemics ? */ + /* polemics - the corresponding class names defined in the css should be for instance : + Ldt-createAnnotation-polemic-plusplus for plusplus + Ldt-createAnnotation-polemic-equalequal for equalequal, etc. + */ + polemics: {"++" : "positive", "--" : "negative", "==" : "reference", "??" : "question"}, + cinecast_version: true /* put to false to enable the platform version, true for the festival cinecast one. */ + }, + "SparklineWidget" : { + column_width: 10 // the width of a column in pixels. + }, + "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: 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 */ + + project_url: platform_url + "/ldtplatform/ldt/front/player/" /* the beginning + of a link to the + new front */ + } + }; }; -IriSP.paths = { +IriSP.defaults.paths = { // "imgs": "/tweetlive/res/metadataplayer/src/css/imgs" "imgs": "/mdp/src/css/imgs" }; -IriSP.default_templates_vars = { + +IriSP.defaults.default_templates_vars = function() { + return { "img_dir" : IriSP.paths.imgs -}; + }; +} /* ui.js - ui related functions */ @@ -2185,6 +2224,51 @@ serializer.sync(IriSP.wrap(widget, function() { this.draw(); })); return widget; }; + +/** Go through the defaults to set a reasonable value */ +IriSP.configureDefaults = function(libdir, platform_url) { + /* the defaults configuration is messy and complicated. There are two things to know : + - we want to allow overwriting of defaults - that's why we have IriSP.widgetDefaults + and IriSP.defaults.widgetDefaults. The first is filled by the embedder and then fleshed out + with the contents of the first. We use underscore.defaults for that, but there's one problem with + this function : it doesn't work recursively. + - we need to compute some values at runtime instead of at compile time + */ + + IriSP.lib = IriSP.underscore.defaults(IriSP.lib, IriSP.defaults.lib(libdir)); + + /* get the factory defaults for the widgets and merge them with the default the user + may have defined + */ + var factory_defaults = IriSP.defaults.widgetsDefaults(platform_url); + for(var widget in factory_defaults) { + + /* create the object if it doesn't exists */ + if (IriSP.null_or_undefined(IriSP.widgetsDefaults[widget])) + IriSP.widgetsDefaults[widget] = {}; + + IriSP.widgetsDefaults[widget] = IriSP.underscore.defaults(IriSP.widgetsDefaults[widget], factory_defaults[widget]); + } + + IriSP.paths = IriSP.underscore.defaults(IriSP.paths, IriSP.defaults.paths); + IriSP.default_templates_vars = IriSP.underscore.defaults(IriSP.default_templates_vars, + IriSP.defaults.default_templates_vars()); +}; + +/** single point of entry for the metadataplayer */ +IriSP.initPlayer = function(config, metadata_url, libdir, platform_url) { + IriSP.configureDefaults(libdir, platform_url); + IriSP.loadLibs(IriSP.lib, config, metadata_url, + function() { + + var layoutManager = new IriSP.LayoutManager(config.gui); + + var pop = IriSP.configurePopcorn(layoutManager, config.player); + + var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); + var modules = IriSP.configureModules(pop, config.modules); + }); +}; /* To wrap a player the develop should create a new class derived from the IriSP.PopcornReplacement.player and defining the correct functions */ @@ -2492,6 +2576,8 @@ this._Popcorn.listen("seeked", IriSP.wrap(this, this.ajaxRedraw)); this._Popcorn.listen("loadedmetadata", IriSP.wrap(this, this.ajaxRedraw)); this._Popcorn.listen("paused", IriSP.wrap(this, this.ajaxRedraw)); + + this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.ajaxRedraw)); } }; @@ -3155,6 +3241,7 @@ this._Popcorn.listen("IriSP.search.matchFound", IriSP.wrap(this, this.searchMatch)); this._Popcorn.listen("IriSP.search.noMatchFound", IriSP.wrap(this, this.searchNoMatch)); + this._Popcorn.listen("IriSP.search.triggeredSearch", IriSP.wrap(this, this.triggeredSearch)); this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); }); @@ -3271,47 +3358,59 @@ return; }; - +IriSP.PlayerWidget.prototype.showSearchBlock = function() { + var self = this; + + if (this._searchBlockOpen == false) { + this.selector.find(".LdtSearch").show("blind", { direction: "horizontal"}, 100); + this.selector.find(".LdtSearchInput").css('background-color','#fff'); + + this._searchBlockOpen = true; + this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } ); + this.selector.find(".LdtSearchInput").focus(); + + // we need this variable because some widget can find a match in + // their data while at the same time other's don't. As we want the + // search field to become green when there's a match, we need a + // variable to remember that we had one. + this._positiveMatch = false; + + // tell the world the field is open + this._Popcorn.trigger("IriSP.search.open"); + } +}; + +IriSP.PlayerWidget.prototype.hideSearchBlock = function() { + if (this._searchBlockOpen == true) { + this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value'); + this.selector.find(".LdtSearchInput").attr('value',''); + this.selector.find(".LdtSearch").hide("blind", { direction: "horizontal"}, 75); + + // unbind the watcher event. + this.selector.find(".LdtSearchInput").unbind('keypress set'); + this._searchBlockOpen = false; + + this._positiveMatch = false; + + this._Popcorn.trigger("IriSP.search.closed"); + } +}; + +/** react to clicks on the search button */ IriSP.PlayerWidget.prototype.searchButtonHandler = function() { - var self = this; - - /* show the search field if it is not shown */ - if ( this._searchBlockOpen == false ) { - this.selector.find(".LdtSearch").show("blind", { direction: "horizontal"}, 100); - - this.selector.find(".LdtSearchInput").css('background-color','#fff'); - this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue); - this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural. - - this._searchBlockOpen = true; - this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } ); - this.selector.find(".LdtSearchInput").focus(); - - // we need this variable because some widget can find a match in - // their data while at the same time other's don't. As we want the - // search field to become green when there's a match, we need a - // variable to remember that we had one. - this._positiveMatch = false; - - // tell the world the field is open - this._Popcorn.trigger("IriSP.search.open"); - + var self = this; + + /* show the search field if it is not shown */ + if ( this._searchBlockOpen == false ) { + this.showSearchBlock(); + this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue); + this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural. } else { - this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value'); - this.selector.find(".LdtSearchInput").attr('value',''); - this.selector.find(".LdtSearch").hide("blind", { direction: "horizontal"}, 75); - - // unbind the watcher event. - this.selector.find(".LdtSearchInput").unbind('keypress set'); - this._searchBlockOpen = false; - - this._positiveMatch = false; - - this._Popcorn.trigger("IriSP.search.closed"); + this.hideSearchBlock(); } }; -/* this handler is called whenever the content of the search +/** this handler is called whenever the content of the search field changes */ IriSP.PlayerWidget.prototype.searchHandler = function() { this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value'); @@ -3326,20 +3425,29 @@ } }; -/* +/** handler for the IriSP.search.found message, which is sent by some views when they highlight a match. */ IriSP.PlayerWidget.prototype.searchMatch = function() { this._positiveMatch = true; this.selector.find(".LdtSearchInput").css('background-color','#e1ffe1'); -} - -/* the same, except that no value could be found */ +}; + +/** the same, except that no value could be found */ IriSP.PlayerWidget.prototype.searchNoMatch = function() { if (this._positiveMatch !== true) this.selector.find(".LdtSearchInput").css('background-color', "#d62e3a"); -} +}; + +/** react to an IriSP.Player.triggeredSearch - that is, when + a widget ask the PlayerWidget to do a search on his behalf */ +IriSP.PlayerWidget.prototype.triggeredSearch = function(searchString) { + this.showSearchBlock(); + this.selector.find(".LdtSearchInput").attr('value', searchString); + this._Popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural. +}; + /* * @@ -4177,20 +4285,29 @@ var time = this._Popcorn.currentTime(); var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000; - var percent = ((time / duration) * 100).toFixed(2); + var percents = time / duration; /* we do these complicated calculations to center exactly the position Marker */ - var pixels_to_percents = 100 / this.selector.width(); /* how much is a pixel in percents */ + + var divWidth = this.selector.width(); + var pixels = Math.floor(this.selector.width() * percents); var positionMarker_width = this.positionMarker.width(); - var correction = (pixels_to_percents * positionMarker_width) / 2; - - var newPos = percent - correction; + var correction = (positionMarker_width / 2); + + /* check that we don't leave the left side */ + var newPos = pixels - correction; if (newPos <= 0) newPos = 0; - this.sliderForeground.css("width", percent + "%"); - this.positionMarker.css("left", newPos + "%"); + /* check that we don't leave the right side */ + var rightEdgePos = pixels + 1 * correction; + + if (rightEdgePos >= divWidth) + newPos = divWidth - 1 * correction - 1; + + this.sliderForeground.css("width", pixels + "px"); + this.positionMarker.css("left", newPos + "px"); }; @@ -4647,7 +4764,7 @@ 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', + 'non', '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, @@ -4686,6 +4803,7 @@ var _max = _words[0].count, _min = Math.min(_words[_words.length - 1].count, _max - 1), _scale = 16 / Math.sqrt(_max - _min), + _this = this, _html = '