video widget size
[living-lab-site.git] / js / jquery.ui.nsvideo.js
1 /*
2  * jQuery UI NS-Video @VERSION
3  *
4  * Copyright 2011, Călin-Andrei Burloiu
5  * Dual licensed under the MIT or GPL Version 2 licenses.
6  * http://jquery.org/license
7  *
8  *
9  * Depends:
10  *   jquery.ui.core.js
11  *   jquery.ui.widget.js
12  */
13 (function( $, undefined ) {
14
15 $.widget( "ui.nsvideo", {
16         version: "@VERSION",
17         options: {
18                 type: 'ns-html5',
19                 width: 800,
20                 height: 600,
21                 showStatus: true,
22                 refreshInterval: 0.1,   // seconds
23                 autoplay: false
24         },
25
26         min: 0,
27
28         _create: function() {
29                 var widget = this;
30                 
31                 widget.element
32                         .addClass( "ui-widget ui-widget-content ui-corner-all" );
33                 
34                 widget.$videoContainer = $('<div class="ui-nsvideo-nsplugin"></div>')
35                         .appendTo(widget.element);
36                 widget.$progressContainer = $('<div class="ui-nsvideo-progress-container ui-widget-content ui-corner-top"></div>')
37                         .appendTo(widget.element);
38                 widget.$progress = $('<div class="ui-nsvideo-progress"></div>')
39                         .appendTo(widget.$progressContainer);
40                 widget.$loadedProgress = $('<div class="ui-nsvideo-loaded-progress"></div>')
41                         .appendTo(widget.$progress);
42                 widget.$controls = $('<div class="ui-nsvideo-controls ui-widget-content ui-corner-bottom"></div>')
43                         .appendTo(widget.element);
44                 
45                 widget.video();
46                 
47                 // Time progress slider with load progress also
48                 widget.$loadedProgress
49                         // TODO an object that inherits progressbar should be used in order to customize min value.
50                         .progressbar({
51                                 value: 0
52                         });
53                 widget.$progress
54                         .slider({
55                                         value: 0,
56                                         min: 0,
57                                         max: 1000, //Math.floor(widget.$video[0].duration),
58                                         slide: function(event, ui) {
59                                                 widget.videoPlugin('crtTime', [ui.value]);
60                                         }
61                         });
62                 
63                 // Play / Pause
64                 $('<button class="ui-nsvideo-play ui-nsvideo-button ui-nsvideo-control-left">Play / Pause</button>')
65                         .appendTo(widget.$controls)
66                         .button({
67                                 text: false,
68                                 icons: { primary: "ui-icon-play" }
69                         })
70                         .click(function() {
71                                 widget.videoPlugin('togglePlay');
72                         });
73                 
74                 // Time information (current and total)
75                 widget.$time = $('<div class="ui-nsvideo-time ui-nsvideo-text ui-nsvideo-control-left">--:-- / --:--</div>')
76                         .appendTo(widget.$controls);
77                         
78                 // Full screen
79                 $('<button class="ui-nsvideo-fullscreen ui-nsvideo-button ui-nsvideo-control-right">Full Screen</button>')
80                         .appendTo(widget.$controls)
81                         .button({
82                                 text: false,
83                                 icons: { primary: "ui-icon-arrow-4-diag" }
84                         })
85                         .click(function() {
86                                 widget.videoPlugin('fullscreen');
87                         });
88
89                 // Video definition buttonset
90                 if (typeof widget.options.src == 'object')
91                 {
92                         var $definitions = $('<form><div class="ui-nsvideo-definitions ui-nsvideo-control-right"></div></form>')
93                                 .appendTo(widget.$controls);
94                         $definitions = $('.ui-nsvideo-definitions', $definitions[0]);
95                         $.each(widget.options.src, function(index, value) {
96                                 id = widget.element.attr('id') + '-def-' + index;
97                                 $('<input type="radio" id="' + id + '" name="definition" />')
98                                         .appendTo($definitions)
99                                         .attr('checked', (index == widget.options.definition))
100                                         .click(function() {
101                                                 widget.videoPlugin('pause');
102                                                 widget.definition(index);
103                                         });
104                                 $('<label for="' + id + '">' + index + '</label>')
105                                         .appendTo($definitions);
106                         });
107                         
108                         $definitions.buttonset();
109                 }
110                 
111                 // Volume
112                 $('<div class="ui-nsvideo-volume ui-nsvideo-control-right"></div>')
113                         .appendTo(widget.$controls)
114                         .slider({
115                                 range: "min",
116                                 min: 0,
117                                 max: 100,
118                                 slide: function(event, ui) {
119                                         widget.videoPlugin('volume', [ui.value]);
120                                 }
121                         });
122                 
123                 // Toggle Mute
124                 $('<button class="ui-nsvideo-mute ui-nsvideo-button ui-nsvideo-control-right">Mute</button>')
125                         .appendTo(widget.$controls)
126                         .button({
127                                 text: false,
128                                 icons: { primary: "ui-icon-volume-on" }
129                         })
130                         .click(function() {
131                                 widget.videoPlugin('toggleMute');
132                         });
133                         
134                 // Status information
135                 if (widget.options.showStatus)
136                 {
137                         widget.$stateText = $('<div class="ui-nsvideo-text ui-nsvideo-control-right">...</div>')
138                                 .appendTo(widget.$controls)
139                                 .css('cursor', 'pointer')
140                                 .click(function() {
141                                         widget.videoPlugin('refreshAll');
142                                 });
143                 }
144                 
145                 // Clear fix helper
146                 $('<div class="ui-helper-clearfix"></div>')
147                         .appendTo(widget.$controls);
148                         
149                 // Initialize video plugin
150                 widget.$video.ready(function() {
151                         widget.videoPlugin('init');
152                 });
153         },
154
155         _destroy: function() {
156                 
157         },
158
159         _setOption: function( key, value ) {
160                 // TODO
161                 if ( key === "TODO" ) {
162                         
163                 }
164
165                 this._super( "_setOption", key, value );
166         },
167         
168         _leadingZeros: function(number, length) {
169                 if (!length)
170                         length = 2;
171                 
172                 var str = '';
173                 
174                 if (isNaN(number))
175                 {
176                         for (var i=0; i<length; i++)
177                                 str += '-';
178                         return str;
179                 }
180                 
181                 str += number;
182                 while (str.length < length) 
183                 {
184                         str = '0' + str;
185                 }
186
187                 return str;
188         },
189         
190         video: function() {
191                 widget = this;
192                 
193                 // Select video source.
194                 // If src option is string, that's the source.
195                 // If src is an object, properties are definitions and values are
196                 // sources.
197                 var src = widget.crtSrc();
198                 if (src == null)
199                         return widget;
200                 
201                 widget.$videoContainer.html('');
202                 
203                 var width = widget.options.width;
204                 var height = widget.options.height;
205                 
206                 // HTML5
207                 if (widget.options.type == 'ns-html5'
208                         || widget.options.type == 'html5')
209                 {
210                         widget.$video = $('<video id="' + widget.element.attr('id') + '-video" src="' + src + '"' + (width == 0 ? '' : ' width="' + width + '"') + (height == 0 ? '' : ' height="' + height + '"') + ' preload="auto"' + (widget.options.autoplay ? ' autoplay="autoplay"' : '') + '>'
211                                 +'Error: Your browser does not support HTML5 or the video format!'
212                         +'</video>')
213                                 .appendTo(widget.$videoContainer)
214                                 .bind({
215                                         ended: function() {
216                                                 widget.html5.pause();
217                                         },
218                                         play: function() {
219                                                 widget.html5.play();
220                                         },
221                                         pause: function() {
222                                                 widget.html5.pause();
223                                         },
224                                         timeupdate: function() {
225                                                 widget.html5.refreshTime();
226                                         },
227                                         progress: function() {
228                                                 widget.html5.refreshLoadedProgress();
229                                         },
230                                         loadedmetadata: function() {
231                                                 widget.html5.refreshTime();
232                                                 widget.html5.refreshVolume();
233                                                 if (widget.options.width == 0)
234                                                         widget.element.css('width',
235                                                                                    widget.$video.width() + 8 + 'px');
236                                         },
237                                         seeked: function() {
238                                                 widget.html5.play();
239                                         },
240                                         volumechange: function() {
241                                                 widget.html5.refreshVolume();
242                                         }
243                                 });
244                 }
245                 // VLC
246                 else if (widget.options.type == 'ns-vlc'
247                         || widget.options.type == 'vlc')
248                 {
249                         var embedType;
250                         if (widget.options.type == 'ns-vlc')
251                                 embedType = 'application/x-ns-stream';
252                         else
253                                 embedType = 'application/x-vlc-plugin';
254                         
255                         if (navigator.appName == "Netscape")
256                         {
257                                 widget.$video = $('<embed type="' + embedType + '" name="vlcVideo" id="' + widget.element.attr('id') + '-video" autoplay="' + (widget.options.autoplay ? 'yes' : 'no') + '" loop="no" width="' + (width == 0 ? '640' : width) + '" height="' + (height == 0 ? '480' : height) + '" target="' + src + '" />')
258                                         .appendTo(widget.$videoContainer);
259                         }
260                         else
261                         {
262                                 widget.$video = $('<object classid="clsid:1800B8AF-4E33-43C0-AFC7-894433C13538" width="' + (width == 0 ? '640' : width) + '" height="' + (height == 0 ? '480' : height) + '" id="' + widget.element.attr('id') + '-video" name="vlcVideo" events="True" target="">'
263                                                 + '<param name="Src" value="' + src + '" />'
264                                                 + '<param name="ShowDisplay" value="True" />'
265                                                 + '<param name="Loop" value="False" />'
266                                                 + '<param name="AutoPlay" value="' + (widget.options.autoplay ? 'True' : 'False') + '" />'
267                                                 + '<param name="Toolbar" value="False" />'
268                                         + '</object>')
269                                         .appendTo(widget.$videoContainer);
270                         }
271                 }
272                 
273                 widget.element.css('width',
274                                                         widget.$video.width() + 8 + 'px');
275         },
276         
277         setPlayButton: function() {
278                 $('button.ui-nsvideo-play', widget.element[0])
279                         .button('option', 'icons', { primary: "ui-icon-play" })
280                         .button('refresh');
281         },
282         setPauseButton: function() {
283                 $('button.ui-nsvideo-play', widget.element[0])
284                         .button('option', 'icons', { primary: "ui-icon-pause" })
285                         .button('refresh');
286         },
287         setMuteButton: function() {
288                 $('button.ui-nsvideo-mute', widget.element[0])
289                         .button('option', 'icons', { primary: "ui-icon-volume-off" })
290                         .button('refresh');
291         },
292         setUnmuteButton: function() {
293                 $('button.ui-nsvideo-mute', widget.element[0])
294                         .button('option', 'icons', { primary: "ui-icon-volume-on" })
295                         .button('refresh');
296         },
297         setTimeText: function(text) {
298                 //$('.ui-nsvideo-time', widget.element[0])
299                 this.$time
300                         .html(text);
301         },
302         setVolumeSlider: function(vol) {
303                 $('.ui-nsvideo-volume', widget.element[0])
304                         .slider('value', vol);
305         },
306         setProgressSlider: function(prog) {
307                 $('.ui-nsvideo-progress', widget.element[0])
308                         .slider('value', prog);
309         },
310         setLoadedProgressSlider: function(prog) {
311                 $('.ui-nsvideo-loaded-progress', widget.element[0])
312                         .progressbar('value', prog);
313         },
314         
315         videoPlugin: function(method, args) {
316                 if (typeof args == 'undefined')
317                         args = [];
318                 var videoPlugin = null;
319                 
320                 if (this.options.type.indexOf('html5') != -1)
321                 {
322                         videoPlugin = this.html5;
323                 }
324                 else if (this.options.type.indexOf('vlc') != -1)
325                 {
326                         videoPlugin = this.vlc;
327                 }
328                 
329                 if (videoPlugin)
330                         return videoPlugin[method].apply(this, args);
331                 
332                 return null;
333         },
334         
335         definition: function(def) {
336                 var widget = this;
337                 
338                 if (typeof def == 'undefined')
339                         return widget.options.definition;
340                 
341                 widget.options.definition = def;
342                 widget.video();
343                 
344                 return widget;
345         },
346         
347         type: function(type) {
348                 var widget = this;
349                 
350                 if (typeof type == 'undefined')
351                         return widget.options.type;
352                 
353                 widget.options.type = type;
354                 widget.video();
355                 
356                 // Initialize video plugin
357                 widget.$video.ready(function() {
358                         widget.videoPlugin('init');
359                 });
360                 
361                 return widget;
362         },
363         
364         crtSrc: function() {
365                 var src;
366                 var widget = this;
367                 
368                 if (typeof widget.options.src == 'string')
369                         src = widget.options.src;
370                 else if (typeof widget.options.src == 'object')
371                 {
372                         if (typeof widget.options.definition == 'undefined')
373                                 return null;
374                         
375                         if (typeof widget.options.src[ widget.options.definition ]
376                                 == 'undefined')
377                                 return null;
378                         
379                         src = widget.options.src[ widget.options.definition ];
380                 }
381                 
382                 if (widget.options.type == 'ns-html5')
383                         src = 'tribe://' + src;
384                 
385                 return src;
386         },
387         
388         html5: {
389                 widget: this,
390                 //lastTime: null,
391                 
392                 init: function() {
393                         //widget.html5.refreshAll();
394                         
395                         //if (widget.options.autoplay)
396                         //      widget.html5.play();
397                 },
398                 
399                 togglePlay: function() {
400                         if (widget.$video[0].paused)
401                         {
402                                 widget.html5.play();
403                         }
404                         else
405                         {
406                                 widget.html5.pause();
407                         }
408                 },
409
410                 play: function() {
411                         if (widget.$video[0].paused)
412                                 widget.$video[0].play();
413                         
414                         widget.setPauseButton();
415                         
416                         return widget;
417                 },
418                 
419                 pause: function() {
420                         if (!widget.$video[0].paused)
421                                 widget.$video[0].pause();
422                         
423                         widget.setPlayButton();
424
425                         return widget;
426                 },
427                 
428                 toggleMute: function() {
429                         if (!widget.$video[0].muted)
430                         {
431                                 widget.html5.mute();
432                         }
433                         else
434                         {
435                                 widget.html5.unmute();
436                         }
437                 },
438                   
439                 mute: function() {
440                         if (!widget.$video[0].muted)
441                                 widget.$video[0].muted = true;
442                         
443                         widget.setMuteButton();
444                         
445                         return widget;
446                 },
447                 
448                 unmute: function() {
449                         if (widget.$video[0].muted)
450                                 widget.$video[0].muted = false;
451                         
452                         widget.setUnmuteButton();
453                         
454                         return widget;
455                 },
456                 
457                 /**
458                 * Volume value is expressed in percents.
459                 */
460                 volume: function(vol) {
461                         if (typeof vol == 'undefined')
462                                 return Math.round(widget.$video[0].volume * 100);
463                         
464                         widget.html5.unmute();
465                         widget.$video[0].volume = vol / 100;
466                         
467                         return widget;
468                 },
469                 
470                 /**
471                  * Seek position is a value between 0 and 1000.
472                  */
473                 crtTime: function(pos) {
474                         // getter
475                         if (typeof pos == 'undefined')
476                         {
477                                 var crtTime = widget.$video[0].currentTime;
478                                 var totTime = widget.$video[0].duration;
479                                 if (isNaN(totTime) || totTime == 0)
480                                         return 0;
481                                 else
482                                         return Math.round(crtTime / totTime * 1000.0);
483                         }
484                         
485                         // setter
486                         widget.$video[0].currentTime = 
487                                 pos / 1000 * widget.$video[0].duration;
488                 },
489                   
490                 refreshAll: function() {
491                         widget.html5.refreshState();
492                         widget.html5.refreshVolume();
493                         widget.html5.refreshLoadedProgress();
494                         widget.$time.html('--:-- / --:--');
495                         widget.$stateText.html('...');
496                         widget.html5.refreshTime();
497                 },
498                 
499                 refreshTime: function() {
500                         if (widget.$video[0].seeking)
501                                 return widget;
502                         
503                         var crtTime = widget.$video[0].currentTime;
504                         var totTime = widget.$video[0].duration;
505                         
506                         // Refresh only at refreshInterval seconds to save CPU time.
507                         var delta = crtTime - widget.html5.lastTime;
508                         if (typeof widget.html5.lastTime !== "undefined"
509                                 && delta >= 0 && delta < widget.options.refreshInterval)
510                                 return widget;
511                         widget.html5.lastTime = crtTime;
512                         
513                         // Current time string
514                         var crtH = Math.floor(crtTime / 3600);
515                         var crtM = Math.floor((crtTime / 60) % 60);
516                         var crtS = Math.floor(crtTime % 60);
517                         var strCrtTime = 
518                                 (crtH == 0 ? '' : (widget._leadingZeros(crtH) + ':'))
519                                 + widget._leadingZeros(crtM) + ':' + widget._leadingZeros(crtS);
520                                 
521                         // Total time string
522                         var totH = Math.floor(totTime / 3600);
523                         var totM = Math.floor((totTime / 60) % 60);
524                         var totS = Math.floor(totTime % 60);
525                         var strTotTime = 
526                                 (totH == 0 || isNaN(totH) ? '' : (widget._leadingZeros(totH) + ':'))
527                                 + widget._leadingZeros(totM) + ':' + widget._leadingZeros(totS);
528                         
529                         widget.setTimeText('' + strCrtTime + ' / ' + strTotTime);
530                         
531                         // Update time progress slider.
532                         widget.html5.refreshProgress();
533                         
534                         return widget;
535                 },
536                 
537                 refreshState: function() {
538                         // TODO refresh HTML5 plugin state
539                         
540                         return widget;
541                 },
542
543                 refreshVolume: function() {
544                         var vol;
545                         
546                         if (widget.$video[0].muted)
547                                 vol = 0;
548                         else
549                                 vol = Math.floor(widget.$video[0].volume * 100);
550                         
551                         widget.setVolumeSlider(vol);
552                         
553                         return widget;
554                 },
555                 
556                 refreshProgress: function() {
557                         widget.setProgressSlider(widget.html5.crtTime());
558                         
559                         return widget;
560                 },
561                 
562                 /**
563                 * Supported for Firefox 4.0 or later.
564                 */
565                 refreshLoadedProgress: function() {
566                         // Return if buffering status not available in browser.
567                         if (typeof widget.$video[0].buffered == 'undefined'
568                                 || widget.$video[0].buffered.length === 0)
569                                 return widget;
570                         
571                         var loadedTime = widget.$video[0].buffered.end(0);
572                         var totTime = widget.$video[0].duration;
573                         var percent;
574                         if (isNaN(totTime) || totTime == 0)
575                                 percent = 0
576                         else
577                                 percent = Math.floor(loadedTime / totTime * 100);
578                         
579                         widget.setLoadedProgressSlider(percent);
580                         
581                         return widget;
582                 },
583
584                 fullscreen: function() {
585                         alert('Your web browser does not support switching to full screen in HTML5 mode with this button. You can switch to full screen manually by right clicking on the video and choosing "Full Screen" from the popup menu.');
586                 }
587         },
588         
589         vlc: {
590                 widget: this,
591                 timerHandle: null,
592                 
593                 STATES: {
594                         IDLE_CLOSE: [0, "Idle / Close"],
595                         OPENING: [1, "Opening..."],
596                         BUFFERING: [2, "Buffering..."],
597                         PLAYING: [3, "Playing..."],
598                         PAUSED: [4, "Paused"],
599                         STOPPING: [5, "Stopping..."],
600                         ERROR: [6, "Error!"]
601                 },
602                 
603                 init: function() {
604                         if (widget.options.autoplay)
605                                 widget.vlc.play();
606                         widget.vlc.refreshAll();
607                 },
608                 
609                 togglePlay: function() {
610                         if (! widget.$video[0].playlist.isPlaying)
611                         {
612                                 widget.vlc.play();
613                         }
614                         else
615                         {
616                                 widget.vlc.pause();
617                         }
618                 },
619                 
620                 play: function() {
621                         if (! widget.$video[0].playlist.isPlaying)
622                                 widget.$video[0].playlist.play();
623                         
624                         widget.setPauseButton();
625                         
626                         // Schedule information refreshment at refreshInterval seconds.
627                         if (! widget.vlc.timerHandle)
628                                 widget.vlc.timerHandle = setTimeout(widget.vlc.refreshHandler, 
629                                                                                 widget.options.refreshInterval * 1000);
630                                 
631                         widget.vlc.refreshState();
632                         
633                         return widget;
634                 },
635                 
636                 pause: function() {
637                         if (widget.$video[0].playlist.isPlaying)
638                                 widget.$video[0].playlist.togglePause();
639                         
640                         widget.setPlayButton();
641                         
642                         // Cancel information refreshment scheduling.
643                         clearTimeout(widget.vlc.timerHandle);
644                         widget.vlc.timerHandle = null;
645                         
646                         widget.vlc.refreshState();
647
648                         return widget;
649                 },
650                 
651                 toggleMute: function() {
652                         if (! widget.$video[0].audio.mute)
653                         {
654                                 widget.vlc.mute();
655                         }
656                         else
657                         {
658                                 widget.vlc.unmute();
659                         }
660                 },
661                   
662                 mute: function() {
663                         if (! widget.$video[0].audio.mute)
664                                 widget.$video[0].audio.toggleMute();
665                         
666                         widget.setMuteButton();
667                         
668                         widget.vlc.refreshVolume();
669                         
670                         return widget;
671                 },
672                 
673                 unmute: function() {
674                         if (widget.$video[0].audio.mute)
675                                 widget.$video[0].audio.toggleMute();
676                         
677                         widget.setUnmuteButton();
678                         
679                         widget.vlc.refreshVolume();
680                         
681                         return widget;
682                 },
683                 
684                 /**
685                 * Volume value is expressed in percents.
686                 */
687                 volume: function(vol) {
688                         if (typeof vol == 'undefined')
689                                 return Math.round(widget.$video[0].audio.volume);
690                         
691                         widget.vlc.unmute();
692                         widget.$video[0].audio.volume = vol;
693                         
694                         return widget;
695                 },
696                 
697                 /**
698                  * Seek position is a value between 0 and 1000.
699                  */
700                 crtTime: function(pos) {
701                         // getter
702                         if (typeof pos == 'undefined')
703                         {
704                                 var crtTime = widget.$video[0].input.time;
705                                 var totTime = widget.$video[0].input.length;
706                                 if (isNaN(totTime) || totTime == 0)
707                                         return 0;
708                                 else
709                                         return Math.round(crtTime / totTime * 1000.0);
710                         }
711                         
712                         // setter
713                         widget.$video[0].input.time = 
714                                 pos / 1000 * widget.$video[0].input.length;
715                                 
716                         widget.vlc.refreshState();
717                 },
718                 
719                 /**
720                  * Timeout callback called at refreshInterval during playing in order
721                  * to refresh information.
722                  */
723                 refreshHandler: function() {
724                         if (widget.$video[0].input.state
725                                 == widget.vlc.STATES.PLAYING[0])
726                         {
727                                 widget.vlc.refreshTime();
728                                 widget.vlc.timerHandle = setTimeout(widget.vlc.refreshHandler, 
729                                                                                 widget.options.refreshInterval * 1000);
730                         }
731                         else
732                                 widget.vlc.pause();
733                         
734                         widget.vlc.refreshState();
735                 },
736                 
737                 refreshAll: function() {
738                         widget.vlc.refreshState();
739                         widget.vlc.refreshVolume();
740                         widget.vlc.refreshLoadedProgress();
741                         
742                         try {
743                                 widget.vlc.refreshTime();
744                         } catch(e) {
745                                 console.log(e);
746                                 widget.$time.html('--:-- / --:--');
747                         }
748                 },
749                 
750                 refreshTime: function() {
751                         // TODO while seeking (maybe not necessary for VLC)
752 //                      if (widget.$video[0].seeking)
753 //                              return widget;
754                         
755                         // Time values in seconds.
756                         var crtTime = widget.$video[0].input.time / 1000.0;
757                         var totTime = widget.$video[0].input.length / 1000.0;
758                         //var crtTime = widget.$video[0].input.position * totTime;
759                         
760                         // Current time string
761                         var crtH = Math.floor(crtTime / 3600);
762                         var crtM = Math.floor((crtTime / 60) % 60);
763                         var crtS = Math.floor(crtTime % 60);
764                         var strCrtTime = 
765                                 (crtH == 0 ? '' : (widget._leadingZeros(crtH) + ':'))
766                                 + widget._leadingZeros(crtM) + ':' + widget._leadingZeros(crtS);
767                                 
768                         // Total time string
769                         var totH = Math.floor(totTime / 3600);
770                         var totM = Math.floor((totTime / 60) % 60);
771                         var totS = Math.floor(totTime % 60);
772                         var strTotTime = 
773                                 (totH == 0 || isNaN(totH) ? '' : (widget._leadingZeros(totH) + ':'))
774                                 + widget._leadingZeros(totM) + ':' + widget._leadingZeros(totS);
775                         
776                         widget.setTimeText('' + strCrtTime + ' / ' + strTotTime);
777                         
778                         // Update time progress slider.
779                         widget.vlc.refreshProgress();
780                         
781                         return widget;
782                 },
783                 
784                 _state: function(code) {
785                         var r;
786                         $.each(widget.vlc.STATES, function(index, value) {
787                                 if ('' + code == '' + value[0])
788                                 {
789                                         r = value;
790                                         return false;
791                                 }
792                         });
793                         
794                         return r;
795                 },
796                 
797                 refreshState: function() {
798                         widget.$stateText
799                                 .html(widget.vlc._state(widget.$video[0].input.state)[1]);
800                 },
801
802                 refreshVolume: function() {
803                         var vol;
804                         
805                         if (widget.$video[0].audio.mute)
806                                 vol = 0;
807                         else
808                                 vol = Math.floor(widget.$video[0].audio.volume);
809                         
810                         widget.setVolumeSlider(vol);
811                         
812                         return widget;
813                 },
814                 
815                 refreshProgress: function() {
816                         widget.setProgressSlider(widget.vlc.crtTime());
817                         
818                         return widget;
819                 },
820                 
821                 /**
822                 * Not supported for VLC.
823                 */
824                 refreshLoadedProgress: function() {
825                         // TODO Currently not possible through VLC API.
826                         
827                         return widget;
828                 },
829
830                 fullscreen: function() {
831                         widget.$video[0].video.toggleFullscreen();
832                 }
833         }
834 });
835
836 })( jQuery );