src/js/widgets/playerWidget.js
changeset 843 75ba66457232
parent 842 4ae2247a59f4
child 870 2c025db10a10
equal deleted inserted replaced
53:7b55777486c3 843:75ba66457232
       
     1 /* Internationalization for this widget */
       
     2 
       
     3 IriSP.i18n.addMessages(
       
     4     {
       
     5         "en": {
       
     6             "play_pause": "Play/Pause",
       
     7             "mute_unmute": "Mute/Unmute",
       
     8             "play": "Play",
       
     9             "pause": "Pause",
       
    10             "mute": "Mute",
       
    11             "unmute": "Unmute",
       
    12             "annotate": "Annotate",
       
    13             "search": "Search",
       
    14             "elapsed_time": "Elapsed time",
       
    15             "total_time": "Total time",
       
    16             "volume": "Volume",
       
    17             "volume_control": "Volume control"
       
    18         },
       
    19         "fr": {
       
    20             "play_pause": "Lecture/Pause",
       
    21             "mute_unmute": "Couper/Activer le son",
       
    22             "play": "Lecture",
       
    23             "pause": "Pause",
       
    24             "mute": "Couper le son",
       
    25             "unmute": "Activer le son",
       
    26             "annotate": "Annoter",
       
    27             "search": "Rechercher",
       
    28             "elapsed_time": "Durée écoulée",
       
    29             "total_time": "Durée totale",
       
    30             "volume": "Niveau sonore",
       
    31             "volume_control": "Réglage du niveau sonore"
       
    32         }
       
    33     }
       
    34 );
       
    35 
       
    36 
       
    37 IriSP.PlayerWidget = function(Popcorn, config, Serializer) {
       
    38   IriSP.Widget.call(this, Popcorn, config, Serializer);
       
    39   
       
    40   this._searchBlockOpen = false;
       
    41   this._searchLastValue = "";
       
    42 };
       
    43 
       
    44 IriSP.PlayerWidget.prototype = new IriSP.Widget();
       
    45 
       
    46 IriSP.PlayerWidget.prototype.draw = function() {
       
    47   var self = this;
       
    48   var width = this.width;
       
    49 	var height = this.height;
       
    50 	var heightS = this.height-20;
       
    51 	  
       
    52 	var playerTempl = IriSP.templToHTML(IriSP.player_template, this._config);
       
    53   this.selector.append(playerTempl);		
       
    54 	
       
    55   this.selector.children(".Ldt-controler").show();
       
    56     
       
    57   // handle clicks by the user on the video.
       
    58   this._Popcorn.listen("play", IriSP.wrap(this, this.playButtonUpdater));
       
    59   this._Popcorn.listen("pause", IriSP.wrap(this, this.playButtonUpdater));
       
    60   
       
    61   this._Popcorn.listen("volumechange", IriSP.wrap(this, this.volumeUpdater));
       
    62 
       
    63   this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeDisplayUpdater));  
       
    64   // update the time display for the first time.
       
    65   this._Popcorn.listen("loadedmetadata", IriSP.wrap(this, this.timeDisplayUpdater));
       
    66   
       
    67   this._Popcorn.listen("IriSP.search.matchFound", IriSP.wrap(this, this.searchMatch));
       
    68   this._Popcorn.listen("IriSP.search.noMatchFound", IriSP.wrap(this, this.searchNoMatch));
       
    69   this._Popcorn.listen("IriSP.search.triggeredSearch", IriSP.wrap(this, this.triggeredSearch));
       
    70   
       
    71   
       
    72   this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); });
       
    73   this.selector.find(".Ldt-CtrlAnnotate").click(function() 
       
    74                                             { self._Popcorn.trigger("IriSP.PlayerWidget.AnnotateButton.clicked"); });
       
    75   this.selector.find(".Ldt-CtrlSearch").click(function() { self.searchButtonHandler.call(self); });
       
    76   
       
    77 	var _volctrl = this.selector.find(".Ldt-Ctrl-Volume-Control");
       
    78     this.selector.find('.Ldt-CtrlSound')
       
    79         .click(function() { self.muteHandler.call(self); } )
       
    80         .mouseover(function() {
       
    81             _volctrl.show();
       
    82         })
       
    83         .mouseout(function() {
       
    84             _volctrl.hide();
       
    85         });
       
    86     _volctrl.mouseover(function() {
       
    87         _volctrl.show();
       
    88     }).mouseout(function() {
       
    89         _volctrl.hide();
       
    90     });
       
    91   
       
    92   /*
       
    93   var searchButtonPos = this.selector.find(".Ldt-CtrlSearch").position();
       
    94   var searchBox = Mustache.to_html(IriSP.search_template, {margin_left : searchButtonPos.left + "px"});
       
    95   this.selector.find(".Ldt-CtrlSearch").after(searchBox);
       
    96   */
       
    97   
       
    98   // trigger an IriSP.PlayerWidget.MouseOver to the widgets that are interested (i.e : sliderWidget)
       
    99   this.selector.hover(function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOver"); }, 
       
   100                       function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOut"); });
       
   101   this.selector.find(".Ldt-Ctrl-Volume-Cursor").draggable({
       
   102       axis: "x",
       
   103       drag: function(event, ui) {
       
   104           var _vol = Math.max(0, Math.min( 1, ui.position.left / (ui.helper.parent().width() - ui.helper.outerWidth())));
       
   105           ui.helper.attr("title",IriSP.i18n.getMessage('volume')+': ' + Math.floor(100*_vol) + '%');
       
   106           self._Popcorn.volume(_vol);
       
   107       },
       
   108       containment: "parent"
       
   109   });
       
   110  
       
   111  setTimeout(function() {
       
   112      self.volumeUpdater();
       
   113  }, 1000); /* some player - jwplayer notable - save the state of the mute button between sessions */
       
   114 };
       
   115 
       
   116 /* Update the elasped time div */
       
   117 IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() {
       
   118   
       
   119   if (this._previousSecond === undefined) {
       
   120     this._previousSecond = this._Popcorn.roundTime();
       
   121   }
       
   122   else {
       
   123     /* we're still in the same second, so it's not necessary to update time */
       
   124     if (this._Popcorn.roundTime() == this._previousSecond)
       
   125       return;
       
   126       
       
   127   }
       
   128   
       
   129   // we get it at each call because it may change.
       
   130   var duration = this.getDuration() / 1000; 
       
   131   var totalTime = IriSP.secondsToTime(duration);
       
   132   var elapsedTime = IriSP.secondsToTime(this._Popcorn.currentTime());
       
   133   
       
   134   this.selector.find(".Ldt-ElapsedTime").html(elapsedTime.toString());
       
   135   this.selector.find(".Ldt-TotalTime").html(totalTime.toString());
       
   136   this._previousSecond = this._Popcorn.roundTime();
       
   137 };
       
   138 
       
   139 /* update the icon of the button - separate function from playHandler
       
   140    because in some cases (for instance, when the user directly clicks on
       
   141    the jwplayer window) we have to change the icon without playing/pausing
       
   142 */
       
   143 IriSP.PlayerWidget.prototype.playButtonUpdater = function() {
       
   144   var status = this._Popcorn.media.paused;
       
   145   
       
   146   if ( status == true ){
       
   147     /* the background sprite is changed by adding/removing the correct classes */
       
   148     this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('play'));
       
   149     this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PauseState").addClass("Ldt-CtrlPlay-PlayState");
       
   150   } else {
       
   151     this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('pause'));
       
   152     this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PlayState").addClass("Ldt-CtrlPlay-PauseState");
       
   153   }  
       
   154 
       
   155   return;
       
   156 };
       
   157 
       
   158 
       
   159 IriSP.PlayerWidget.prototype.playHandler = function() {
       
   160   var status = this._Popcorn.media.paused;
       
   161   
       
   162   if ( status == true ){        
       
   163     this._Popcorn.play();   
       
   164   } else {
       
   165     this._Popcorn.pause();
       
   166   }  
       
   167 };
       
   168 
       
   169 IriSP.PlayerWidget.prototype.muteHandler = function() {
       
   170   this._Popcorn.mute(!this._Popcorn.muted());
       
   171 };
       
   172 
       
   173 IriSP.PlayerWidget.prototype.volumeUpdater = function() {
       
   174     var _muted = this._Popcorn.muted(),
       
   175         _vol = this._Popcorn.volume();
       
   176     if (_vol === false) {
       
   177         _vol = .5;
       
   178     }
       
   179     var _soundCtl = this.selector.find(".Ldt-CtrlSound");
       
   180     _soundCtl.removeClass("Ldt-CtrlSound-Mute Ldt-CtrlSound-Half Ldt-CtrlSound-Full");
       
   181     if (_muted) {        
       
   182         _soundCtl.attr("title", IriSP.i18n.getMessage('unmute'))
       
   183             .addClass("Ldt-CtrlSound-Mute");    
       
   184     } else {
       
   185         _soundCtl.attr("title", IriSP.i18n.getMessage('mute'))
       
   186             .addClass(_vol < .5 ? "Ldt-CtrlSound-Half" : "Ldt-CtrlSound-Full" )
       
   187     }
       
   188     var _cursor = this.selector.find(".Ldt-Ctrl-Volume-Cursor");
       
   189     _cursor.css({
       
   190         "left": ( _muted ? 0 : Math.floor(_vol * (_cursor.parent().width() - _cursor.outerWidth())) ) + "px"
       
   191     })
       
   192 };
       
   193 
       
   194 IriSP.PlayerWidget.prototype.showSearchBlock = function() {
       
   195   var self = this;
       
   196   
       
   197   if (this._searchBlockOpen == false) {
       
   198     this.selector.find(".LdtSearch").show("blind", { direction: "horizontal"}, 100);
       
   199     this.selector.find(".LdtSearchInput").css('background-color','#fff');
       
   200    
       
   201     this._searchBlockOpen = true;           
       
   202     this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } );
       
   203     this.selector.find(".LdtSearchInput").focus();
       
   204     
       
   205     // we need this variable because some widget can find a match in
       
   206     // their data while at the same time other's don't. As we want the
       
   207     // search field to become green when there's a match, we need a 
       
   208     // variable to remember that we had one.
       
   209     this._positiveMatch = false;
       
   210 
       
   211     // tell the world the field is open
       
   212     this._Popcorn.trigger("IriSP.search.open");     
       
   213 	}
       
   214 };
       
   215 
       
   216 IriSP.PlayerWidget.prototype.hideSearchBlock = function() {
       
   217  if (this._searchBlockOpen == true) {
       
   218     this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
       
   219     this.selector.find(".LdtSearchInput").attr('value','');
       
   220     this.selector.find(".LdtSearch").hide("blind", { direction: "horizontal"}, 75);
       
   221     
       
   222     // unbind the watcher event.
       
   223     this.selector.find(".LdtSearchInput").unbind('keypress set');
       
   224     this._searchBlockOpen = false;
       
   225 
       
   226     this._positiveMatch = false;
       
   227     
       
   228     this._Popcorn.trigger("IriSP.search.closed");
       
   229 	}
       
   230 };
       
   231 
       
   232 /** react to clicks on the search button */
       
   233 IriSP.PlayerWidget.prototype.searchButtonHandler = function() {
       
   234   var self = this;
       
   235 
       
   236   /* show the search field if it is not shown */
       
   237   if ( this._searchBlockOpen == false ) {
       
   238     this.showSearchBlock();
       
   239     this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue);      
       
   240     this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural.
       
   241 	} else {
       
   242     this.hideSearchBlock();
       
   243   }
       
   244 };
       
   245 
       
   246 /** this handler is called whenever the content of the search
       
   247    field changes */
       
   248 IriSP.PlayerWidget.prototype.searchHandler = function() {
       
   249   this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
       
   250   this._positiveMatch = false;
       
   251   
       
   252   // do nothing if the search field is empty, instead of highlighting everything.
       
   253   if (this._searchLastValue == "") {
       
   254     this._Popcorn.trigger("IriSP.search.cleared");
       
   255     this.selector.find(".LdtSearchInput").css('background-color','');
       
   256   } else {
       
   257     this._Popcorn.trigger("IriSP.search", this._searchLastValue);
       
   258   }
       
   259 };
       
   260 
       
   261 /**
       
   262   handler for the IriSP.search.found message, which is sent by some views when they
       
   263   highlight a match.
       
   264 */
       
   265 IriSP.PlayerWidget.prototype.searchMatch = function() {
       
   266   this._positiveMatch = true;
       
   267   this.selector.find(".LdtSearchInput").css('background-color','#e1ffe1');
       
   268 };
       
   269 
       
   270 /** the same, except that no value could be found */
       
   271 IriSP.PlayerWidget.prototype.searchNoMatch = function() {
       
   272   if (this._positiveMatch !== true)
       
   273     this.selector.find(".LdtSearchInput").css('background-color', "#d62e3a");
       
   274 };
       
   275 
       
   276 /** react to an IriSP.Player.triggeredSearch - that is, when
       
   277     a widget ask the PlayerWidget to do a search on his behalf */
       
   278 IriSP.PlayerWidget.prototype.triggeredSearch = function(searchString) {
       
   279   this.showSearchBlock();
       
   280   this.selector.find(".LdtSearchInput").attr('value', searchString);      
       
   281   this._Popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural.
       
   282 };
       
   283 
       
   284