/* Playback Technology - Base class for playback technologies ================================================================================ */ _V_.PlaybackTech = _V_.Component.extend({ init: function(player, options){ // this._super(player, options); // Make playback element clickable // _V_.addEvent(this.el, "click", _V_.proxy(this, _V_.PlayToggle.prototype.onClick)); // player.triggerEvent("techready"); }, createElement: function(){}, setupTriggers: function(){}, removeTriggers: function(){} }); // Create placeholder methods for each that warn when a method // isn't supported by the current playback technology _V_.apiMethods = "play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,exitFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted".split(","); _V_.each(_V_.apiMethods, function(methodName){ _V_.PlaybackTech.prototype[methodName] = function(){ throw new Error("The '"+method+"' method is not available on the playback technology's API"); } }); /* HTML5 Playback Technology - Wrapper for HTML5 Media API ================================================================================ */ _V_.HTML5 = _V_.PlaybackTech.extend({ name: "HTML5", init: function(player, options){ this.player = player; this.el = this.createElement(); var source = options.source; if (source && this.el.currentSrc != source.src) { this.el.src = source.src; } else if (source) { player.triggerEvent("loadstart"); } // Moving video inside box breaks autoplay on Safari. This forces it to play. // Currently triggering play in other browsers as well. player.addEvent("techready", function(){ if (this.options.autoplay && this.paused()) { this.play(); } this.removeEvent("techready", arguments.callee); }); // Trigger tech ready on player. // TODO: Switch to component ready when available. setTimeout(_V_.proxy(this, function(){ this.player.triggerEvent("techready"); }), 0); }, createElement: function(){ var html5 = _V_.HTML5, player = this.player, // Reuse original tag for HTML5 playback technology element el = player.tag, newEl; // Check if this browser supports moving the element into the box. // On the iPhone video will break if you move the element, // So we have to create a brand new element. if (html5.supports.movingElementInDOM === false) { newEl = _V_.createElement("video", { id: el.id, className: el.className }); player.el.removeChild(el); el = newEl; player.el.appendChild(el); } // Update tag settings, in case they were overridden _V_.each(["autoplay","preload","loop","muted","poster"], function(attr){ el[attr] = player.options[attr]; }, this); return el; }, setupTriggers: function(){ // Make video events trigger player events // May seem verbose here, but makes other APIs possible. // ["play", "playing", "pause", "ended", "volumechange", "error", "progress", "seeking", "timeupdate"] var types = _V_.HTML5.events, i; for (i = 0;i