2 * jQuery UI NS-Video @VERSION
4 * Copyright 2011, Călin-Andrei Burloiu
5 * Dual licensed under the MIT or GPL Version 2 licenses.
6 * http://jquery.org/license
14 function padWithZeros(number, length)
23 for (var i=0; i<length; i++)
29 while (str.length < length)
37 (function( $, undefined ) {
39 $.widget( "ui.nsvideo", {
43 //src: 'http://10.38.128.248/devel/data/torrents/rtt01a_600p.ogv.tstream' // TODO no default src
44 //src: 'http://10.38.128.248/devel/data/torrents/IndependentaRomaniei_240p.ogv.tstream' // TODO no default src
53 .addClass( "ui-widget ui-widget-content ui-corner-all" );
55 widget.$nsPlugin = $('<div class="ui-nsvideo-nsplugin"></div>')
56 .appendTo(widget.element);
57 widget.$progressContainer = $('<div class="ui-nsvideo-progress-container ui-widget-content ui-corner-top"></div>')
58 .appendTo(widget.element);
59 widget.$progress = $('<div class="ui-nsvideo-progress"></div>')
60 .appendTo(widget.$progressContainer);
61 widget.$loadedProgress = $('<div class="ui-nsvideo-loaded-progress"></div>')
62 .appendTo(widget.$progress);
63 widget.$controls = $('<div class="ui-nsvideo-controls ui-widget-content ui-corner-bottom"></div>')
64 .appendTo(widget.element);
68 // Time progress slider with load progress also
69 widget.$loadedProgress
70 // TODO an object that inherits progressbar should be used in order to customize min value.
78 max: 1000, //Math.floor(widget.$video[0].duration),
79 slide: function(event, ui) {
80 widget.$video[0].currentTime =
81 ui.value / 1000 * widget.$video[0].duration;
86 $('<button class="ui-nsvideo-play ui-nsvideo-control-left">Play / Pause</button>')
87 .appendTo(widget.$controls)
90 icons: { primary: "ui-icon-play" }
96 // Time information (current and total)
97 $('<div class="ui-nsvideo-time ui-nsvideo-control-left">--:-- / --:--</div>')
98 .appendTo(widget.$controls);
100 // Video definition buttonset
101 if (typeof widget.options.src == 'object')
103 var $definitions = $('<form><div class="ui-nsvideo-definitions ui-nsvideo-control-right"></div></form>')
104 .appendTo(widget.$controls);
105 $definitions = $('.ui-nsvideo-definitions', $definitions[0]);
106 $.each(widget.options.src, function(index, value) {
107 id = widget.element.attr('id') + '-def-' + index;
108 $('<input type="radio" id="' + id + '" name="definition" />')
109 .appendTo($definitions)
110 .attr('checked', (index == widget.options.definition))
112 widget.setDefinition(index);
114 $('<label for="' + id + '">' + index + '</label>')
115 .appendTo($definitions);
118 $definitions.buttonset();
122 $('<div class="ui-nsvideo-volume ui-nsvideo-control-right"></div>')
123 .appendTo(widget.$controls)
128 slide: function(event, ui) {
129 widget.unmuteHtml5();
130 widget.$video[0].volume = ui.value / 100;
135 $('<button class="ui-nsvideo-mute ui-nsvideo-control-right">Mute</button>')
136 .appendTo(widget.$controls)
139 icons: { primary: "ui-icon-volume-on" }
146 $('<div class="ui-helper-clearfix"></div>')
147 .appendTo(widget.$controls);
150 _destroy: function() {
154 _setOption: function( key, value ) {
155 if ( key === "TODO" ) {
159 this._super( "_setOption", key, value );
162 setVideo: function() {
165 // Select video source.
166 // If src option is string, that's the source.
167 // If src is an object, properties are definitions and values are
169 var src = widget.getCrtSrc();
173 widget.$nsPlugin.html('');
175 if (widget.options.type == 'ns-html5'
176 || widget.options.type == 'html5')
178 widget.$video = $('<video id="vid" src="' + src + '" width="800" height="450" preload="auto">'
179 +'Error: Your browser does not support HTML5 or the video format!'
181 .appendTo(widget.$nsPlugin)
192 timeupdate: function() {
193 widget.refreshTimeHtml5();
195 progress: function() {
196 widget.refreshLoadedProgressHtml5();
198 loadedmetadata: function() {
199 widget.refreshTimeHtml5();
200 widget.refreshVolumeHtml5();
205 volumechange: function() {
206 widget.refreshVolumeHtml5();
212 playHtml5: function() {
213 if (this.$video[0].paused)
214 this.$video[0].play();
216 $('button.ui-nsvideo-play', this.element[0])
217 .button('option', 'icons', { primary: "ui-icon-pause" })
223 pauseHtml5: function() {
224 if (!this.$video[0].paused)
225 this.$video[0].pause();
227 $('button.ui-nsvideo-play', this.element[0])
228 .button('option', 'icons', { primary: "ui-icon-play" })
234 refreshTimeHtml5: function() {
237 if (widget.$video[0].seeking)
240 var crtTime = widget.$video[0].currentTime;
241 var totTime = widget.$video[0].duration;
243 // Refresh only at 0.1 s to save CPU time.
244 var delta = crtTime - widget.lastTime;
245 if (typeof widget.lastTime != "undefined" && delta >= 0 && delta < 0.1)
247 widget.lastTime = crtTime;
249 // Current time string
250 var crtH = Math.floor(crtTime / 3600);
251 var crtM = Math.floor((crtTime / 60) % 60);
252 var crtS = Math.floor(crtTime % 60);
254 (crtH == 0 ? '' : (padWithZeros(crtH) + ':'))
255 + padWithZeros(crtM) + ':' + padWithZeros(crtS);
258 var totH = Math.floor(totTime / 3600);
259 var totM = Math.floor((totTime / 60) % 60);
260 var totS = Math.floor(totTime % 60);
262 (totH == 0 || isNaN(totH) ? '' : (padWithZeros(totH) + ':'))
263 + padWithZeros(totM) + ':' + padWithZeros(totS);
265 $('.ui-nsvideo-time', widget.element[0])
266 .html('' + strCrtTime + ' / ' + strTotTime);
268 // Update time progress slider.
269 widget.refreshProgressHtml5();
274 muteHtml5: function() {
275 if (!this.$video[0].muted)
276 this.$video[0].muted = true;
278 $('button.ui-nsvideo-mute', this.element[0])
279 .button('option', 'icons', { primary: "ui-icon-volume-off" })
285 unmuteHtml5: function() {
286 if (this.$video[0].muted)
287 this.$video[0].muted = false;
289 $('button.ui-nsvideo-mute', this.element[0])
290 .button('option', 'icons', { primary: "ui-icon-volume-on" })
296 refreshVolumeHtml5: function() {
299 if (this.$video[0].muted)
302 vol = Math.floor(this.$video[0].volume * 100);
304 $('.ui-nsvideo-volume', this.element[0])
305 .slider('value', vol);
310 refreshProgressHtml5: function() {
311 var crtTime = this.$video[0].currentTime;
312 var totTime = this.$video[0].duration;
314 if (isNaN(totTime) || totTime == 0)
317 permilia = Math.floor(crtTime / totTime * 1000);
319 $('.ui-nsvideo-progress', this.element[0])
320 .slider('value', permilia);
326 * Supported for Firefox 4.0 or later.
328 refreshLoadedProgressHtml5: function() {
329 // Return if buffering status not available in browser.
330 if (typeof this.$video[0].buffered == 'undefined'
331 || this.$video[0].buffered.length === 0)
334 var loadedTime = this.$video[0].buffered.end(0);
335 var totTime = this.$video[0].duration;
337 if (isNaN(totTime) || totTime == 0)
340 percent = Math.floor(loadedTime / totTime * 100);
342 $('.ui-nsvideo-loaded-progress', this.element[0])
343 .progressbar('value', percent);
348 togglePlay: function() {
349 if (this.options.type.indexOf('html5') != -1)
351 if (this.$video[0].paused)
360 else if (this.options.type == 'ns-vlc')
368 toggleMute: function() {
369 if (this.options.type.indexOf('html5') != -1)
371 if (!this.$video[0].muted)
380 else if (this.options.type == 'ns-vlc')
388 getCrtSrc: function() {
392 if (typeof widget.options.src == 'string')
393 src = widget.options.src;
394 else if (typeof widget.options.src == 'object')
396 if (typeof widget.options.definition == 'undefined')
399 if (typeof widget.options.src[ widget.options.definition ]
403 src = widget.options.src[ widget.options.definition ];
406 if (widget.options.type == 'ns-html5')
407 src = 'tribe://' + src;
412 setDefinition: function(definition) {
413 if (this.options.type.indexOf('html5') != -1)
415 this.options.definition = definition;