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