2011-11-29 11:40:05 -08:00
/ * P l a y b a c k T e c h n o l o g y - B a s e c l a s s f o r p l a y b a c k t e c h n o l o g i e s
=== === === === === === === === === === === === === === === === === === === === === === === === === === == * /
_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));
2012-01-05 23:25:09 -08:00
// this.addEvent("click", this.proxy(this.onClick));
2011-11-29 11:40:05 -08:00
// player.triggerEvent("techready");
2012-01-05 23:25:09 -08:00
} ,
2012-01-02 13:02:04 -08:00
// destroy: function(){},
2011-12-07 22:02:40 -08:00
// createElement: function(){},
2012-01-05 23:25:09 -08:00
onClick : function ( ) {
if ( this . player . options . controls ) {
_V _ . PlayToggle . prototype . onClick . call ( this ) ;
}
}
2011-11-29 11:40:05 -08:00
} ) ;
2011-12-07 22:02:40 -08:00
// Create placeholder methods for each that warn when a method isn't supported by the current playback technology
2011-12-01 16:48:06 -08:00
_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 ( "," ) ;
2011-11-29 11:40:05 -08:00
_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" ) ;
}
} ) ;
/ * H T M L 5 P l a y b a c k T e c h n o l o g y - W r a p p e r f o r H T M L 5 M e d i a A P I
=== === === === === === === === === === === === === === === === === === === === === === === === === === == * /
2011-12-07 21:03:12 -08:00
_V _ . html5 = _V _ . PlaybackTech . extend ( {
2011-11-29 11:40:05 -08:00
2011-12-01 15:47:12 -08:00
init : function ( player , options , ready ) {
2011-11-29 11:40:05 -08:00
this . player = player ;
this . el = this . createElement ( ) ;
2011-12-01 15:47:12 -08:00
this . ready ( ready ) ;
2012-01-05 23:25:09 -08:00
this . addEvent ( "click" , this . proxy ( this . onClick ) ) ;
2011-11-29 11:40:05 -08:00
var source = options . source ;
2011-12-01 15:47:12 -08:00
// 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 ) {
2011-11-29 11:40:05 -08:00
player . triggerEvent ( "loadstart" ) ;
2011-12-01 15:47:12 -08:00
// Otherwise set the source if one was provided.
} else if ( source ) {
this . el . src = source . src ;
2011-11-29 11:40:05 -08:00
}
2011-12-01 15:47:12 -08:00
// 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 ( ) {
2011-11-29 11:40:05 -08:00
if ( this . options . autoplay && this . paused ( ) ) {
2011-12-01 15:47:12 -08:00
this . tag . poster = null ; // Chrome Fix. Fixed in Chrome v16.
2011-11-29 11:40:05 -08:00
this . play ( ) ;
}
} ) ;
2012-01-02 13:02:04 -08:00
this . setupTriggers ( ) ;
2011-12-01 15:47:12 -08:00
this . triggerReady ( ) ;
2011-11-29 11:40:05 -08:00
} ,
2012-01-20 17:34:18 -08:00
2012-01-02 13:02:04 -08:00
destroy : function ( ) {
this . player . tag = false ;
2012-01-05 23:25:09 -08:00
this . removeTriggers ( ) ;
2012-01-02 13:02:04 -08:00
this . el . parentNode . removeChild ( this . el ) ;
} ,
2011-11-29 11:40:05 -08:00
createElement : function ( ) {
2011-12-07 21:03:12 -08:00
var html5 = _V _ . html5 ,
2011-11-30 13:06:32 -08:00
player = this . player ,
2011-11-29 11:40:05 -08:00
2012-01-02 13:02:04 -08:00
// If possible, reuse original tag for HTML5 playback technology element
2011-11-30 13:06:32 -08:00
el = player . tag ,
newEl ;
2011-11-29 11:40:05 -08:00
// 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.
2012-01-05 23:25:09 -08:00
if ( ! el || this . support . movingElementInDOM === false ) {
2012-01-02 13:02:04 -08:00
// If the original tag is still there, remove it.
2012-01-20 17:34:18 -08:00
if ( el ) {
2012-01-02 13:02:04 -08:00
player . el . removeChild ( el ) ;
}
2011-11-30 13:06:32 -08:00
newEl = _V _ . createElement ( "video" , {
2012-01-02 13:02:04 -08:00
id : el . id || player . el . id + "_html5_api" ,
className : el . className || "vjs-tech"
2011-11-29 11:40:05 -08:00
} ) ;
el = newEl ;
2011-12-01 15:47:12 -08:00
_V _ . insertFirst ( el , player . el ) ;
2011-11-29 11:40:05 -08:00
}
// Update tag settings, in case they were overridden
2012-01-02 16:57:17 -08:00
_V _ . each ( [ "autoplay" , "preload" , "loop" , "muted" ] , function ( attr ) { // ,"poster"
2011-11-30 13:06:32 -08:00
el [ attr ] = player . options [ attr ] ;
2011-11-29 11:40:05 -08:00
} , this ) ;
return el ;
} ,
2012-01-05 23:25:09 -08:00
// Make video events trigger player events
// May seem verbose here, but makes other APIs possible.
2011-11-29 11:40:05 -08:00
setupTriggers : function ( ) {
2012-01-05 23:25:09 -08:00
_V _ . each . call ( this , _V _ . html5 . events , function ( type ) {
_V _ . addEvent ( this . el , type , _V _ . proxy ( this . player , this . eventHandler ) ) ;
} ) ;
} ,
removeTriggers : function ( ) {
_V _ . each . call ( this , _V _ . html5 . events , function ( type ) {
_V _ . removeEvent ( this . el , type , _V _ . proxy ( this . player , this . eventHandler ) ) ;
} ) ;
} ,
eventHandler : function ( e ) {
e . stopPropagation ( ) ;
this . triggerEvent ( e ) ;
2011-11-29 11:40:05 -08:00
} ,
play : function ( ) { this . el . play ( ) ; } ,
pause : function ( ) { this . el . pause ( ) ; } ,
paused : function ( ) { return this . el . paused ; } ,
currentTime : function ( ) { return this . el . currentTime ; } ,
setCurrentTime : function ( seconds ) {
2011-12-05 11:28:18 -08:00
try {
this . el . currentTime = seconds ;
} catch ( e ) {
_V _ . log ( e , "Video isn't ready. (VideoJS)" ) ;
2011-11-29 11:40:05 -08:00
// this.warning(VideoJS.warnings.videoNotReady);
}
} ,
duration : function ( ) { return this . el . duration || 0 ; } ,
buffered : function ( ) { return this . el . buffered ; } ,
volume : function ( ) { return this . el . volume ; } ,
setVolume : function ( percentAsDecimal ) { this . el . volume = percentAsDecimal ; } ,
muted : function ( ) { return this . el . muted ; } ,
setMuted : function ( muted ) { this . el . muted = muted } ,
width : function ( ) { return this . el . offsetWidth ; } ,
height : function ( ) { return this . el . offsetHeight ; } ,
supportsFullScreen : function ( ) {
2011-12-01 16:29:52 -08:00
if ( typeof this . el . webkitEnterFullScreen == 'function' ) {
2011-12-07 22:02:40 -08:00
2011-11-29 11:40:05 -08:00
// Seems to be broken in Chromium/Chrome && Safari in Leopard
if ( ! navigator . userAgent . match ( "Chrome" ) && ! navigator . userAgent . match ( "Mac OS X 10.5" ) ) {
return true ;
}
2011-12-07 22:02:40 -08:00
}
2012-01-05 23:25:09 -08:00
return false ;
2011-11-29 11:40:05 -08:00
} ,
2012-01-05 23:25:09 -08:00
2011-11-29 11:40:05 -08:00
enterFullScreen : function ( ) {
2011-12-01 15:24:34 -08:00
try {
this . el . webkitEnterFullScreen ( ) ;
} catch ( e ) {
if ( e . code == 11 ) {
// this.warning(VideoJS.warnings.videoNotReady);
_V _ . log ( "VideoJS: Video not ready." )
}
2011-11-29 11:40:05 -08:00
}
} ,
src : function ( src ) { this . el . src = src ; } ,
load : function ( ) { this . el . load ( ) ; } ,
currentSrc : function ( ) { return this . el . currentSrc ; } ,
preload : function ( ) { return this . el . preload ; } ,
setPreload : function ( val ) { this . el . preload = val ; } ,
autoplay : function ( ) { return this . el . autoplay ; } ,
setAutoplay : function ( val ) { this . el . autoplay = val ; } ,
loop : function ( ) { return this . el . loop ; } ,
setLoop : function ( val ) { this . el . loop = val ; } ,
error : function ( ) { return this . el . error ; } ,
2012-01-20 17:42:38 -08:00
// networkState: function(){ return this.el.networkState; },
// readyState: function(){ return this.el.readyState; },
2011-11-29 11:40:05 -08:00
seeking : function ( ) { return this . el . seeking ; } ,
2012-01-20 17:42:38 -08:00
// initialTime: function(){ return this.el.initialTime; },
// startOffsetTime: function(){ return this.el.startOffsetTime; },
// played: function(){ return this.el.played; },
// seekable: function(){ return this.el.seekable; },
2011-11-29 11:40:05 -08:00
ended : function ( ) { return this . el . ended ; } ,
2012-01-20 17:42:38 -08:00
// videoTracks: function(){ return this.el.videoTracks; },
// audioTracks: function(){ return this.el.audioTracks; },
// videoWidth: function(){ return this.el.videoWidth; },
// videoHeight: function(){ return this.el.videoHeight; },
// textTracks: function(){ return this.el.textTracks; },
// defaultPlaybackRate: function(){ return this.el.defaultPlaybackRate; },
// playbackRate: function(){ return this.el.playbackRate; },
// mediaGroup: function(){ return this.el.mediaGroup; },
// controller: function(){ return this.el.controller; },
2011-11-29 11:40:05 -08:00
controls : function ( ) { return this . player . options . controls ; } ,
defaultMuted : function ( ) { return this . el . defaultMuted ; }
} ) ;
/* HTML5 Support Testing -------------------------------------------------------- */
2011-12-07 21:03:12 -08:00
_V _ . html5 . isSupported = function ( ) {
2011-11-29 11:40:05 -08:00
return ! ! document . createElement ( "video" ) . canPlayType ;
} ;
2011-12-07 21:03:12 -08:00
_V _ . html5 . canPlaySource = function ( srcObj ) {
2011-12-01 15:47:12 -08:00
return ! ! document . createElement ( "video" ) . canPlayType ( srcObj . type ) ;
2011-11-29 11:40:05 -08:00
// TODO: Check Type
// If no Type, check ext
// Check Media Type
} ;
// List of all HTML5 events (various uses).
2011-12-07 21:03:12 -08:00
_V _ . html5 . events = "loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange" . split ( "," ) ;
2011-11-29 11:40:05 -08:00
/* HTML5 Device Fixes ---------------------------------------------------------- */
2012-01-05 23:25:09 -08:00
_V _ . html5 . prototype . support = {
2012-01-20 17:34:18 -08:00
2012-01-05 23:25:09 -08:00
// Support for tech specific full screen. (webkitEnterFullScreen, not requestFullscreen)
// http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html
// Seems to be broken in Chromium/Chrome && Safari in Leopard
fullscreen : ( typeof _V _ . testVid . webkitEnterFullScreen !== undefined ) ? ( ! _V _ . ua . match ( "Chrome" ) && ! _V _ . ua . match ( "Mac OS X 10.5" ) ? true : false ) : false ,
// In iOS, if you move a video element in the DOM, it breaks video playback.
movingElementInDOM : ! _V _ . isIOS ( )
} ;
2011-11-29 11:40:05 -08:00
// Android
if ( _V _ . isAndroid ( ) ) {
// Override Android 2.2 and less canPlayType method which is broken
if ( _V _ . androidVersion ( ) < 3 ) {
document . createElement ( "video" ) . constructor . prototype . canPlayType = function ( type ) {
return ( type && type . toLowerCase ( ) . indexOf ( "video/mp4" ) != - 1 ) ? "maybe" : "" ;
} ;
}
}
2011-12-07 21:03:12 -08:00
/ * V i d e o J S - S W F - C u s t o m F l a s h P l a y e r w i t h H T M L 5 - i s h A P I
2011-11-29 11:40:05 -08:00
=== === === === === === === === === === === === === === === === === === === === === === === === === === == * /
2011-12-07 21:03:12 -08:00
_V _ . flash = _V _ . PlaybackTech . extend ( {
2011-11-29 11:40:05 -08:00
init : function ( player , options ) {
this . player = player ;
2012-01-02 13:02:04 -08:00
var source = options . source ,
parentEl = options . parentEl ,
placeHolder = this . el = _V _ . createElement ( "div" , { id : parentEl . id + "_temp_flash" } ) ,
2011-12-07 21:03:12 -08:00
objId = player . el . id + "_flash_api" ,
2011-11-30 13:06:32 -08:00
playerOptions = player . options ;
2011-11-29 11:40:05 -08:00
2011-12-07 21:29:21 -08:00
flashVars = _V _ . merge ( {
// SWF Callback Functions
2012-01-20 17:42:38 -08:00
readyFunction : "_V_.flash.onReady" ,
eventProxyFunction : "_V_.flash.onEvent" ,
errorEventProxyFunction : "_V_.flash.onError" ,
2011-12-07 21:29:21 -08:00
// Player Settings
2011-11-30 13:06:32 -08:00
autoplay : playerOptions . autoplay ,
preload : playerOptions . preload ,
loop : playerOptions . loop ,
2011-12-01 15:47:12 -08:00
muted : playerOptions . muted
2011-12-07 21:29:21 -08:00
} , options . flashVars ) ,
2011-11-29 11:40:05 -08:00
2011-12-07 22:02:40 -08:00
params = _V _ . merge ( {
2011-11-29 11:40:05 -08:00
allowScriptAccess : "always" ,
wmode : "opaque" ,
bgcolor : "#000000"
2011-12-07 22:02:40 -08:00
} , options . params ) ,
2011-11-29 11:40:05 -08:00
2011-12-07 22:02:40 -08:00
attributes = _V _ . merge ( {
2011-11-29 11:40:05 -08:00
id : objId ,
name : objId ,
'class' : 'vjs-tech'
2011-12-07 22:02:40 -08:00
} , options . attributes ) ;
2011-11-29 11:40:05 -08:00
2011-11-30 13:06:32 -08:00
// If source was supplied pass as a flash var.
if ( source ) {
2012-01-18 23:24:02 +09:00
flashVars . src = encodeURIComponent ( source . src ) ;
2011-11-30 13:06:32 -08:00
}
2011-12-07 22:02:40 -08:00
// Add to box.
2012-01-02 13:02:04 -08:00
_V _ . insertFirst ( placeHolder , parentEl ) ;
2011-11-29 11:40:05 -08:00
2012-01-05 23:25:09 -08:00
if ( options . startTime ) {
this . ready ( function ( ) {
this . load ( ) ;
this . play ( ) ;
this . currentTime ( options . startTime ) ;
} ) ;
}
2012-01-20 17:34:18 -08:00
// Flash iFrame Mode
// In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.
// - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)
// - Webkit when hiding the plugin
// - Webkit and Firefox when using requestFullScreen on a parent element
// Loading the flash plugin into a dynamically generated iFrame gets around most of these issues.
// Issues that remain include hiding the element and requestFullScreen in Firefox specifically
// There's on particularly annoying issue with this method which is that Firefox throws a security error on an offsite Flash object loaded into a dynamically created iFrame.
// Even though the iframe was inserted into a page on the web, Firefox + Flash considers it a local app trying to access an internet file.
// I tried mulitple ways of setting the iframe src attribute but couldn't find a src that worked well. Tried a real/fake source, in/out of domain.
// Also tried a method from stackoverflow that caused a security error in all browsers. http://stackoverflow.com/questions/2486901/how-to-set-document-domain-for-a-dynamically-generated-iframe
// In the end the solution I found to work was setting the iframe window.location.href right before doing a document.write of the Flash object.
// The only downside of this it seems to trigger another http request to the original page (no matter what's put in the href). Not sure why that is.
2012-01-23 14:55:06 -08:00
if ( ! options . iFrameMode ) {
2012-01-20 17:34:18 -08:00
// Create iFrame with vjs-tech class so it's 100% width/height
var iFrm = _V _ . createElement ( "iframe" , {
id : objId + "_iframe" ,
className : "vjs-tech" ,
scrolling : "no" ,
marginWidth : 0 ,
marginHeight : 0 ,
frameBorder : 0
} ) ;
// Wait until iFrame has loaded to write into it.
_V _ . addEvent ( iFrm , "load" , _V _ . proxy ( this , function ( ) {
var iDoc , objTag , swfLoc ,
iWin = iFrm . contentWindow ,
varString = "" ;
// Setting the window href gets around a security error that Firefox throws when it thinks a local page is attempting to load a remote script.
// Firefox seems to be telling Flash (incorrectly) that iframe is local
// Need to find a better method than UA parsing
if ( _V _ . ua . match ( "Firefox" ) ) {
iWin . location . href = "" ;
}
// Get the iFrame's document
iDoc = iFrm . contentDocument ? iFrm . contentDocument : iFrm . contentWindow . document ;
// Build the Flash object tag
// Using bgcolor prevents a white flash when the object is loading
swfLoc = 'http://vjs.zencdn.net/c/video-js.swf' ;
flashVars . readyFunction = "ready" ;
flashVars . eventProxyFunction = "events" ;
flashVars . errorEventProxyFunction = "errors" ;
2012-01-23 14:55:06 -08:00
// Set styls on obj. iFrame won't have video-js.css in scope
attributes . style = "width: 100%; height: 100%;"
2012-01-20 17:34:18 -08:00
// Using document.write because other methods like append and innerHTML were causing the same security errors in Firefox
2012-01-23 14:55:06 -08:00
iDoc . write ( _V _ . flash . getEmbedCode ( swfLoc , flashVars , params , attributes ) ) ;
2012-01-20 17:34:18 -08:00
// Setting variables on the window need to come after the doc write because otherwise they can get reset in some browsers
// So far no issues with swf ready event being called before it's set on the window.
iWin . player = this . player ;
iWin . ready = _V _ . proxy ( this . player , function ( currSwf ) {
var el = iDoc . getElementById ( currSwf ) ,
player = this ,
tech = player . tech ;
// Reference player on tech element
el . player = player ;
// Update reference to playback technology element
tech . el = el ;
// Now that the element is ready, make a click on the swf play the video
tech . addEvent ( "click" , tech . onClick ) ;
el . vjs _setProperty ( "volume" , 0 ) ;
_V _ . flash . checkReady ( tech ) ;
} ) ;
iWin . events = _V _ . proxy ( this . player , function ( swfID , eventName , other ) {
try {
var player = this ;
if ( player && player . techName == "flash" ) {
player . triggerEvent ( eventName ) ;
}
} catch ( err ) {
_V _ . log ( err ) ;
}
} ) ;
iWin . errors = _V _ . proxy ( this . player , function ( swfID , eventName ) {
_V _ . log ( "Flash Error" , eventName ) ;
} ) ;
} ) ) ;
placeHolder . parentNode . replaceChild ( iFrm , placeHolder ) ;
} else {
2012-01-23 14:55:06 -08:00
// swfobject.embedSWF(options.swf, placeHolder.id, "480", "270", "9", "", flashVars, params, attributes);
_V _ . flash . embed ( options . swf , placeHolder , flashVars , params , attributes ) ;
2012-01-20 17:34:18 -08:00
}
2011-11-29 11:40:05 -08:00
} ,
2012-01-20 17:34:18 -08:00
2012-01-02 13:02:04 -08:00
destroy : function ( ) {
this . el . parentNode . removeChild ( this . el ) ;
2011-11-29 11:40:05 -08:00
} ,
2012-01-20 17:42:38 -08:00
// setupTriggers: function(){}, // Using global onEvent func to distribute events
2012-01-02 13:02:04 -08:00
2011-11-29 11:40:05 -08:00
play : function ( ) { this . el . vjs _play ( ) ; } ,
pause : function ( ) { this . el . vjs _pause ( ) ; } ,
2011-12-07 22:02:40 -08:00
src : function ( src ) {
2011-12-01 15:47:12 -08:00
this . el . vjs _src ( src ) ;
// Currently the SWF doesn't autoplay if you load a source later.
// e.g. Load player w/ no source, wait 2s, set src.
if ( this . player . autoplay ) {
2011-12-01 16:48:06 -08:00
var tech = this ;
setTimeout ( function ( ) { tech . play ( ) ; } , 0 ) ;
2011-12-01 15:47:12 -08:00
}
} ,
2011-11-30 14:05:28 -08:00
load : function ( ) { this . el . vjs _load ( ) ; } ,
2011-11-29 11:40:05 -08:00
poster : function ( ) { this . el . vjs _getProperty ( "poster" ) ; } ,
buffered : function ( ) {
2012-01-09 12:18:08 -08:00
return _V _ . createTimeRange ( 0 , this . el . vjs _getProperty ( "buffered" ) ) ;
2011-11-29 11:40:05 -08:00
} ,
supportsFullScreen : function ( ) {
return false ; // Flash does not allow fullscreen through javascript
} ,
2011-12-07 22:02:40 -08:00
enterFullScreen : function ( ) {
return false ;
2011-11-29 11:40:05 -08:00
}
} ) ;
// Create setters and getters for attributes
( function ( ) {
2011-12-07 21:03:12 -08:00
var api = _V _ . flash . prototype ,
2011-11-30 13:06:32 -08:00
readWrite = "preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted" . split ( "," ) ,
2011-11-29 11:40:05 -08:00
readOnly = "error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks" . split ( "," ) ,
callOnly = "load,play,pause" . split ( "," ) ;
// Overridden: buffered
createSetter = function ( attr ) {
var attrUpper = attr . charAt ( 0 ) . toUpperCase ( ) + attr . slice ( 1 ) ;
api [ "set" + attrUpper ] = function ( val ) { return this . el . vjs _setProperty ( attr , val ) ; } ;
} ,
createGetter = function ( attr ) {
api [ attr ] = function ( ) { return this . el . vjs _getProperty ( attr ) ; } ;
} ;
// Create getter and setters for all read/write attributes
_V _ . each ( readWrite , function ( attr ) {
createGetter ( attr ) ;
createSetter ( attr ) ;
} ) ;
// Create getters for read-only attributes
_V _ . each ( readOnly , function ( attr ) {
createGetter ( attr ) ;
} ) ;
} ) ( ) ;
/* Flash Support Testing -------------------------------------------------------- */
2011-12-07 21:03:12 -08:00
_V _ . flash . isSupported = function ( ) {
2012-01-05 23:25:09 -08:00
return swfobject . hasFlashPlayerVersion ( "10" ) ;
2011-11-29 11:40:05 -08:00
} ;
2011-12-07 21:03:12 -08:00
_V _ . flash . canPlaySource = function ( srcObj ) {
2012-01-05 23:25:09 -08:00
if ( srcObj . type in _V _ . flash . prototype . support . formats ) { return "maybe" ; }
2011-11-29 11:40:05 -08:00
} ;
2012-01-05 23:25:09 -08:00
_V _ . flash . prototype . support = {
formats : {
2011-11-29 11:40:05 -08:00
"video/flv" : "FLV" ,
"video/x-flv" : "FLV" ,
"video/mp4" : "MP4" ,
"video/m4v" : "MP4"
} ,
// Optional events that we can manually mimic with timers
2012-01-05 23:25:09 -08:00
progressEvent : false ,
timeupdateEvent : false ,
2012-01-20 17:34:18 -08:00
// Resizing plugins using request fullscreen reloads the plugin
2012-01-05 23:25:09 -08:00
fullscreenResize : false ,
// Resizing plugins in Firefox always reloads the plugin (e.g. full window mode)
parentResize : ! ( _V _ . ua . match ( "Firefox" ) )
2011-11-29 11:40:05 -08:00
} ;
2012-01-20 17:42:38 -08:00
_V _ . flash . onReady = function ( currSwf ) {
2011-12-07 22:02:40 -08:00
2011-12-21 17:59:36 -08:00
var el = _V _ . el ( currSwf ) ;
2011-11-29 11:40:05 -08:00
2011-12-21 17:59:36 -08:00
// Get player from box
// On firefox reloads, el might already have a player
var player = el . player || el . parentNode . player ,
2012-01-02 13:02:04 -08:00
tech = player . tech ;
2011-11-29 11:40:05 -08:00
2011-12-21 17:59:36 -08:00
// Reference player on tech element
el . player = player ;
2011-11-29 11:40:05 -08:00
2011-12-21 17:59:36 -08:00
// Update reference to playback technology element
tech . el = el ;
2011-11-29 11:40:05 -08:00
2012-01-05 23:25:09 -08:00
// Now that the element is ready, make a click on the swf play the video
tech . addEvent ( "click" , tech . onClick ) ;
2012-01-02 16:57:17 -08:00
2011-12-21 17:59:36 -08:00
_V _ . flash . checkReady ( tech ) ;
} ;
2011-11-29 11:40:05 -08:00
2011-12-21 17:59:36 -08:00
// The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object.
// If it's not ready, we set a timeout to check again shortly.
_V _ . flash . checkReady = function ( tech ) {
if ( tech . el . vjs _getProperty ) {
tech . triggerReady ( ) ;
} else {
setTimeout ( function ( ) {
_V _ . flash . checkReady ( tech ) ;
} , 50 ) ;
2011-11-29 11:40:05 -08:00
}
} ;
2011-12-07 22:02:40 -08:00
2012-01-20 17:42:38 -08:00
_V _ . flash . onEvent = function ( swfID , eventName , other ) {
2011-11-29 11:40:05 -08:00
try {
var player = _V _ . el ( swfID ) . player ;
2012-01-05 23:25:09 -08:00
if ( player && player . techName == "flash" ) {
2011-11-29 11:40:05 -08:00
player . triggerEvent ( eventName ) ;
}
} catch ( err ) {
_V _ . log ( err ) ;
}
} ;
2012-01-20 17:42:38 -08:00
_V _ . flash . onError = function ( swfID , eventName ) {
2011-12-07 21:03:12 -08:00
_V _ . log ( "Flash Error" , eventName ) ;
2011-11-29 11:40:05 -08:00
} ;
2012-01-20 18:20:00 -08:00
// Flash Version Check
_V _ . flash . version = function ( ) {
var version = '0,0,0'
// IE
try {
version = new ActiveXObject ( 'ShockwaveFlash.ShockwaveFlash' ) . GetVariable ( '$version' ) . replace ( /\D+/g , ',' ) . match ( /^,?(.+),?$/ ) [ 1 ] ;
// other browsers
} catch ( e ) {
try {
if ( navigator . mimeTypes [ "application/x-shockwave-flash" ] . enabledPlugin ) {
version = ( navigator . plugins [ "Shockwave Flash 2.0" ] || navigator . plugins [ "Shockwave Flash" ] ) . description . replace ( /\D+/g , "," ) . match ( /^,?(.+),?$/ ) [ 1 ] ;
}
} catch ( e ) { }
}
return version . split ( "," ) ;
2012-01-23 14:55:06 -08:00
}
_V _ . flash . embed = function ( swf , placeHolder , flashVars , params , attributes ) {
var code = _V _ . flash . getEmbedCode ( swf , flashVars , params , attributes )
// Get element by embedding code and retrieving created element
, obj = _V _ . createElement ( "div" , { innerHTML : code } ) . childNodes [ 0 ] ;
// swfobject.embedSWF(swf, placeHolder.id, "480", "270", "9", "", flashVars, params, attributes);
// placeHolder.outerHTML = code;
var par = placeHolder . parentNode ;
placeHolder . parentNode . replaceChild ( obj , placeHolder ) ;
// IE6 seems to have an issue where it won't initialize the swf object after injecting it.
// This is a dumb temporary fix
var newObj = par . childNodes [ 0 ] ;
setTimeout ( function ( ) {
newObj . style . display = "block" ;
} , 1000 ) ;
} ;
_V _ . flash . getEmbedCode = function ( swf , flashVars , params , attributes ) {
var objTag = '<object type="application/x-shockwave-flash"' ,
flashVarsString = '' ,
paramsString = ''
attrsString = '' ;
// Convert flash vars to string
if ( flashVars ) {
_V _ . objEach ( flashVars , function ( key , val ) {
flashVarsString += ( key + "=" + val + "&" ) ;
} ) ;
}
// Add swf, flashVars, and other default params
params = _V _ . merge ( {
movie : swf ,
flashvars : flashVarsString ,
allowScriptAccess : 'always'
} , params ) ;
// Create param tags
_V _ . objEach ( params , function ( key , val ) {
paramsString += '<param name="' + key + '" value="' + val + '" />' ;
} ) ;
// Add swf to attributes (need both for IE and Others to work)
attributes = _V _ . merge ( {
data : swf ,
width : "640" ,
height : "270"
} , attributes ) ;
_V _ . objEach ( attributes , function ( key , val ) {
attrsString += ( key + '="' + val + '" ' ) ;
} ) ;
return objTag + attrsString + '>' + paramsString + '</object>' ;
2012-01-28 17:27:45 -08:00
}