jQuery UI NextShare Video Widget (alpha version) finished and integrated into the...
[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: 450,
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                 // HTML5
204                 if (widget.options.type == 'ns-html5'
205                         || widget.options.type == 'html5')
206                 {
207                         widget.$video = $('<video id="' + widget.element.attr('id') + '-video" src="' + src + '" width="' + widget.options.width + '" height="' + widget.options.height + '" preload="auto"' + (widget.options.autoplay ? ' autoplay="autoplay"' : '') + '>'
208                                 +'Error: Your browser does not support HTML5 or the video format!'
209                         +'</video>')
210                                 .appendTo(widget.$videoContainer)
211                                 .bind({
212                                         ended: function() {
213                                                 widget.html5.pause();
214                                         },
215                                         play: function() {
216                                                 widget.html5.play();
217                                         },
218                                         pause: function() {
219                                                 widget.html5.pause();
220                                         },
221                                         timeupdate: function() {
222                                                 widget.html5.refreshTime();
223                                         },
224                                         progress: function() {
225                                                 widget.html5.refreshLoadedProgress();
226                                         },
227                                         loadedmetadata: function() {
228                                                 widget.html5.refreshTime();
229                                                 widget.html5.refreshVolume();
230                                         },
231                                         seeked: function() {
232                                                 widget.html5.play();
233                                         },
234                                         volumechange: function() {
235                                                 widget.html5.refreshVolume();
236                                         }
237                                 });
238                 }
239                 // VLC
240                 else if (widget.options.type == 'ns-vlc'
241                         || widget.options.type == 'vlc')
242                 {
243                         var embedType;
244                         if (widget.options.type == 'ns-vlc')
245                                 embedType = 'application/x-ns-stream';
246                         else
247                                 embedType = 'application/x-vlc-plugin';
248                         
249                         if (navigator.appName == "Netscape")
250                         {
251                                 widget.$video = $('<embed type="' + embedType + '" name="vlcVideo" id="' + widget.element.attr('id') + '-video" autoplay="' + (widget.options.autoplay ? 'yes' : 'no') + '" loop="no" width="' + widget.options.width + '" height="' + widget.options.height + '" target="' + src + '" />')
252                                         .appendTo(widget.$videoContainer);
253                         }
254                         else
255                         {
256                                 widget.$video = $('<object classid="clsid:1800B8AF-4E33-43C0-AFC7-894433C13538" width="' + widget.options.width + '" height="' + widget.options.height + '" id="' + widget.element.attr('id') + '-video" name="vlcVideo" events="True" target="">'
257                                                 + '<param name="Src" value="' + src + '" />'
258                                                 + '<param name="ShowDisplay" value="True" />'
259                                                 + '<param name="Loop" value="False" />'
260                                                 + '<param name="AutoPlay" value="' + (widget.options.autoplay ? 'True' : 'False') + '" />'
261                                                 + '<param name="Toolbar" value="False" />'
262                                         + '</object>')
263                                         .appendTo(widget.$videoContainer);
264                         }
265                 }
266         },
267         
268         setPlayButton: function() {
269                 $('button.ui-nsvideo-play', widget.element[0])
270                         .button('option', 'icons', { primary: "ui-icon-play" })
271                         .button('refresh');
272         },
273         setPauseButton: function() {
274                 $('button.ui-nsvideo-play', widget.element[0])
275                         .button('option', 'icons', { primary: "ui-icon-pause" })
276                         .button('refresh');
277         },
278         setMuteButton: function() {
279                 $('button.ui-nsvideo-mute', widget.element[0])
280                         .button('option', 'icons', { primary: "ui-icon-volume-off" })
281                         .button('refresh');
282         },
283         setUnmuteButton: function() {
284                 $('button.ui-nsvideo-mute', widget.element[0])
285                         .button('option', 'icons', { primary: "ui-icon-volume-on" })
286                         .button('refresh');
287         },
288         setTimeText: function(text) {
289                 //$('.ui-nsvideo-time', widget.element[0])
290                 this.$time
291                         .html(text);
292         },
293         setVolumeSlider: function(vol) {
294                 $('.ui-nsvideo-volume', widget.element[0])
295                         .slider('value', vol);
296         },
297         setProgressSlider: function(prog) {
298                 $('.ui-nsvideo-progress', widget.element[0])
299                         .slider('value', prog);
300         },
301         setLoadedProgressSlider: function(prog) {
302                 $('.ui-nsvideo-loaded-progress', widget.element[0])
303                         .progressbar('value', prog);
304         },
305         
306         videoPlugin: function(method, args) {
307                 if (typeof args == 'undefined')
308                         args = [];
309                 var videoPlugin = null;
310                 
311                 if (this.options.type.indexOf('html5') != -1)
312                 {
313                         videoPlugin = this.html5;
314                 }
315                 else if (this.options.type.indexOf('vlc') != -1)
316                 {
317                         videoPlugin = this.vlc;
318                 }
319                 
320                 if (videoPlugin)
321                         return videoPlugin[method].apply(this, args);
322                 
323                 return null;
324         },
325         
326         definition: function(def) {
327                 var widget = this;
328                 
329                 if (typeof def == 'undefined')
330                         return widget.options.definition;
331                 
332                 widget.options.definition = def;
333                 widget.video();
334                 
335                 return widget;
336         },
337         
338         type: function(type) {
339                 var widget = this;
340                 
341                 if (typeof type == 'undefined')
342                         return widget.options.type;
343                 
344                 widget.options.type = type;
345                 widget.video();
346                 
347                 // Initialize video plugin
348                 widget.$video.ready(function() {
349                         widget.videoPlugin('init');
350                 });
351                 
352                 return widget;
353         },
354         
355         crtSrc: function() {
356                 var src;
357                 var widget = this;
358                 
359                 if (typeof widget.options.src == 'string')
360                         src = widget.options.src;
361                 else if (typeof widget.options.src == 'object')
362                 {
363                         if (typeof widget.options.definition == 'undefined')
364                                 return null;
365                         
366                         if (typeof widget.options.src[ widget.options.definition ]
367                                 == 'undefined')
368                                 return null;
369                         
370                         src = widget.options.src[ widget.options.definition ];
371                 }
372                 
373                 if (widget.options.type == 'ns-html5')
374                         src = 'tribe://' + src;
375                 
376                 return src;
377         },
378         
379         html5: {
380                 widget: this,
381                 //lastTime: null,
382                 
383                 init: function() {
384                         widget.html5.refreshAll();
385                         
386                         //if (widget.options.autoplay)
387                         //      widget.html5.play();
388                 },
389                 
390                 togglePlay: function() {
391                         if (widget.$video[0].paused)
392                         {
393                                 widget.html5.play();
394                         }
395                         else
396                         {
397                                 widget.html5.pause();
398                         }
399                 },
400
401                 play: function() {
402                         if (widget.$video[0].paused)
403                                 widget.$video[0].play();
404                         
405                         widget.setPauseButton();
406                         
407                         return widget;
408                 },
409                 
410                 pause: function() {
411                         if (!widget.$video[0].paused)
412                                 widget.$video[0].pause();
413                         
414                         widget.setPlayButton();
415
416                         return widget;
417                 },
418                 
419                 toggleMute: function() {
420                         if (!widget.$video[0].muted)
421                         {
422                                 widget.html5.mute();
423                         }
424                         else
425                         {
426                                 widget.html5.unmute();
427                         }
428                 },
429                   
430                 mute: function() {
431                         if (!widget.$video[0].muted)
432                                 widget.$video[0].muted = true;
433                         
434                         widget.setMuteButton();
435                         
436                         return widget;
437                 },
438                 
439                 unmute: function() {
440                         if (widget.$video[0].muted)
441                                 widget.$video[0].muted = false;
442                         
443                         widget.setUnmuteButton();
444                         
445                         return widget;
446                 },
447                 
448                 /**
449                 * Volume value is expressed in percents.
450                 */
451                 volume: function(vol) {
452                         if (typeof vol == 'undefined')
453                                 return Math.round(widget.$video[0].volume * 100);
454                         
455                         widget.html5.unmute();
456                         widget.$video[0].volume = vol / 100;
457                         
458                         return widget;
459                 },
460                 
461                 /**
462                  * Seek position is a value between 0 and 1000.
463                  */
464                 crtTime: function(pos) {
465                         // getter
466                         if (typeof pos == 'undefined')
467                         {
468                                 var crtTime = widget.$video[0].currentTime;
469                                 var totTime = widget.$video[0].duration;
470                                 if (isNaN(totTime) || totTime == 0)
471                                         return 0;
472                                 else
473                                         return Math.round(crtTime / totTime * 1000.0);
474                         }
475                         
476                         // setter
477                         widget.$video[0].currentTime = 
478                                 pos / 1000 * widget.$video[0].duration;
479                 },
480                   
481                 refreshAll: function() {
482                         widget.html5.refreshState();
483                         widget.html5.refreshVolume();
484                         widget.html5.refreshLoadedProgress();
485                         widget.$time.html('--:-- / --:--');
486                         widget.$stateText.html('...');
487                         widget.html5.refreshTime();
488                 },
489                 
490                 refreshTime: function() {
491                         if (widget.$video[0].seeking)
492                                 return widget;
493                         
494                         var crtTime = widget.$video[0].currentTime;
495                         var totTime = widget.$video[0].duration;
496                         
497                         // Refresh only at refreshInterval seconds to save CPU time.
498                         var delta = crtTime - widget.html5.lastTime;
499                         if (typeof widget.html5.lastTime !== "undefined"
500                                 && delta >= 0 && delta < widget.options.refreshInterval)
501                                 return widget;
502                         widget.html5.lastTime = crtTime;
503                         
504                         // Current time string
505                         var crtH = Math.floor(crtTime / 3600);
506                         var crtM = Math.floor((crtTime / 60) % 60);
507                         var crtS = Math.floor(crtTime % 60);
508                         var strCrtTime = 
509                                 (crtH == 0 ? '' : (widget._leadingZeros(crtH) + ':'))
510                                 + widget._leadingZeros(crtM) + ':' + widget._leadingZeros(crtS);
511                                 
512                         // Total time string
513                         var totH = Math.floor(totTime / 3600);
514                         var totM = Math.floor((totTime / 60) % 60);
515                         var totS = Math.floor(totTime % 60);
516                         var strTotTime = 
517                                 (totH == 0 || isNaN(totH) ? '' : (widget._leadingZeros(totH) + ':'))
518                                 + widget._leadingZeros(totM) + ':' + widget._leadingZeros(totS);
519                         
520                         widget.setTimeText('' + strCrtTime + ' / ' + strTotTime);
521                         
522                         // Update time progress slider.
523                         widget.html5.refreshProgress();
524                         
525                         return widget;
526                 },
527                 
528                 refreshState: function() {
529                         // TODO refresh HTML5 plugin state
530                         
531                         return widget;
532                 },
533
534                 refreshVolume: function() {
535                         var vol;
536                         
537                         if (widget.$video[0].muted)
538                                 vol = 0;
539                         else
540                                 vol = Math.floor(widget.$video[0].volume * 100);
541                         
542                         widget.setVolumeSlider(vol);
543                         
544                         return widget;
545                 },
546                 
547                 refreshProgress: function() {
548                         widget.setProgressSlider(widget.html5.crtTime());
549                         
550                         return widget;
551                 },
552                 
553                 /**
554                 * Supported for Firefox 4.0 or later.
555                 */
556                 refreshLoadedProgress: function() {
557                         // Return if buffering status not available in browser.
558                         if (typeof widget.$video[0].buffered == 'undefined'
559                                 || widget.$video[0].buffered.length === 0)
560                                 return widget;
561                         
562                         var loadedTime = widget.$video[0].buffered.end(0);
563                         var totTime = widget.$video[0].duration;
564                         var percent;
565                         if (isNaN(totTime) || totTime == 0)
566                                 percent = 0
567                         else
568                                 percent = Math.floor(loadedTime / totTime * 100);
569                         
570                         widget.setLoadedProgressSlider(percent);
571                         
572                         return widget;
573                 },
574
575                 fullscreen: function() {
576                         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.');
577                 }
578         },
579         
580         vlc: {
581                 widget: this,
582                 timerHandle: null,
583                 
584                 STATES: {
585                         IDLE_CLOSE: [0, "Idle / Close"],
586                         OPENING: [1, "Opening..."],
587                         BUFFERING: [2, "Buffering..."],
588                         PLAYING: [3, "Playing..."],
589                         PAUSED: [4, "Paused"],
590                         STOPPING: [5, "Stopping..."],
591                         ERROR: [6, "Error!"]
592                 },
593                 
594                 init: function() {
595                         if (widget.options.autoplay)
596                                 widget.vlc.play();
597                         widget.vlc.refreshAll();
598                 },
599                 
600                 togglePlay: function() {
601                         if (! widget.$video[0].playlist.isPlaying)
602                         {
603                                 widget.vlc.play();
604                         }
605                         else
606                         {
607                                 widget.vlc.pause();
608                         }
609                 },
610                 
611                 play: function() {
612                         if (! widget.$video[0].playlist.isPlaying)
613                                 widget.$video[0].playlist.play();
614                         
615                         widget.setPauseButton();
616                         
617                         // Schedule information refreshment at refreshInterval seconds.
618                         if (! widget.vlc.timerHandle)
619                                 widget.vlc.timerHandle = setTimeout(widget.vlc.refreshHandler, 
620                                                                                 widget.options.refreshInterval * 1000);
621                                 
622                         widget.vlc.refreshState();
623                         
624                         return widget;
625                 },
626                 
627                 pause: function() {
628                         if (widget.$video[0].playlist.isPlaying)
629                                 widget.$video[0].playlist.togglePause();
630                         
631                         widget.setPlayButton();
632                         
633                         // Cancel information refreshment scheduling.
634                         clearTimeout(widget.vlc.timerHandle);
635                         widget.vlc.timerHandle = null;
636                         
637                         widget.vlc.refreshState();
638
639                         return widget;
640                 },
641                 
642                 toggleMute: function() {
643                         if (! widget.$video[0].audio.mute)
644                         {
645                                 widget.vlc.mute();
646                         }
647                         else
648                         {
649                                 widget.vlc.unmute();
650                         }
651                 },
652                   
653                 mute: function() {
654                         if (! widget.$video[0].audio.mute)
655                                 widget.$video[0].audio.toggleMute();
656                         
657                         widget.setMuteButton();
658                         
659                         widget.vlc.refreshVolume();
660                         
661                         return widget;
662                 },
663                 
664                 unmute: function() {
665                         if (widget.$video[0].audio.mute)
666                                 widget.$video[0].audio.toggleMute();
667                         
668                         widget.setUnmuteButton();
669                         
670                         widget.vlc.refreshVolume();
671                         
672                         return widget;
673                 },
674                 
675                 /**
676                 * Volume value is expressed in percents.
677                 */
678                 volume: function(vol) {
679                         if (typeof vol == 'undefined')
680                                 return Math.round(widget.$video[0].audio.volume);
681                         
682                         widget.vlc.unmute();
683                         widget.$video[0].audio.volume = vol;
684                         
685                         return widget;
686                 },
687                 
688                 /**
689                  * Seek position is a value between 0 and 1000.
690                  */
691                 crtTime: function(pos) {
692                         // getter
693                         if (typeof pos == 'undefined')
694                         {
695                                 var crtTime = widget.$video[0].input.time;
696                                 var totTime = widget.$video[0].input.length;
697                                 if (isNaN(totTime) || totTime == 0)
698                                         return 0;
699                                 else
700                                         return Math.round(crtTime / totTime * 1000.0);
701                         }
702                         
703                         // setter
704                         widget.$video[0].input.time = 
705                                 pos / 1000 * widget.$video[0].input.length;
706                                 
707                         widget.vlc.refreshState();
708                 },
709                 
710                 /**
711                  * Timeout callback called at refreshInterval during playing in order
712                  * to refresh information.
713                  */
714                 refreshHandler: function() {
715                         if (widget.$video[0].input.state
716                                 == widget.vlc.STATES.PLAYING[0])
717                         {
718                                 widget.vlc.refreshTime();
719                                 widget.vlc.timerHandle = setTimeout(widget.vlc.refreshHandler, 
720                                                                                 widget.options.refreshInterval * 1000);
721                         }
722                         else
723                                 widget.vlc.pause();
724                         
725                         widget.vlc.refreshState();
726                 },
727                 
728                 refreshAll: function() {
729                         widget.vlc.refreshState();
730                         widget.vlc.refreshVolume();
731                         widget.vlc.refreshLoadedProgress();
732                         
733                         try {
734                                 widget.vlc.refreshTime();
735                         } catch(e) {
736                                 console.log(e);
737                                 widget.$time.html('--:-- / --:--');
738                         }
739                 },
740                 
741                 refreshTime: function() {
742                         // TODO while seeking (maybe not necessary for VLC)
743 //                      if (widget.$video[0].seeking)
744 //                              return widget;
745                         
746                         // Time values in seconds.
747                         var crtTime = widget.$video[0].input.time / 1000.0;
748                         var totTime = widget.$video[0].input.length / 1000.0;
749                         //var crtTime = widget.$video[0].input.position * totTime;
750                         
751                         // Current time string
752                         var crtH = Math.floor(crtTime / 3600);
753                         var crtM = Math.floor((crtTime / 60) % 60);
754                         var crtS = Math.floor(crtTime % 60);
755                         var strCrtTime = 
756                                 (crtH == 0 ? '' : (widget._leadingZeros(crtH) + ':'))
757                                 + widget._leadingZeros(crtM) + ':' + widget._leadingZeros(crtS);
758                                 
759                         // Total time string
760                         var totH = Math.floor(totTime / 3600);
761                         var totM = Math.floor((totTime / 60) % 60);
762                         var totS = Math.floor(totTime % 60);
763                         var strTotTime = 
764                                 (totH == 0 || isNaN(totH) ? '' : (widget._leadingZeros(totH) + ':'))
765                                 + widget._leadingZeros(totM) + ':' + widget._leadingZeros(totS);
766                         
767                         widget.setTimeText('' + strCrtTime + ' / ' + strTotTime);
768                         
769                         // Update time progress slider.
770                         widget.vlc.refreshProgress();
771                         
772                         return widget;
773                 },
774                 
775                 _state: function(code) {
776                         var r;
777                         $.each(widget.vlc.STATES, function(index, value) {
778                                 if ('' + code == '' + value[0])
779                                 {
780                                         r = value;
781                                         return false;
782                                 }
783                         });
784                         
785                         return r;
786                 },
787                 
788                 refreshState: function() {
789                         widget.$stateText
790                                 .html(widget.vlc._state(widget.$video[0].input.state)[1]);
791                 },
792
793                 refreshVolume: function() {
794                         var vol;
795                         
796                         if (widget.$video[0].audio.mute)
797                                 vol = 0;
798                         else
799                                 vol = Math.floor(widget.$video[0].audio.volume);
800                         
801                         widget.setVolumeSlider(vol);
802                         
803                         return widget;
804                 },
805                 
806                 refreshProgress: function() {
807                         widget.setProgressSlider(widget.vlc.crtTime());
808                         
809                         return widget;
810                 },
811                 
812                 /**
813                 * Not supported for VLC.
814                 */
815                 refreshLoadedProgress: function() {
816                         // TODO Currently not possible through VLC API.
817                         
818                         return widget;
819                 },
820
821                 fullscreen: function() {
822                         widget.$video[0].video.toggleFullscreen();
823                 }
824         }
825 });
826
827 })( jQuery );