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