1 /** The minplayer namespace. */ 2 var minplayer = minplayer || {}; 3 4 /** All the media player implementations */ 5 minplayer.players = minplayer.players || {}; 6 7 /** 8 * @constructor 9 * @extends minplayer.display 10 * @class The HTML5 media player implementation. 11 * 12 * @param {object} context The jQuery context. 13 * @param {object} options This components options. 14 */ 15 minplayer.players.html5 = function(context, options) { 16 17 // Derive players base. 18 minplayer.players.base.call(this, context, options); 19 }; 20 21 /** Derive from minplayer.players.base. */ 22 minplayer.players.html5.prototype = new minplayer.players.base(); 23 24 /** Reset the constructor. */ 25 minplayer.players.html5.prototype.constructor = minplayer.players.html5; 26 27 /** 28 * @see minplayer.players.base#getPriority 29 * @return {number} The priority of this media player. 30 */ 31 minplayer.players.html5.getPriority = function() { 32 return 10; 33 }; 34 35 /** 36 * @see minplayer.players.base#canPlay 37 * @return {boolean} If this player can play this media type. 38 */ 39 minplayer.players.html5.canPlay = function(file) { 40 switch (file.mimetype) { 41 case 'video/ogg': 42 return !!minplayer.playTypes.videoOGG; 43 case 'video/mp4': 44 return !!minplayer.playTypes.videoH264; 45 case 'video/x-webm': 46 case 'video/webm': 47 case 'application/octet-stream': 48 return !!minplayer.playTypes.videoWEBM; 49 case 'audio/ogg': 50 return !!minplayer.playTypes.audioOGG; 51 case 'audio/mpeg': 52 return !!minplayer.playTypes.audioMP3; 53 case 'audio/mp4': 54 return !!minplayer.playTypes.audioMP4; 55 default: 56 return false; 57 } 58 }; 59 60 /** 61 * @see minplayer.plugin.construct 62 */ 63 minplayer.players.html5.prototype.construct = function() { 64 65 // Call base constructor. 66 minplayer.players.base.prototype.construct.call(this); 67 68 // Store the this pointer... 69 var _this = this; 70 71 // For the HTML5 player, we will just pass events along... 72 if (this.player) { 73 74 this.player.addEventListener('abort', function() { 75 _this.trigger('abort'); 76 }, false); 77 this.player.addEventListener('loadstart', function() { 78 _this.onReady(); 79 }, false); 80 this.player.addEventListener('loadeddata', function() { 81 _this.onLoaded(); 82 }, false); 83 this.player.addEventListener('loadedmetadata', function() { 84 _this.onLoaded(); 85 }, false); 86 this.player.addEventListener('canplaythrough', function() { 87 _this.onLoaded(); 88 }, false); 89 this.player.addEventListener('ended', function() { 90 _this.onComplete(); 91 }, false); 92 this.player.addEventListener('pause', function() { 93 _this.onPaused(); 94 }, false); 95 this.player.addEventListener('play', function() { 96 _this.onPlaying(); 97 }, false); 98 this.player.addEventListener('playing', function() { 99 _this.onPlaying(); 100 }, false); 101 this.player.addEventListener('error', function() { 102 _this.trigger('error', 'An error occured - ' + this.error.code); 103 }, false); 104 this.player.addEventListener('waiting', function() { 105 _this.onWaiting(); 106 }, false); 107 this.player.addEventListener('durationchange', function() { 108 _this.duration.set(this.duration); 109 _this.trigger('durationchange', {duration: this.duration}); 110 }, false); 111 this.player.addEventListener('progress', function(event) { 112 _this.bytesTotal.set(event.total); 113 _this.bytesLoaded.set(event.loaded); 114 }, false); 115 } 116 }; 117 118 /** 119 * @see minplayer.players.base#playerFound 120 * @return {boolean} TRUE - if the player is in the DOM, FALSE otherwise. 121 */ 122 minplayer.players.html5.prototype.playerFound = function() { 123 return (this.display.find(this.mediaFile.type).length > 0); 124 }; 125 126 /** 127 * @see minplayer.players.base#create 128 * @return {object} The media player entity. 129 */ 130 minplayer.players.html5.prototype.create = function() { 131 minplayer.players.base.prototype.create.call(this); 132 var element = jQuery(document.createElement(this.mediaFile.type)) 133 .attr(this.options.attributes) 134 .append( 135 jQuery(document.createElement('source')).attr({ 136 'src': this.mediaFile.path 137 }) 138 ); 139 140 // Fix the fluid width and height. 141 element.eq(0)[0].setAttribute('width', '100%'); 142 element.eq(0)[0].setAttribute('height', '100%'); 143 return element; 144 }; 145 146 /** 147 * @see minplayer.players.base#getPlayer 148 * @return {object} The media player object. 149 */ 150 minplayer.players.html5.prototype.getPlayer = function() { 151 return this.options.elements.media.eq(0)[0]; 152 }; 153 154 /** 155 * @see minplayer.players.base#load 156 */ 157 minplayer.players.html5.prototype.load = function(file) { 158 159 if (file && this.isReady()) { 160 161 // Get the current source. 162 var src = this.options.elements.media.attr('src'); 163 164 // If the source is different. 165 if (src != file.path) { 166 167 // Change the source... 168 var code = '<source src="' + file.path + '" '; 169 code += 'type="' + file.mimetype + '"'; 170 code += file.codecs ? ' codecs="' + file.path + '">' : '>'; 171 this.options.elements.media.attr('src', '').empty().html(code); 172 } 173 } 174 175 // Always call the base first on load... 176 minplayer.players.base.prototype.load.call(this, file); 177 }; 178 179 /** 180 * @see minplayer.players.base#play 181 */ 182 minplayer.players.html5.prototype.play = function() { 183 minplayer.players.base.prototype.play.call(this); 184 if (this.isReady()) { 185 this.player.play(); 186 } 187 }; 188 189 /** 190 * @see minplayer.players.base#pause 191 */ 192 minplayer.players.html5.prototype.pause = function() { 193 minplayer.players.base.prototype.pause.call(this); 194 if (this.isReady()) { 195 this.player.pause(); 196 } 197 }; 198 199 /** 200 * @see minplayer.players.base#stop 201 */ 202 minplayer.players.html5.prototype.stop = function() { 203 minplayer.players.base.prototype.stop.call(this); 204 if (this.isReady()) { 205 this.player.pause(); 206 this.player.src = ''; 207 } 208 }; 209 210 /** 211 * @see minplayer.players.base#seek 212 */ 213 minplayer.players.html5.prototype.seek = function(pos) { 214 minplayer.players.base.prototype.seek.call(this, pos); 215 if (this.isReady()) { 216 this.player.currentTime = pos; 217 } 218 }; 219 220 /** 221 * @see minplayer.players.base#setVolume 222 */ 223 minplayer.players.html5.prototype.setVolume = function(vol) { 224 minplayer.players.base.prototype.setVolume.call(this, vol); 225 if (this.isReady()) { 226 this.player.volume = vol; 227 } 228 }; 229 230 /** 231 * @see minplayer.players.base#getVolume 232 */ 233 minplayer.players.html5.prototype.getVolume = function(callback) { 234 if (this.isReady()) { 235 callback(this.player.volume); 236 } 237 }; 238 239 /** 240 * @see minplayer.players.base#getDuration 241 */ 242 minplayer.players.html5.prototype.getDuration = function(callback) { 243 if (this.isReady()) { 244 callback(this.player.duration); 245 } 246 }; 247 248 /** 249 * @see minplayer.players.base#getCurrentTime 250 */ 251 minplayer.players.html5.prototype.getCurrentTime = function(callback) { 252 if (this.isReady()) { 253 callback(this.player.currentTime); 254 } 255 }; 256 257 /** 258 * @see minplayer.players.base#getBytesLoaded 259 */ 260 minplayer.players.html5.prototype.getBytesLoaded = function(callback) { 261 if (this.isReady()) { 262 var loaded = 0; 263 264 // Check several different possibilities. 265 if (this.bytesLoaded.value) { 266 loaded = this.bytesLoaded.value; 267 } 268 else if (this.player.buffered && 269 this.player.buffered.length > 0 && 270 this.player.buffered.end && 271 this.player.duration) { 272 loaded = this.player.buffered.end(0); 273 } 274 else if (this.player.bytesTotal != undefined && 275 this.player.bytesTotal > 0 && 276 this.player.bufferedBytes != undefined) { 277 loaded = this.player.bufferedBytes; 278 } 279 280 // Return the loaded amount. 281 callback(loaded); 282 } 283 }; 284 285 /** 286 * @see minplayer.players.base#getBytesTotal 287 */ 288 minplayer.players.html5.prototype.getBytesTotal = function(callback) { 289 if (this.isReady()) { 290 291 var total = 0; 292 293 // Check several different possibilities. 294 if (this.bytesTotal.value) { 295 total = this.bytesTotal.value; 296 } 297 else if (this.player.buffered && 298 this.player.buffered.length > 0 && 299 this.player.buffered.end && 300 this.player.duration) { 301 total = this.player.duration; 302 } 303 else if (this.player.bytesTotal != undefined && 304 this.player.bytesTotal > 0 && 305 this.player.bufferedBytes != undefined) { 306 total = this.player.bytesTotal; 307 } 308 309 // Return the loaded amount. 310 callback(total); 311 } 312 }; 313