2013-01-10 13:06:12 -08:00
/ * *
* @ fileoverview VideoJS - SWF - Custom Flash Player with HTML5 - ish API
* https : //github.com/zencoder/video-js-swf
* Not using setupTriggers . Using global onEvent func to distribute events
* /
2012-12-31 15:25:56 -08:00
/ * *
2013-10-28 18:25:28 -07:00
* Flash Media Controller - Wrapper for fallback SWF API
*
* @ param { vjs . Player } player
2012-12-31 15:25:56 -08:00
* @ param { Object = } options
* @ param { Function = } ready
* @ constructor
* /
2013-04-09 13:43:35 -07:00
vjs . Flash = vjs . MediaTechController . extend ( {
/** @constructor */
init : function ( player , options , ready ) {
vjs . MediaTechController . call ( this , player , options , ready ) ;
var source = options [ 'source' ] ,
// Which element to embed in
parentEl = options [ 'parentEl' ] ,
// Create a temporary element to be replaced by swf object
placeHolder = this . el _ = vjs . createEl ( 'div' , { id : player . id ( ) + '_temp_flash' } ) ,
// Generate ID for swf object
objId = player . id ( ) + '_flash_api' ,
// Store player options in local var for optimization
// TODO: switch to using player methods instead of options
// e.g. player.autoplay();
playerOptions = player . options _ ,
// Merge default flashvars with ones passed in to init
flashVars = vjs . obj . merge ( {
// SWF Callback Functions
'readyFunction' : 'videojs.Flash.onReady' ,
'eventProxyFunction' : 'videojs.Flash.onEvent' ,
'errorEventProxyFunction' : 'videojs.Flash.onError' ,
// Player Settings
'autoplay' : playerOptions . autoplay ,
'preload' : playerOptions . preload ,
'loop' : playerOptions . loop ,
'muted' : playerOptions . muted
} , options [ 'flashVars' ] ) ,
// Merge default parames with ones passed in
params = vjs . obj . merge ( {
'wmode' : 'opaque' , // Opaque is needed to overlay controls, but can affect playback performance
'bgcolor' : '#000000' // Using bgcolor prevents a white flash when the object is loading
} , options [ 'params' ] ) ,
// Merge default attributes with ones passed in
attributes = vjs . obj . merge ( {
'id' : objId ,
'name' : objId , // Both ID and Name needed or swf to identifty itself
'class' : 'vjs-tech'
2014-07-14 15:46:17 -07:00
} , options [ 'attributes' ] )
2013-04-09 13:43:35 -07:00
;
// If source was supplied pass as a flash var.
if ( source ) {
2013-08-23 15:05:04 -07:00
if ( source . type && vjs . Flash . isStreamingType ( source . type ) ) {
var parts = vjs . Flash . streamToParts ( source . src ) ;
flashVars [ 'rtmpConnection' ] = encodeURIComponent ( parts . connection ) ;
flashVars [ 'rtmpStream' ] = encodeURIComponent ( parts . stream ) ;
}
else {
flashVars [ 'src' ] = encodeURIComponent ( vjs . getAbsoluteURL ( source . src ) ) ;
}
2013-04-09 13:43:35 -07:00
}
// Add placeholder to player div
vjs . insertFirst ( placeHolder , parentEl ) ;
// Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
// This allows resetting the playhead when we catch the reload
if ( options [ 'startTime' ] ) {
this . ready ( function ( ) {
this . load ( ) ;
this . play ( ) ;
this . currentTime ( options [ 'startTime' ] ) ;
2012-12-31 15:25:56 -08:00
} ) ;
2013-04-09 13:43:35 -07:00
}
2013-12-20 14:14:00 -08:00
// firefox doesn't bubble mousemove events to parent. videojs/video-js-swf#37
// bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=836786
if ( vjs . IS _FIREFOX ) {
this . ready ( function ( ) {
vjs . on ( this . el ( ) , 'mousemove' , vjs . bind ( this , function ( ) {
// since it's a custom event, don't bubble higher than the player
this . player ( ) . trigger ( { 'type' : 'mousemove' , 'bubbles' : false } ) ;
} ) ) ;
} ) ;
}
2014-06-13 14:16:03 -07:00
// native click events on the SWF aren't triggered on IE11, Win8.1RT
// use stageclick events triggered from inside the SWF instead
player . on ( 'stageclick' , player . reportUserActivity ) ;
2013-04-09 13:43:35 -07: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.
// NOTE (2012-01-29): Cannot get Firefox to load the remote hosted SWF into a dynamically created iFrame
// Firefox 9 throws a security error, unleess you call location.href right before doc.write.
// Not sure why that even works, but it causes the browser to look like it's continuously trying to load the page.
// Firefox 3.6 keeps calling the iframe onload function anytime I write to it, causing an endless loop.
if ( options [ 'iFrameMode' ] === true && ! vjs . IS _FIREFOX ) {
// Create iFrame with vjs-tech class so it's 100% width/height
var iFrm = vjs . createEl ( 'iframe' , {
'id' : objId + '_iframe' ,
'name' : objId + '_iframe' ,
'className' : 'vjs-tech' ,
'scrolling' : 'no' ,
'marginWidth' : 0 ,
'marginHeight' : 0 ,
'frameBorder' : 0
2012-12-31 15:25:56 -08:00
} ) ;
2013-04-09 13:43:35 -07:00
// Update ready function names in flash vars for iframe window
flashVars [ 'readyFunction' ] = 'ready' ;
flashVars [ 'eventProxyFunction' ] = 'events' ;
flashVars [ 'errorEventProxyFunction' ] = 'errors' ;
// Tried multiple methods to get this to work in all browsers
// Tried embedding the flash object in the page first, and then adding a place holder to the iframe, then replacing the placeholder with the page object.
// The goal here was to try to load the swf URL in the parent page first and hope that got around the firefox security error
// var newObj = vjs.Flash.embed(options['swf'], placeHolder, flashVars, params, attributes);
// (in onload)
// var temp = vjs.createEl('a', { id:'asdf', innerHTML: 'asdf' } );
// iDoc.body.appendChild(temp);
// Tried embedding the flash object through javascript in the iframe source.
// This works in webkit but still triggers the firefox security error
// iFrm.src = 'javascript: document.write('"+vjs.Flash.getEmbedCode(options['swf'], flashVars, params, attributes)+"');";
// Tried an actual local iframe just to make sure that works, but it kills the easiness of the CDN version if you require the user to host an iframe
// We should add an option to host the iframe locally though, because it could help a lot of issues.
// iFrm.src = "iframe.html";
// Wait until iFrame has loaded to write into it.
vjs . on ( iFrm , 'load' , vjs . bind ( this , function ( ) {
var iDoc ,
iWin = iFrm . contentWindow ;
// The one working method I found was to use the iframe's document.write() to create the swf object
// This got around the security issue in all browsers except firefox.
// I did find a hack where if I call the iframe's window.location.href='', it would get around the security error
// However, the main page would look like it was loading indefinitely (URL bar loading spinner would never stop)
// Plus Firefox 3.6 didn't work no matter what I tried.
// if (vjs.USER_AGENT.match('Firefox')) {
// iWin.location.href = '';
// }
// Get the iFrame's document depending on what the browser supports
iDoc = iFrm . contentDocument ? iFrm . contentDocument : iFrm . contentWindow . document ;
// Tried ensuring both document domains were the same, but they already were, so that wasn't the issue.
// Even tried adding /. that was mentioned in a browser security writeup
// document.domain = document.domain+'/.';
// iDoc.domain = document.domain+'/.';
// Tried adding the object to the iframe doc's innerHTML. Security error in all browsers.
// iDoc.body.innerHTML = swfObjectHTML;
// Tried appending the object to the iframe doc's body. Security error in all browsers.
// iDoc.body.appendChild(swfObject);
// Using document.write actually got around the security error that browsers were throwing.
// Again, it's a dynamically generated (same domain) iframe, loading an external Flash swf.
// Not sure why that's a security issue, but apparently it is.
iDoc . write ( vjs . Flash . getEmbedCode ( options [ 'swf' ] , flashVars , params , attributes ) ) ;
// Setting variables on the window needs 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 _ ;
// Create swf ready function for iFrame window
iWin [ 'ready' ] = vjs . bind ( this . player _ , function ( currSwf ) {
var el = iDoc . getElementById ( currSwf ) ,
player = this ,
tech = player . tech ;
// Update reference to playback technology element
tech . el _ = el ;
// Make sure swf is actually ready. Sometimes the API isn't actually yet.
vjs . Flash . checkReady ( tech ) ;
} ) ;
// Create event listener for all swf events
iWin [ 'events' ] = vjs . bind ( this . player _ , function ( swfID , eventName ) {
var player = this ;
if ( player && player . techName === 'flash' ) {
player . trigger ( eventName ) ;
}
} ) ;
// Create error listener for all swf errors
iWin [ 'errors' ] = vjs . bind ( this . player _ , function ( swfID , eventName ) {
vjs . log ( 'Flash Error' , eventName ) ;
} ) ;
} ) ) ;
// Replace placeholder with iFrame (it will load now)
placeHolder . parentNode . replaceChild ( iFrm , placeHolder ) ;
// If not using iFrame mode, embed as normal object
} else {
vjs . Flash . embed ( options [ 'swf' ] , placeHolder , flashVars , params , attributes ) ;
}
2012-12-31 15:25:56 -08:00
}
2013-04-09 13:43:35 -07:00
} ) ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . dispose = function ( ) {
2013-04-09 13:43:35 -07:00
vjs . MediaTechController . prototype . dispose . call ( this ) ;
2013-01-04 16:58:23 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . play = function ( ) {
this . el _ . vjs _play ( ) ;
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . pause = function ( ) {
this . el _ . vjs _pause ( ) ;
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . src = function ( src ) {
2014-02-27 17:34:01 -08:00
if ( src === undefined ) {
return this . currentSrc ( ) ;
}
2013-08-23 15:05:04 -07:00
if ( vjs . Flash . isStreamingSrc ( src ) ) {
src = vjs . Flash . streamToParts ( src ) ;
this . setRtmpConnection ( src . connection ) ;
this . setRtmpStream ( src . stream ) ;
2014-02-27 17:34:01 -08:00
} else {
2013-08-23 15:05:04 -07:00
// Make sure source URL is abosolute.
src = vjs . getAbsoluteURL ( src ) ;
this . el _ . vjs _src ( src ) ;
}
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
// Currently the SWF doesn't autoplay if you load a source later.
// e.g. Load player w/ no source, wait 2s, set src.
2013-01-16 20:24:38 -05:00
if ( this . player _ . autoplay ( ) ) {
2013-01-04 16:58:23 -08:00
var tech = this ;
setTimeout ( function ( ) { tech . play ( ) ; } , 0 ) ;
}
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2014-07-14 15:46:17 -07:00
vjs . Flash . prototype . setCurrentTime = function ( time ) {
this . lastSeekTarget _ = time ;
this . el _ . vjs _setProperty ( 'currentTime' , time ) ;
} ;
vjs . Flash . prototype . currentTime = function ( time ) {
// when seeking make the reported time keep up with the requested time
// by reading the time we're seeking to
if ( this . seeking ( ) ) {
return this . lastSeekTarget _ || 0 ;
}
return this . el _ . vjs _getProperty ( 'currentTime' ) ;
} ;
2013-08-23 15:05:04 -07:00
vjs . Flash . prototype . currentSrc = function ( ) {
var src = this . el _ . vjs _getProperty ( 'currentSrc' ) ;
// no src, check and see if RTMP
if ( src == null ) {
2014-03-26 19:45:42 -04:00
var connection = this [ 'rtmpConnection' ] ( ) ,
stream = this [ 'rtmpStream' ] ( ) ;
2013-08-23 15:05:04 -07:00
if ( connection && stream ) {
src = vjs . Flash . streamFromParts ( connection , stream ) ;
}
}
return src ;
} ;
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . load = function ( ) {
this . el _ . vjs _load ( ) ;
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . poster = function ( ) {
2013-01-10 13:06:12 -08:00
this . el _ . vjs _getProperty ( 'poster' ) ;
} ;
2013-08-24 19:34:26 -04:00
vjs . Flash . prototype . setPoster = function ( ) {
// poster images are not handled by the Flash tech so make this a no-op
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . buffered = function ( ) {
2013-01-10 13:06:12 -08:00
return vjs . createTimeRange ( 0 , this . el _ . vjs _getProperty ( 'buffered' ) ) ;
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . supportsFullScreen = function ( ) {
return false ; // Flash does not allow fullscreen through javascript
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . prototype . enterFullScreen = function ( ) {
return false ;
2013-01-10 13:06:12 -08:00
} ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
// Create setters and getters for attributes
var api = vjs . Flash . prototype ,
2014-01-23 18:13:22 -05:00
readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted' . split ( ',' ) ,
2014-02-27 17:34:01 -08:00
readOnly = 'error,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks' . split ( ',' ) ;
2014-03-04 11:24:10 -08:00
// Overridden: buffered, currentTime, currentSrc
2013-01-04 16:58:23 -08:00
2013-01-10 13:06:12 -08:00
/ * *
* @ this { * }
2013-10-28 18:25:28 -07:00
* @ private
2013-01-10 13:06:12 -08:00
* /
var createSetter = function ( attr ) {
var attrUpper = attr . charAt ( 0 ) . toUpperCase ( ) + attr . slice ( 1 ) ;
api [ 'set' + attrUpper ] = function ( val ) { return this . el _ . vjs _setProperty ( attr , val ) ; } ;
} ;
/ * *
* @ this { * }
2013-10-28 18:25:28 -07:00
* @ private
2013-01-10 13:06:12 -08:00
* /
var createGetter = function ( attr ) {
api [ attr ] = function ( ) { return this . el _ . vjs _getProperty ( attr ) ; } ;
} ;
2012-12-31 15:25:56 -08:00
2013-01-25 17:36:40 -08:00
( function ( ) {
var i ;
// Create getter and setters for all read/write attributes
for ( i = 0 ; i < readWrite . length ; i ++ ) {
createGetter ( readWrite [ i ] ) ;
createSetter ( readWrite [ i ] ) ;
}
2012-12-31 15:25:56 -08:00
2013-01-25 17:36:40 -08:00
// Create getters for read-only attributes
for ( i = 0 ; i < readOnly . length ; i ++ ) {
createGetter ( readOnly [ i ] ) ;
}
} ) ( ) ;
2012-12-31 15:25:56 -08:00
/* Flash Support Testing -------------------------------------------------------- */
2013-01-04 16:58:23 -08:00
vjs . Flash . isSupported = function ( ) {
return vjs . Flash . version ( ) [ 0 ] >= 10 ;
2013-01-10 13:06:12 -08:00
// return swfobject.hasFlashPlayerVersion('10');
2012-12-31 15:25:56 -08:00
} ;
2013-01-04 16:58:23 -08:00
vjs . Flash . canPlaySource = function ( srcObj ) {
2013-10-29 11:00:54 -07:00
var type ;
if ( ! srcObj . type ) {
return '' ;
}
type = srcObj . type . replace ( /;.*/ , '' ) . toLowerCase ( ) ;
if ( type in vjs . Flash . formats || type in vjs . Flash . streamingFormats ) {
return 'maybe' ;
}
2012-12-31 15:25:56 -08:00
} ;
2013-04-09 13:18:55 -07:00
vjs . Flash . formats = {
'video/flv' : 'FLV' ,
'video/x-flv' : 'FLV' ,
'video/mp4' : 'MP4' ,
'video/m4v' : 'MP4'
2012-12-31 15:25:56 -08:00
} ;
2013-08-23 15:05:04 -07:00
vjs . Flash . streamingFormats = {
'rtmp/mp4' : 'MP4' ,
'rtmp/flv' : 'FLV'
} ;
2013-01-04 16:58:23 -08:00
vjs . Flash [ 'onReady' ] = function ( currSwf ) {
var el = vjs . el ( currSwf ) ;
2012-12-31 15:25:56 -08:00
// Get player from box
// On firefox reloads, el might already have a player
2013-01-16 20:24:38 -05:00
var player = el [ 'player' ] || el . parentNode [ 'player' ] ,
2012-12-31 15:25:56 -08:00
tech = player . tech ;
// Reference player on tech element
2013-01-16 20:24:38 -05:00
el [ 'player' ] = player ;
2012-12-31 15:25:56 -08:00
// Update reference to playback technology element
2013-01-04 16:58:23 -08:00
tech . el _ = el ;
2012-12-31 15:25:56 -08:00
2013-01-04 16:58:23 -08:00
vjs . Flash . checkReady ( tech ) ;
2012-12-31 15:25:56 -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.
2013-01-04 16:58:23 -08:00
vjs . Flash . checkReady = function ( tech ) {
2012-12-31 15:25:56 -08:00
// Check if API property exists
2013-01-10 13:06:12 -08:00
if ( tech . el ( ) . vjs _getProperty ) {
2012-12-31 15:25:56 -08:00
// If so, tell tech it's ready
tech . triggerReady ( ) ;
// Otherwise wait longer.
} else {
setTimeout ( function ( ) {
2013-01-04 16:58:23 -08:00
vjs . Flash . checkReady ( tech ) ;
2012-12-31 15:25:56 -08:00
} , 50 ) ;
}
} ;
// Trigger events from the swf on the player
2013-01-04 16:58:23 -08:00
vjs . Flash [ 'onEvent' ] = function ( swfID , eventName ) {
2013-01-16 20:24:38 -05:00
var player = vjs . el ( swfID ) [ 'player' ] ;
2013-01-04 16:58:23 -08:00
player . trigger ( eventName ) ;
2012-12-31 15:25:56 -08:00
} ;
// Log errors from the swf
2013-01-04 16:58:23 -08:00
vjs . Flash [ 'onError' ] = function ( swfID , err ) {
2013-01-16 20:24:38 -05:00
var player = vjs . el ( swfID ) [ 'player' ] ;
2014-05-12 17:08:48 -07:00
var msg = 'FLASH: ' + err ;
if ( err == 'srcnotfound' ) {
player . error ( { code : 4 , message : msg } ) ;
// errors we haven't categorized into the media errors
} else {
player . error ( msg ) ;
}
2012-12-31 15:25:56 -08:00
} ;
// Flash Version Check
2013-01-04 16:58:23 -08:00
vjs . Flash . version = function ( ) {
2012-12-31 15:25:56 -08:00
var version = '0,0,0' ;
// IE
try {
2013-01-10 13:06:12 -08:00
version = new window . ActiveXObject ( 'ShockwaveFlash.ShockwaveFlash' ) . GetVariable ( '$version' ) . replace ( /\D+/g , ',' ) . match ( /^,?(.+),?$/ ) [ 1 ] ;
2012-12-31 15:25:56 -08:00
// other browsers
} catch ( e ) {
try {
2013-01-10 13:06:12 -08:00
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 ] ;
2012-12-31 15:25:56 -08:00
}
2013-01-10 13:06:12 -08:00
} catch ( err ) { }
2012-12-31 15:25:56 -08:00
}
2013-01-10 13:06:12 -08:00
return version . split ( ',' ) ;
2012-12-31 15:25:56 -08:00
} ;
// Flash embedding method. Only used in non-iframe mode
2013-01-04 16:58:23 -08:00
vjs . Flash . embed = function ( swf , placeHolder , flashVars , params , attributes ) {
var code = vjs . Flash . getEmbedCode ( swf , flashVars , params , attributes ) ,
2012-12-31 15:25:56 -08:00
// Get element by embedding code and retrieving created element
2013-01-10 13:06:12 -08:00
obj = vjs . createEl ( 'div' , { innerHTML : code } ) . childNodes [ 0 ] ,
2012-12-31 15:25:56 -08:00
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.
2013-01-10 13:06:12 -08:00
// This is a dumb fix
var newObj = par . childNodes [ 0 ] ;
setTimeout ( function ( ) {
newObj . style . display = 'block' ;
} , 1000 ) ;
2012-12-31 15:25:56 -08:00
return obj ;
} ;
2013-01-04 16:58:23 -08:00
vjs . Flash . getEmbedCode = function ( swf , flashVars , params , attributes ) {
2012-12-31 15:25:56 -08:00
var objTag = '<object type="application/x-shockwave-flash"' ,
flashVarsString = '' ,
paramsString = '' ,
attrsString = '' ;
// Convert flash vars to string
if ( flashVars ) {
2013-01-25 17:36:40 -08:00
vjs . obj . each ( flashVars , function ( key , val ) {
2013-01-10 13:06:12 -08:00
flashVarsString += ( key + '=' + val + '&' ) ;
2012-12-31 15:25:56 -08:00
} ) ;
}
// Add swf, flashVars, and other default params
2013-01-25 17:36:40 -08:00
params = vjs . obj . merge ( {
2013-01-04 16:58:23 -08:00
'movie' : swf ,
'flashvars' : flashVarsString ,
2013-01-10 13:06:12 -08:00
'allowScriptAccess' : 'always' , // Required to talk to swf
'allowNetworking' : 'all' // All should be default, but having security issues.
2012-12-31 15:25:56 -08:00
} , params ) ;
// Create param tags string
2013-01-25 17:36:40 -08:00
vjs . obj . each ( params , function ( key , val ) {
2012-12-31 15:25:56 -08:00
paramsString += '<param name="' + key + '" value="' + val + '" />' ;
} ) ;
2013-01-25 17:36:40 -08:00
attributes = vjs . obj . merge ( {
2012-12-31 15:25:56 -08:00
// Add swf to attributes (need both for IE and Others to work)
2013-01-04 16:58:23 -08:00
'data' : swf ,
2012-12-31 15:25:56 -08:00
// Default to 100% width/height
2013-01-10 13:06:12 -08:00
'width' : '100%' ,
'height' : '100%'
2012-12-31 15:25:56 -08:00
} , attributes ) ;
// Create Attributes string
2013-01-25 17:36:40 -08:00
vjs . obj . each ( attributes , function ( key , val ) {
2012-12-31 15:25:56 -08:00
attrsString += ( key + '="' + val + '" ' ) ;
} ) ;
return objTag + attrsString + '>' + paramsString + '</object>' ;
} ;
2013-08-23 15:05:04 -07:00
vjs . Flash . streamFromParts = function ( connection , stream ) {
return connection + '&' + stream ;
} ;
vjs . Flash . streamToParts = function ( src ) {
var parts = {
connection : '' ,
stream : ''
} ;
if ( ! src ) {
return parts ;
}
// Look for the normal URL separator we expect, '&'.
// If found, we split the URL into two pieces around the
// first '&'.
var connEnd = src . indexOf ( '&' ) ;
var streamBegin ;
if ( connEnd !== - 1 ) {
streamBegin = connEnd + 1 ;
}
else {
// If there's not a '&', we use the last '/' as the delimiter.
connEnd = streamBegin = src . lastIndexOf ( '/' ) + 1 ;
if ( connEnd === 0 ) {
// really, there's not a '/'?
connEnd = streamBegin = src . length ;
}
}
parts . connection = src . substring ( 0 , connEnd ) ;
parts . stream = src . substring ( streamBegin , src . length ) ;
return parts ;
} ;
vjs . Flash . isStreamingType = function ( srcType ) {
return srcType in vjs . Flash . streamingFormats ;
} ;
// RTMP has four variations, any string starting
// with one of these protocols should be valid
vjs . Flash . RTMP _RE = /^rtmp[set]?:\/\//i ;
vjs . Flash . isStreamingSrc = function ( src ) {
return vjs . Flash . RTMP _RE . test ( src ) ;
} ;