/* 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,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({ init: function(player, options, ready){ this.player = player; this.el = this.createElement(); this.ready(ready); var source = options.source; // If the element source is already set, we may have missed the loadstart event, and want to trigger it. // We don't want to set the source again and interrupt playback. if (source && this.el.currentSrc == source.src) { player.triggerEvent("loadstart"); // Otherwise set the source if one was provided. } else if (source) { this.el.src = source.src; } // Chrome and Safari both have issues with autoplay. // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work. // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays) // This fixes both issues. Need to wait for API, so it updates displays correctly player.ready(function(){ if (this.options.autoplay && this.paused()) { this.tag.poster = null; // Chrome Fix. Fixed in Chrome v16. this.play(); } }); this.triggerReady(); }, 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; _V_.insertFirst(el, player.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