1 // Add a way to instanciate using jQuery prototype. 2 if (!jQuery.fn.minplayer) { 3 4 /** 5 * @constructor 6 * 7 * Define a jQuery minplayer prototype. 8 * 9 * @param {object} options The options for this jQuery prototype. 10 * @return {Array} jQuery object. 11 */ 12 jQuery.fn.minplayer = function(options) { 13 return jQuery(this).each(function() { 14 options = options || {}; 15 options.id = options.id || $(this).attr('id') || Math.random(); 16 if (!minplayer.plugins[options.id]) { 17 options.template = options.template || 'default'; 18 if (minplayer[options.template]) { 19 new minplayer[options.template](jQuery(this), options); 20 } 21 else { 22 new minplayer(jQuery(this), options); 23 } 24 } 25 }); 26 }; 27 } 28 29 /** 30 * @constructor 31 * @extends minplayer.display 32 * @class The core media player class which governs the media player 33 * functionality. 34 * 35 * <p><strong>Usage:</strong> 36 * <pre><code> 37 * 38 * // Create a media player. 39 * var player = jQuery("#player").minplayer({ 40 * 41 * }); 42 * 43 * </code></pre> 44 * </p> 45 * 46 * @param {object} context The jQuery context. 47 * @param {object} options This components options. 48 */ 49 minplayer = jQuery.extend(function(context, options) { 50 51 // Derive from display 52 minplayer.display.call(this, 'player', context, options); 53 }, minplayer); 54 55 /** Derive from minplayer.display. */ 56 minplayer.prototype = new minplayer.display(); 57 58 /** Reset the constructor. */ 59 minplayer.prototype.constructor = minplayer; 60 61 /** 62 * Define a way to debug. 63 */ 64 minplayer.console = console || {log: function(data) {}}; 65 66 /** 67 * @see minplayer.plugin.construct 68 */ 69 minplayer.prototype.construct = function() { 70 71 // Allow them to provide arguments based off of the DOM attributes. 72 jQuery.each(this.context[0].attributes, (function(player) { 73 return function(index, attr) { 74 player.options[attr.name] = player.options[attr.name] || attr.value; 75 }; 76 })(this)); 77 78 // Make sure we provide default options... 79 this.options = jQuery.extend({ 80 id: 'player', 81 build: false, 82 wmode: 'transparent', 83 preload: true, 84 autoplay: false, 85 loop: false, 86 width: '100%', 87 height: '350px', 88 debug: false, 89 volume: 80, 90 files: [], 91 file: '', 92 preview: '', 93 attributes: {} 94 }, this.options); 95 96 // Call the minplayer display constructor. 97 minplayer.display.prototype.construct.call(this); 98 99 /** The controller for this player. */ 100 this.controller = this.create('controller'); 101 102 /** The play loader for this player. */ 103 this.playLoader = this.create('playLoader'); 104 105 /** Variable to store the current media player. */ 106 this.currentPlayer = 'html5'; 107 108 // Add key events to the window. 109 this.addKeyEvents(); 110 111 // Now load these files. 112 this.load(this.getFiles()); 113 114 // Add the player events. 115 this.addEvents(); 116 117 // The player is ready. 118 this.ready(); 119 }; 120 121 /** 122 * We need to bind to events we are interested in. 123 */ 124 minplayer.prototype.addEvents = function() { 125 minplayer.get.call(this, this.options.id, null, (function(player) { 126 return function(plugin) { 127 128 // Bind to the error event. 129 plugin.bind('error', function(event, data) { 130 131 // If an error occurs within the html5 media player, then try 132 // to fall back to the flash player. 133 if (player.currentPlayer == 'html5') { 134 player.options.file.player = 'minplayer'; 135 player.loadPlayer(); 136 } 137 else { 138 player.error(data); 139 } 140 }); 141 142 // Bind to the fullscreen event. 143 plugin.bind('fullscreen', function(event, data) { 144 player.resize(); 145 }); 146 }; 147 })(this)); 148 }; 149 150 /** 151 * Sets an error on the player. 152 * 153 * @param {string} error The error to display on the player. 154 */ 155 minplayer.prototype.error = function(error) { 156 error = error || ''; 157 if (this.elements.error) { 158 159 // Set the error text. 160 this.elements.error.text(error); 161 if (error) { 162 this.elements.error.show(); 163 } 164 else { 165 this.elements.error.hide(); 166 } 167 } 168 }; 169 170 /** 171 * Adds key events to the player. 172 */ 173 minplayer.prototype.addKeyEvents = function() { 174 jQuery(document).bind('keydown', (function(player) { 175 return function(event) { 176 switch (event.keyCode) { 177 case 113: // ESC 178 case 27: // Q 179 if (player.isFullScreen()) { 180 player.fullscreen(false); 181 } 182 break; 183 } 184 }; 185 })(this)); 186 }; 187 188 /** 189 * Returns all the media files available for this player. 190 * 191 * @return {array} All the media files for this player. 192 */ 193 minplayer.prototype.getFiles = function() { 194 var files = []; 195 var mediaSrc = null; 196 197 // Get the files involved... 198 if (this.elements.media) { 199 mediaSrc = this.elements.media.attr('src'); 200 if (mediaSrc) { 201 files.push({'path': mediaSrc}); 202 } 203 jQuery('source', this.elements.media).each(function() { 204 files.push({ 205 'path': jQuery(this).attr('src'), 206 'mimetype': jQuery(this).attr('type'), 207 'codecs': jQuery(this).attr('codecs') 208 }); 209 }); 210 } 211 212 return files; 213 }; 214 215 /** 216 * Returns the full media player object. 217 * @param {array} files An array of files to chose from. 218 * @return {object} The best media file to play in the current browser. 219 */ 220 minplayer.prototype.getMediaFile = function(files) { 221 222 // If there are no files then return null. 223 if (!files) { 224 return null; 225 } 226 227 // If the file is a single string, then return the file object. 228 if (typeof files === 'string') { 229 return new minplayer.file({'path': files}); 230 } 231 232 // If the file is already a file object then just return. 233 if (files.path || files.id) { 234 return new minplayer.file(files); 235 } 236 237 // Add the files and get the best player to play. 238 var i = files.length, bestPriority = 0, mFile = null, file = null; 239 while (i--) { 240 file = files[i]; 241 242 // Get the minplayer file object. 243 if (typeof file === 'string') { 244 file = new minplayer.file({'path': file}); 245 } 246 else { 247 file = new minplayer.file(file); 248 } 249 250 // Determine the best file for this browser. 251 if (file.priority > bestPriority) { 252 mFile = file; 253 } 254 } 255 256 // Return the best minplayer file. 257 return mFile; 258 }; 259 260 /** 261 * Loads a media player based on the current file. 262 */ 263 minplayer.prototype.loadPlayer = function() { 264 265 // Do nothing if there isn't a file. 266 if (!this.options.file) { 267 this.error('No media found.'); 268 return; 269 } 270 271 if (!this.options.file.player) { 272 this.error('Cannot play media: ' + this.options.file.mimetype); 273 return; 274 } 275 276 // Reset the error. 277 this.error(); 278 279 // Only destroy if the current player is different than the new player. 280 var player = this.options.file.player.toString(); 281 282 // If there isn't media or if the players are different. 283 if (!this.media || (player !== this.currentPlayer)) { 284 285 // Set the current media player. 286 this.currentPlayer = player; 287 288 // Do nothing if we don't have a display. 289 if (!this.elements.display) { 290 this.error('No media display found.'); 291 return; 292 } 293 294 // Destroy the current media. 295 var queue = {}; 296 if (this.media) { 297 queue = this.media.queue; 298 this.media.destroy(); 299 } 300 301 // Get the class name and create the new player. 302 pClass = minplayer.players[this.options.file.player]; 303 304 // Create the new media player. 305 this.options.mediaelement = this.elements.media; 306 this.media = new pClass(this.elements.display, this.options, queue); 307 308 // Now get the media when it is ready. 309 this.get('media', (function(player) { 310 return function(media) { 311 312 // Load the media. 313 media.load(player.options.file); 314 }; 315 })(this)); 316 } 317 // If the media object already exists... 318 else if (this.media) { 319 320 // Now load the different media file. 321 this.media.load(this.options.file); 322 } 323 }; 324 325 /** 326 * Load a set of files or a single file for the media player. 327 * 328 * @param {array} files An array of files to chose from to load. 329 */ 330 minplayer.prototype.load = function(files) { 331 332 // Set the id and class. 333 var id = '', pClass = ''; 334 335 // If no file was provided, then get it. 336 this.options.files = files || this.options.files; 337 this.options.file = this.getMediaFile(this.options.files); 338 339 // Now load the player. 340 this.loadPlayer(); 341 }; 342 343 /** 344 * Called when the player is resized. 345 */ 346 minplayer.prototype.resize = function() { 347 348 // Call onRezie for each plugin. 349 this.get(function(plugin) { 350 if (plugin.onResize) { 351 plugin.onResize(); 352 } 353 }); 354 }; 355