1 /** The minplayer namespace. */ 2 var minplayer = minplayer || {}; 3 4 /** Define the controller object. */ 5 minplayer.controller = minplayer.controller || {}; 6 7 /** 8 * @constructor 9 * @extends minplayer.display 10 * @class This is the base minplayer controller. Other controllers can derive 11 * from the base and either build on top of it or simply define the elements 12 * that this base controller uses. 13 * 14 * @param {object} context The jQuery context. 15 * @param {object} options This components options. 16 */ 17 minplayer.controller.base = function(context, options) { 18 19 // Derive from display 20 minplayer.display.call(this, 'controller', context, options); 21 }; 22 23 // Define the prototype for all controllers. 24 var controllersBase = minplayer.controller.base; 25 26 /** Derive from minplayer.display. */ 27 minplayer.controller.base.prototype = new minplayer.display(); 28 29 /** Reset the constructor. */ 30 minplayer.controller.base.prototype.constructor = minplayer.controller.base; 31 32 /** 33 * A static function that will format a time value into a string time format. 34 * 35 * @param {integer} time An integer value of time. 36 * @return {string} A string representation of the time. 37 */ 38 minplayer.formatTime = function(time) { 39 time = time || 0; 40 var seconds = 0, minutes = 0, hour = 0, timeString = ''; 41 42 hour = Math.floor(time / 3600); 43 time -= (hour * 3600); 44 minutes = Math.floor(time / 60); 45 time -= (minutes * 60); 46 seconds = Math.floor(time % 60); 47 48 if (hour) { 49 timeString += String(hour); 50 timeString += ':'; 51 } 52 53 timeString += (minutes >= 10) ? String(minutes) : ('0' + String(minutes)); 54 timeString += ':'; 55 timeString += (seconds >= 10) ? String(seconds) : ('0' + String(seconds)); 56 return {time: timeString, units: ''}; 57 }; 58 59 /** 60 * @see minplayer.display#getElements 61 * @return {object} The elements defined by this display. 62 */ 63 minplayer.controller.base.prototype.getElements = function() { 64 var elements = minplayer.display.prototype.getElements.call(this); 65 return jQuery.extend(elements, { 66 play: null, 67 pause: null, 68 fullscreen: null, 69 seek: null, 70 progress: null, 71 volume: null, 72 timer: null 73 }); 74 }; 75 76 /** 77 * @see minplayer.plugin#construct 78 */ 79 minplayer.controller.base.prototype.construct = function() { 80 81 // Call the minplayer plugin constructor. 82 minplayer.display.prototype.construct.call(this); 83 84 // Keep track of if we are dragging... 85 this.dragging = false; 86 87 // If they have a seek bar. 88 if (this.elements.seek) { 89 90 // Create the seek bar slider control. 91 this.seekBar = this.elements.seek.slider({ 92 range: 'min' 93 }); 94 } 95 96 // If they have a volume bar. 97 if (this.elements.volume) { 98 99 // Create the volume bar slider control. 100 this.volumeBar = this.elements.volume.slider({ 101 range: 'min', 102 orientation: 'vertical' 103 }); 104 } 105 106 // Get the player plugin. 107 this.get('player', function(player) { 108 109 // If they have a fullscreen button. 110 if (this.elements.fullscreen) { 111 112 // Bind to the click event. 113 this.elements.fullscreen.unbind().bind('click', function(e) { 114 115 // Toggle fullscreen mode. 116 player.toggleFullScreen(); 117 }).css({'pointer' : 'hand'}); 118 } 119 }); 120 121 // Get the media plugin. 122 this.get('media', function(media) { 123 124 var _this = this; 125 126 // If they have a pause button 127 if (this.elements.pause) { 128 129 // Bind to the click on this button. 130 this.elements.pause.unbind().bind('click', {obj: this}, function(e) { 131 e.preventDefault(); 132 e.data.obj.playPause(false, media); 133 }); 134 135 // Bind to the pause event of the media. 136 media.bind('pause', {obj: this}, function(e) { 137 e.data.obj.setPlayPause(true); 138 }); 139 } 140 141 // If they have a play button 142 if (this.elements.play) { 143 144 // Bind to the click on this button. 145 this.elements.play.unbind().bind('click', {obj: this}, function(e) { 146 e.preventDefault(); 147 e.data.obj.playPause(true, media); 148 }); 149 150 // Bind to the play event of the media. 151 media.bind('playing', {obj: this}, function(e) { 152 e.data.obj.setPlayPause(false); 153 }); 154 } 155 156 // If they have a duration, then trigger on duration change. 157 if (this.elements.duration) { 158 159 // Bind to the duration change event. 160 media.bind('durationchange', {obj: this}, function(e, data) { 161 e.data.obj.setTimeString('duration', data.duration); 162 }); 163 164 // Set the timestring to the duration. 165 media.getDuration(function(duration) { 166 _this.setTimeString('duration', duration); 167 }); 168 } 169 170 // If they have a progress element. 171 if (this.elements.progress) { 172 173 // Bind to the progress event. 174 media.bind('progress', {obj: this}, function(e, data) { 175 var percent = data.total ? (data.loaded / data.total) * 100 : 0; 176 e.data.obj.elements.progress.width(percent + '%'); 177 }); 178 } 179 180 // If they have a seek bar or timer, bind to the timeupdate. 181 if (this.seekBar || this.elements.timer) { 182 183 // Bind to the time update event. 184 media.bind('timeupdate', {obj: this}, function(e, data) { 185 if (!e.data.obj.dragging) { 186 var value = 0; 187 if (data.duration) { 188 value = (data.currentTime / data.duration) * 100; 189 } 190 191 // Update the seek bar if it exists. 192 if (e.data.obj.seekBar) { 193 e.data.obj.seekBar.slider('option', 'value', value); 194 } 195 196 e.data.obj.setTimeString('timer', data.currentTime); 197 } 198 }); 199 } 200 201 // If they have a seekBar element. 202 if (this.seekBar) { 203 204 // Register the events for the control bar to control the media. 205 this.seekBar.slider({ 206 start: function(event, ui) { 207 _this.dragging = true; 208 }, 209 stop: function(event, ui) { 210 _this.dragging = false; 211 media.getDuration(function(duration) { 212 media.seek((ui.value / 100) * duration); 213 }); 214 }, 215 slide: function(event, ui) { 216 media.getDuration(function(duration) { 217 var time = (ui.value / 100) * duration; 218 if (!_this.dragging) { 219 media.seek(time); 220 } 221 _this.setTimeString('timer', time); 222 }); 223 } 224 }); 225 } 226 227 // Setup the volume bar. 228 if (this.volumeBar) { 229 230 // Create the slider. 231 this.volumeBar.slider({ 232 slide: function(event, ui) { 233 media.setVolume(ui.value / 100); 234 } 235 }); 236 237 media.bind('volumeupdate', {obj: this}, function(event, vol) { 238 event.data.obj.volumeBar.slider('option', 'value', (vol * 100)); 239 }); 240 241 // Set the volume to match that of the player. 242 media.getVolume(function(vol) { 243 _this.volumeBar.slider('option', 'value', (vol * 100)); 244 }); 245 } 246 }); 247 248 // We are now ready. 249 this.ready(); 250 }; 251 252 /** 253 * Sets the play and pause state of the control bar. 254 * 255 * @param {boolean} state TRUE - Show Play, FALSE - Show Pause. 256 */ 257 minplayer.controller.base.prototype.setPlayPause = function(state) { 258 var css = ''; 259 if (this.elements.play) { 260 css = state ? 'inherit' : 'none'; 261 this.elements.play.css('display', css); 262 } 263 if (this.elements.pause) { 264 css = state ? 'none' : 'inherit'; 265 this.elements.pause.css('display', css); 266 } 267 }; 268 269 /** 270 * Plays or pauses the media. 271 * 272 * @param {bool} state true => play, false => pause. 273 * @param {object} media The media player object. 274 */ 275 minplayer.controller.base.prototype.playPause = function(state, media) { 276 var type = state ? 'play' : 'pause'; 277 this.display.trigger(type); 278 this.setPlayPause(!state); 279 if (media) { 280 media[type](); 281 } 282 }; 283 284 /** 285 * Sets the time string on the control bar. 286 * 287 * @param {string} element The name of the element to set. 288 * @param {number} time The total time amount to set. 289 */ 290 minplayer.controller.base.prototype.setTimeString = function(element, time) { 291 if (this.elements[element]) { 292 this.elements[element].text(minplayer.formatTime(time).time); 293 } 294 }; 295