annotate johndyer-mediaelement-13fa20a/src/js/me-shim.js @ 25:4a4bd554b4c1 tip

Closing this sub branch.
author Daniele Barchiesi <daniele.barchiesi@eecs.qmul.ac.uk>
date Mon, 25 Mar 2013 14:02:54 +0000
parents 032bc65ebafc
children
rev   line source
gyorgy@0 1
gyorgy@0 2 // Handles calls from Flash/Silverlight and reports them as native <video/audio> events and properties
gyorgy@0 3 mejs.MediaPluginBridge = {
gyorgy@0 4
gyorgy@0 5 pluginMediaElements:{},
gyorgy@0 6 htmlMediaElements:{},
gyorgy@0 7
gyorgy@0 8 registerPluginElement: function (id, pluginMediaElement, htmlMediaElement) {
gyorgy@0 9 this.pluginMediaElements[id] = pluginMediaElement;
gyorgy@0 10 this.htmlMediaElements[id] = htmlMediaElement;
gyorgy@0 11 },
gyorgy@0 12
gyorgy@0 13 // when Flash/Silverlight is ready, it calls out to this method
gyorgy@0 14 initPlugin: function (id) {
gyorgy@0 15
gyorgy@0 16 var pluginMediaElement = this.pluginMediaElements[id],
gyorgy@0 17 htmlMediaElement = this.htmlMediaElements[id];
gyorgy@0 18
gyorgy@0 19 // find the javascript bridge
gyorgy@0 20 switch (pluginMediaElement.pluginType) {
gyorgy@0 21 case "flash":
gyorgy@0 22 pluginMediaElement.pluginElement = pluginMediaElement.pluginApi = document.getElementById(id);
gyorgy@0 23 break;
gyorgy@0 24 case "silverlight":
gyorgy@0 25 pluginMediaElement.pluginElement = document.getElementById(pluginMediaElement.id);
gyorgy@0 26 pluginMediaElement.pluginApi = pluginMediaElement.pluginElement.Content.MediaElementJS;
gyorgy@0 27 break;
gyorgy@0 28 }
gyorgy@0 29
gyorgy@0 30 if (pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
gyorgy@0 31 pluginMediaElement.success(pluginMediaElement, htmlMediaElement);
gyorgy@0 32 }
gyorgy@0 33 },
gyorgy@0 34
gyorgy@0 35 // receives events from Flash/Silverlight and sends them out as HTML5 media events
gyorgy@0 36 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
gyorgy@0 37 fireEvent: function (id, eventName, values) {
gyorgy@0 38
gyorgy@0 39 var
gyorgy@0 40 e,
gyorgy@0 41 i,
gyorgy@0 42 bufferedTime,
gyorgy@0 43 pluginMediaElement = this.pluginMediaElements[id];
gyorgy@0 44
gyorgy@0 45 pluginMediaElement.ended = false;
gyorgy@0 46 pluginMediaElement.paused = true;
gyorgy@0 47
gyorgy@0 48 // fake event object to mimic real HTML media event.
gyorgy@0 49 e = {
gyorgy@0 50 type: eventName,
gyorgy@0 51 target: pluginMediaElement
gyorgy@0 52 };
gyorgy@0 53
gyorgy@0 54 // attach all values to element and event object
gyorgy@0 55 for (i in values) {
gyorgy@0 56 pluginMediaElement[i] = values[i];
gyorgy@0 57 e[i] = values[i];
gyorgy@0 58 }
gyorgy@0 59
gyorgy@0 60 // fake the newer W3C buffered TimeRange (loaded and total have been removed)
gyorgy@0 61 bufferedTime = values.bufferedTime || 0;
gyorgy@0 62
gyorgy@0 63 e.target.buffered = e.buffered = {
gyorgy@0 64 start: function(index) {
gyorgy@0 65 return 0;
gyorgy@0 66 },
gyorgy@0 67 end: function (index) {
gyorgy@0 68 return bufferedTime;
gyorgy@0 69 },
gyorgy@0 70 length: 1
gyorgy@0 71 };
gyorgy@0 72
gyorgy@0 73 pluginMediaElement.dispatchEvent(e.type, e);
gyorgy@0 74 }
gyorgy@0 75 };
gyorgy@0 76
gyorgy@0 77 /*
gyorgy@0 78 Default options
gyorgy@0 79 */
gyorgy@0 80 mejs.MediaElementDefaults = {
gyorgy@0 81 // allows testing on HTML5, flash, silverlight
gyorgy@0 82 // auto: attempts to detect what the browser can do
gyorgy@0 83 // native: forces HTML5 playback
gyorgy@0 84 // shim: disallows HTML5, will attempt either Flash or Silverlight
gyorgy@0 85 // none: forces fallback view
gyorgy@0 86 mode: 'auto',
gyorgy@0 87 // remove or reorder to change plugin priority and availability
gyorgy@0 88 plugins: ['flash','silverlight'],
gyorgy@0 89 // shows debug errors on screen
gyorgy@0 90 enablePluginDebug: false,
gyorgy@0 91 // overrides the type specified, useful for dynamic instantiation
gyorgy@0 92 type: '',
gyorgy@0 93 // path to Flash and Silverlight plugins
gyorgy@0 94 pluginPath: mejs.Utility.getScriptPath(['mediaelement.js','mediaelement.min.js','mediaelement-and-player.js','mediaelement-and-player.min.js']),
gyorgy@0 95 // name of flash file
gyorgy@0 96 flashName: 'flashmediaelement.swf',
gyorgy@0 97 // turns on the smoothing filter in Flash
gyorgy@0 98 enablePluginSmoothing: false,
gyorgy@0 99 // name of silverlight file
gyorgy@0 100 silverlightName: 'silverlightmediaelement.xap',
gyorgy@0 101 // default if the <video width> is not specified
gyorgy@0 102 defaultVideoWidth: 480,
gyorgy@0 103 // default if the <video height> is not specified
gyorgy@0 104 defaultVideoHeight: 270,
gyorgy@0 105 // overrides <video width>
gyorgy@0 106 pluginWidth: -1,
gyorgy@0 107 // overrides <video height>
gyorgy@0 108 pluginHeight: -1,
gyorgy@0 109 // rate in milliseconds for Flash and Silverlight to fire the timeupdate event
gyorgy@0 110 // larger number is less accurate, but less strain on plugin->JavaScript bridge
gyorgy@0 111 timerRate: 250,
gyorgy@0 112 success: function () { },
gyorgy@0 113 error: function () { }
gyorgy@0 114 };
gyorgy@0 115
gyorgy@0 116 /*
gyorgy@0 117 Determines if a browser supports the <video> or <audio> element
gyorgy@0 118 and returns either the native element or a Flash/Silverlight version that
gyorgy@0 119 mimics HTML5 MediaElement
gyorgy@0 120 */
gyorgy@0 121 mejs.MediaElement = function (el, o) {
gyorgy@0 122 return mejs.HtmlMediaElementShim.create(el,o);
gyorgy@0 123 };
gyorgy@0 124
gyorgy@0 125 mejs.HtmlMediaElementShim = {
gyorgy@0 126
gyorgy@0 127 create: function(el, o) {
gyorgy@0 128 var
gyorgy@0 129 options = mejs.MediaElementDefaults,
gyorgy@0 130 htmlMediaElement = (typeof(el) == 'string') ? document.getElementById(el) : el,
gyorgy@0 131 tagName = htmlMediaElement.tagName.toLowerCase(),
gyorgy@0 132 isMediaTag = (tagName == 'audio' || tagName == 'video'),
gyorgy@0 133 src = htmlMediaElement.getAttribute('src'),
gyorgy@0 134 poster = htmlMediaElement.getAttribute('poster'),
gyorgy@0 135 autoplay = htmlMediaElement.getAttribute('autoplay'),
gyorgy@0 136 preload = htmlMediaElement.getAttribute('preload'),
gyorgy@0 137 controls = htmlMediaElement.getAttribute('controls'),
gyorgy@0 138 playback,
gyorgy@0 139 prop;
gyorgy@0 140
gyorgy@0 141 // extend options
gyorgy@0 142 for (prop in o) {
gyorgy@0 143 options[prop] = o[prop];
gyorgy@0 144 }
gyorgy@0 145
gyorgy@0 146
gyorgy@0 147 // is this a true HTML5 media element
gyorgy@0 148 if (isMediaTag) {
gyorgy@0 149 isVideo = (htmlMediaElement.tagName.toLowerCase() == 'video');
gyorgy@0 150 } else {
gyorgy@0 151 // fake source from <a href=""></a>
gyorgy@0 152 src = htmlMediaElement.getAttribute('href');
gyorgy@0 153 }
gyorgy@0 154
gyorgy@0 155 // clean up attributes
gyorgy@0 156 src = (src == 'undefined' || src == '' || src === null) ? null : src;
gyorgy@0 157 poster = (typeof poster == 'undefined' || poster === null) ? '' : poster;
gyorgy@0 158 preload = (typeof preload == 'undefined' || preload === null || preload === 'false') ? 'none' : preload;
gyorgy@0 159 autoplay = !(typeof autoplay == 'undefined' || autoplay === null || autoplay === 'false');
gyorgy@0 160 controls = !(typeof controls == 'undefined' || controls === null || controls === 'false');
gyorgy@0 161
gyorgy@0 162 // test for HTML5 and plugin capabilities
gyorgy@0 163 playback = this.determinePlayback(htmlMediaElement, options, mejs.MediaFeatures.supportsMediaTag, isMediaTag, src);
gyorgy@0 164
gyorgy@0 165 if (playback.method == 'native') {
gyorgy@0 166 // second fix for android
gyorgy@0 167 if (mejs.MediaFeatures.isBustedAndroid) {
gyorgy@0 168 htmlMediaElement.src = playback.url;
gyorgy@0 169 htmlMediaElement.addEventListener('click', function() {
gyorgy@0 170 htmlMediaElement.play();
gyorgy@0 171 }, true);
gyorgy@0 172 }
gyorgy@0 173
gyorgy@0 174 // add methods to native HTMLMediaElement
gyorgy@0 175 return this.updateNative( playback.htmlMediaElement, options, autoplay, preload, playback);
gyorgy@0 176 } else if (playback.method !== '') {
gyorgy@0 177 // create plugin to mimic HTMLMediaElement
gyorgy@0 178 return this.createPlugin( htmlMediaElement, options, playback.method, (playback.url !== null) ? mejs.Utility.absolutizeUrl(playback.url) : '', poster, autoplay, preload, controls);
gyorgy@0 179 } else {
gyorgy@0 180 // boo, no HTML5, no Flash, no Silverlight.
gyorgy@0 181 this.createErrorMessage( htmlMediaElement, options, (playback.url !== null) ? mejs.Utility.absolutizeUrl(playback.url) : '', poster );
gyorgy@0 182 }
gyorgy@0 183 },
gyorgy@0 184
gyorgy@0 185 videoRegExp: /(mp4|m4v|ogg|ogv|webm|flv|wmv|mpeg)/gi,
gyorgy@0 186
gyorgy@0 187 determinePlayback: function(htmlMediaElement, options, supportsMediaTag, isMediaTag, src) {
gyorgy@0 188 var
gyorgy@0 189 mediaFiles = [],
gyorgy@0 190 i,
gyorgy@0 191 j,
gyorgy@0 192 k,
gyorgy@0 193 l,
gyorgy@0 194 n,
gyorgy@0 195 type,
gyorgy@0 196 result = { method: '', url: '', htmlMediaElement: htmlMediaElement, isVideo: (htmlMediaElement.tagName.toLowerCase() != 'audio')},
gyorgy@0 197 pluginName,
gyorgy@0 198 pluginVersions,
gyorgy@0 199 pluginInfo,
gyorgy@0 200 dummy;
gyorgy@0 201
gyorgy@0 202 // STEP 1: Get URL and type from <video src> or <source src>
gyorgy@0 203
gyorgy@0 204 // supplied type overrides <video type> and <source type>
gyorgy@0 205 if (typeof options.type != 'undefined' && options.type !== '') {
gyorgy@0 206
gyorgy@0 207 // accept either string or array of types
gyorgy@0 208 if (typeof options.type == 'string') {
gyorgy@0 209 mediaFiles.push({type:options.type, url:src});
gyorgy@0 210 } else {
gyorgy@0 211
gyorgy@0 212 for (i=0; i<options.type.length; i++) {
gyorgy@0 213 mediaFiles.push({type:options.type[i], url:src});
gyorgy@0 214 }
gyorgy@0 215 }
gyorgy@0 216
gyorgy@0 217 // test for src attribute first
gyorgy@0 218 } else if (src !== null) {
gyorgy@0 219 type = this.formatType(src, htmlMediaElement.getAttribute('type'));
gyorgy@0 220 mediaFiles.push({type:type, url:src});
gyorgy@0 221
gyorgy@0 222 // then test for <source> elements
gyorgy@0 223 } else {
gyorgy@0 224 // test <source> types to see if they are usable
gyorgy@0 225 for (i = 0; i < htmlMediaElement.childNodes.length; i++) {
gyorgy@0 226 n = htmlMediaElement.childNodes[i];
gyorgy@0 227 if (n.nodeType == 1 && n.tagName.toLowerCase() == 'source') {
gyorgy@0 228 src = n.getAttribute('src');
gyorgy@0 229 type = this.formatType(src, n.getAttribute('type'));
gyorgy@0 230 mediaFiles.push({type:type, url:src});
gyorgy@0 231 }
gyorgy@0 232 }
gyorgy@0 233 }
gyorgy@0 234
gyorgy@0 235 // STEP 2: Test for playback method
gyorgy@0 236
gyorgy@0 237 // special case for Android which sadly doesn't implement the canPlayType function (always returns '')
gyorgy@0 238 if (mejs.MediaFeatures.isBustedAndroid) {
gyorgy@0 239 htmlMediaElement.canPlayType = function(type) {
gyorgy@0 240 return (type.match(/video\/(mp4|m4v)/gi) !== null) ? 'maybe' : '';
gyorgy@0 241 };
gyorgy@0 242 }
gyorgy@0 243
gyorgy@0 244
gyorgy@0 245 // test for native playback first
gyorgy@0 246 if (supportsMediaTag && (options.mode === 'auto' || options.mode === 'native')) {
gyorgy@0 247
gyorgy@0 248 if (!isMediaTag) {
gyorgy@0 249 var tagName = 'video';
gyorgy@0 250 if (mediaFiles.length > 0 && mediaFiles[0].url !== null && this.getTypeFromFile(mediaFiles[0].url).indexOf('audio') > -1) {
gyorgy@0 251 tagName = 'audio';
gyorgy@0 252 result.isVideo = false;
gyorgy@0 253 }
gyorgy@0 254
gyorgy@0 255 // create a real HTML5 Media Element
gyorgy@0 256 dummy = document.createElement(tagName);
gyorgy@0 257 htmlMediaElement.parentNode.insertBefore(dummy, htmlMediaElement);
gyorgy@0 258 htmlMediaElement.style.display = 'none';
gyorgy@0 259
gyorgy@0 260 // use this one from now on
gyorgy@0 261 result.htmlMediaElement = htmlMediaElement = dummy;
gyorgy@0 262 }
gyorgy@0 263
gyorgy@0 264 for (i=0; i<mediaFiles.length; i++) {
gyorgy@0 265 // normal check
gyorgy@0 266 if (htmlMediaElement.canPlayType(mediaFiles[i].type).replace(/no/, '') !== ''
gyorgy@0 267 // special case for Mac/Safari 5.0.3 which answers '' to canPlayType('audio/mp3') but 'maybe' to canPlayType('audio/mpeg')
gyorgy@0 268 || htmlMediaElement.canPlayType(mediaFiles[i].type.replace(/mp3/,'mpeg')).replace(/no/, '') !== '') {
gyorgy@0 269 result.method = 'native';
gyorgy@0 270 result.url = mediaFiles[i].url;
gyorgy@0 271 break;
gyorgy@0 272 }
gyorgy@0 273 }
gyorgy@0 274
gyorgy@0 275 if (result.method === 'native') {
gyorgy@0 276 return result;
gyorgy@0 277 }
gyorgy@0 278 }
gyorgy@0 279
gyorgy@0 280 // if native playback didn't work, then test plugins
gyorgy@0 281 if (options.mode === 'auto' || options.mode === 'shim') {
gyorgy@0 282 for (i=0; i<mediaFiles.length; i++) {
gyorgy@0 283 type = mediaFiles[i].type;
gyorgy@0 284
gyorgy@0 285 // test all plugins in order of preference [silverlight, flash]
gyorgy@0 286 for (j=0; j<options.plugins.length; j++) {
gyorgy@0 287
gyorgy@0 288 pluginName = options.plugins[j];
gyorgy@0 289
gyorgy@0 290 // test version of plugin (for future features)
gyorgy@0 291 pluginVersions = mejs.plugins[pluginName];
gyorgy@0 292 for (k=0; k<pluginVersions.length; k++) {
gyorgy@0 293 pluginInfo = pluginVersions[k];
gyorgy@0 294
gyorgy@0 295 // test if user has the correct plugin version
gyorgy@0 296 if (mejs.PluginDetector.hasPluginVersion(pluginName, pluginInfo.version)) {
gyorgy@0 297
gyorgy@0 298 // test for plugin playback types
gyorgy@0 299 for (l=0; l<pluginInfo.types.length; l++) {
gyorgy@0 300 // find plugin that can play the type
gyorgy@0 301 if (type == pluginInfo.types[l]) {
gyorgy@0 302 result.method = pluginName;
gyorgy@0 303 result.url = mediaFiles[i].url;
gyorgy@0 304 return result;
gyorgy@0 305 }
gyorgy@0 306 }
gyorgy@0 307 }
gyorgy@0 308 }
gyorgy@0 309 }
gyorgy@0 310 }
gyorgy@0 311 }
gyorgy@0 312
gyorgy@0 313 // what if there's nothing to play? just grab the first available
gyorgy@0 314 if (result.method === '') {
gyorgy@0 315 result.url = mediaFiles[0].url;
gyorgy@0 316 }
gyorgy@0 317
gyorgy@0 318 return result;
gyorgy@0 319 },
gyorgy@0 320
gyorgy@0 321 formatType: function(url, type) {
gyorgy@0 322 var ext;
gyorgy@0 323
gyorgy@0 324 // if no type is supplied, fake it with the extension
gyorgy@0 325 if (url && !type) {
gyorgy@0 326 return this.getTypeFromFile(url);
gyorgy@0 327 } else {
gyorgy@0 328 // only return the mime part of the type in case the attribute contains the codec
gyorgy@0 329 // see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#the-source-element
gyorgy@0 330 // `video/mp4; codecs="avc1.42E01E, mp4a.40.2"` becomes `video/mp4`
gyorgy@0 331
gyorgy@0 332 if (type && ~type.indexOf(';')) {
gyorgy@0 333 return type.substr(0, type.indexOf(';'));
gyorgy@0 334 } else {
gyorgy@0 335 return type;
gyorgy@0 336 }
gyorgy@0 337 }
gyorgy@0 338 },
gyorgy@0 339
gyorgy@0 340 getTypeFromFile: function(url) {
gyorgy@0 341 var ext = url.substring(url.lastIndexOf('.') + 1);
gyorgy@0 342 return (this.videoRegExp.test(ext) ? 'video' : 'audio') + '/' + ext;
gyorgy@0 343 },
gyorgy@0 344
gyorgy@0 345 createErrorMessage: function(htmlMediaElement, options, downloadUrl, poster) {
gyorgy@0 346 var errorContainer = document.createElement('div');
gyorgy@0 347 errorContainer.className = 'me-cannotplay';
gyorgy@0 348
gyorgy@0 349 try {
gyorgy@0 350 errorContainer.style.width = htmlMediaElement.width + 'px';
gyorgy@0 351 errorContainer.style.height = htmlMediaElement.height + 'px';
gyorgy@0 352 } catch (e) {}
gyorgy@0 353
gyorgy@0 354 errorContainer.innerHTML = (poster !== '') ?
gyorgy@0 355 '<a href="' + downloadUrl + '"><img src="' + poster + '" /></a>' :
gyorgy@0 356 '<a href="' + downloadUrl + '"><span>Download File</span></a>';
gyorgy@0 357
gyorgy@0 358 htmlMediaElement.parentNode.insertBefore(errorContainer, htmlMediaElement);
gyorgy@0 359 htmlMediaElement.style.display = 'none';
gyorgy@0 360
gyorgy@0 361 options.error(htmlMediaElement);
gyorgy@0 362 },
gyorgy@0 363
gyorgy@0 364 createPlugin:function(htmlMediaElement, options, isVideo, pluginType, mediaUrl, poster, autoplay, preload, controls) {
gyorgy@0 365 var width = 1,
gyorgy@0 366 height = 1,
gyorgy@0 367 pluginid = 'me_' + pluginType + '_' + (mejs.meIndex++),
gyorgy@0 368 pluginMediaElement = new mejs.PluginMediaElement(pluginid, pluginType, mediaUrl),
gyorgy@0 369 container = document.createElement('div'),
gyorgy@0 370 specialIEContainer,
gyorgy@0 371 node,
gyorgy@0 372 initVars;
gyorgy@0 373
gyorgy@0 374 // check for placement inside a <p> tag (sometimes WYSIWYG editors do this)
gyorgy@0 375 node = htmlMediaElement.parentNode;
gyorgy@0 376 while (node !== null && node.tagName.toLowerCase() != 'body') {
gyorgy@0 377 if (node.parentNode.tagName.toLowerCase() == 'p') {
gyorgy@0 378 node.parentNode.parentNode.insertBefore(node, node.parentNode);
gyorgy@0 379 break;
gyorgy@0 380 }
gyorgy@0 381 node = node.parentNode;
gyorgy@0 382 }
gyorgy@0 383
gyorgy@0 384 if (isVideo) {
gyorgy@0 385 width = (options.videoWidth > 0) ? options.videoWidth : (htmlMediaElement.getAttribute('width') !== null) ? htmlMediaElement.getAttribute('width') : options.defaultVideoWidth;
gyorgy@0 386 height = (options.videoHeight > 0) ? options.videoHeight : (htmlMediaElement.getAttribute('height') !== null) ? htmlMediaElement.getAttribute('height') : options.defaultVideoHeight;
gyorgy@0 387 } else {
gyorgy@0 388 if (options.enablePluginDebug) {
gyorgy@0 389 width = 320;
gyorgy@0 390 height = 240;
gyorgy@0 391 }
gyorgy@0 392 }
gyorgy@0 393
gyorgy@0 394 // register plugin
gyorgy@0 395 pluginMediaElement.success = options.success;
gyorgy@0 396 mejs.MediaPluginBridge.registerPluginElement(pluginid, pluginMediaElement, htmlMediaElement);
gyorgy@0 397
gyorgy@0 398 // add container (must be added to DOM before inserting HTML for IE)
gyorgy@0 399 container.className = 'me-plugin';
gyorgy@0 400 htmlMediaElement.parentNode.insertBefore(container, htmlMediaElement);
gyorgy@0 401
gyorgy@0 402 // flash/silverlight vars
gyorgy@0 403 initVars = [
gyorgy@0 404 'id=' + pluginid,
gyorgy@0 405 'isvideo=' + ((isVideo) ? "true" : "false"),
gyorgy@0 406 'autoplay=' + ((autoplay) ? "true" : "false"),
gyorgy@0 407 'preload=' + preload,
gyorgy@0 408 'width=' + width,
gyorgy@0 409 'startvolume=' + options.startVolume,
gyorgy@0 410 'timerrate=' + options.timerRate,
gyorgy@0 411 'height=' + height];
gyorgy@0 412
gyorgy@0 413 if (mediaUrl !== null) {
gyorgy@0 414 if (pluginType == 'flash') {
gyorgy@0 415 initVars.push('file=' + mejs.Utility.encodeUrl(mediaUrl));
gyorgy@0 416 } else {
gyorgy@0 417 initVars.push('file=' + mediaUrl);
gyorgy@0 418 }
gyorgy@0 419 }
gyorgy@0 420 if (options.enablePluginDebug) {
gyorgy@0 421 initVars.push('debug=true');
gyorgy@0 422 }
gyorgy@0 423 if (options.enablePluginSmoothing) {
gyorgy@0 424 initVars.push('smoothing=true');
gyorgy@0 425 }
gyorgy@0 426 if (controls) {
gyorgy@0 427 initVars.push('controls=true'); // shows controls in the plugin if desired
gyorgy@0 428 }
gyorgy@0 429
gyorgy@0 430 switch (pluginType) {
gyorgy@0 431 case 'silverlight':
gyorgy@0 432 container.innerHTML =
gyorgy@0 433 '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="' + pluginid + '" name="' + pluginid + '" width="' + width + '" height="' + height + '">' +
gyorgy@0 434 '<param name="initParams" value="' + initVars.join(',') + '" />' +
gyorgy@0 435 '<param name="windowless" value="true" />' +
gyorgy@0 436 '<param name="background" value="black" />' +
gyorgy@0 437 '<param name="minRuntimeVersion" value="3.0.0.0" />' +
gyorgy@0 438 '<param name="autoUpgrade" value="true" />' +
gyorgy@0 439 '<param name="source" value="' + options.pluginPath + options.silverlightName + '" />' +
gyorgy@0 440 '</object>';
gyorgy@0 441 break;
gyorgy@0 442
gyorgy@0 443 case 'flash':
gyorgy@0 444
gyorgy@0 445 if (mejs.MediaFeatures.isIE) {
gyorgy@0 446 specialIEContainer = document.createElement('div');
gyorgy@0 447 container.appendChild(specialIEContainer);
gyorgy@0 448 specialIEContainer.outerHTML =
gyorgy@0 449 '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
gyorgy@0 450 'id="' + pluginid + '" width="' + width + '" height="' + height + '">' +
gyorgy@0 451 '<param name="movie" value="' + options.pluginPath + options.flashName + '?x=' + (new Date()) + '" />' +
gyorgy@0 452 '<param name="flashvars" value="' + initVars.join('&amp;') + '" />' +
gyorgy@0 453 '<param name="quality" value="high" />' +
gyorgy@0 454 '<param name="bgcolor" value="#000000" />' +
gyorgy@0 455 '<param name="wmode" value="transparent" />' +
gyorgy@0 456 '<param name="allowScriptAccess" value="always" />' +
gyorgy@0 457 '<param name="allowFullScreen" value="true" />' +
gyorgy@0 458 '</object>';
gyorgy@0 459
gyorgy@0 460 } else {
gyorgy@0 461
gyorgy@0 462 container.innerHTML =
gyorgy@0 463 '<embed id="' + pluginid + '" name="' + pluginid + '" ' +
gyorgy@0 464 'play="true" ' +
gyorgy@0 465 'loop="false" ' +
gyorgy@0 466 'quality="high" ' +
gyorgy@0 467 'bgcolor="#000000" ' +
gyorgy@0 468 'wmode="transparent" ' +
gyorgy@0 469 'allowScriptAccess="always" ' +
gyorgy@0 470 'allowFullScreen="true" ' +
gyorgy@0 471 'type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" ' +
gyorgy@0 472 'src="' + options.pluginPath + options.flashName + '" ' +
gyorgy@0 473 'flashvars="' + initVars.join('&') + '" ' +
gyorgy@0 474 'width="' + width + '" ' +
gyorgy@0 475 'height="' + height + '"></embed>';
gyorgy@0 476 }
gyorgy@0 477 break;
gyorgy@0 478 }
gyorgy@0 479 // hide original element
gyorgy@0 480 htmlMediaElement.style.display = 'none';
gyorgy@0 481
gyorgy@0 482 // FYI: options.success will be fired by the MediaPluginBridge
gyorgy@0 483
gyorgy@0 484 return pluginMediaElement;
gyorgy@0 485 },
gyorgy@0 486
gyorgy@0 487 updateNative: function(htmlMediaElement, options, autoplay, preload, playback) {
gyorgy@0 488 // add methods to video object to bring it into parity with Flash Object
gyorgy@0 489 for (var m in mejs.HtmlMediaElement) {
gyorgy@0 490 htmlMediaElement[m] = mejs.HtmlMediaElement[m];
gyorgy@0 491 }
gyorgy@0 492
gyorgy@0 493 /*
gyorgy@0 494 Chrome now supports preload="none"
gyorgy@0 495 if (mejs.MediaFeatures.isChrome) {
gyorgy@0 496
gyorgy@0 497 // special case to enforce preload attribute (Chrome doesn't respect this)
gyorgy@0 498 if (preload === 'none' && !autoplay) {
gyorgy@0 499
gyorgy@0 500 // forces the browser to stop loading (note: fails in IE9)
gyorgy@0 501 htmlMediaElement.src = '';
gyorgy@0 502 htmlMediaElement.load();
gyorgy@0 503 htmlMediaElement.canceledPreload = true;
gyorgy@0 504
gyorgy@0 505 htmlMediaElement.addEventListener('play',function() {
gyorgy@0 506 if (htmlMediaElement.canceledPreload) {
gyorgy@0 507 htmlMediaElement.src = playback.url;
gyorgy@0 508 htmlMediaElement.load();
gyorgy@0 509 htmlMediaElement.play();
gyorgy@0 510 htmlMediaElement.canceledPreload = false;
gyorgy@0 511 }
gyorgy@0 512 }, false);
gyorgy@0 513 // for some reason Chrome forgets how to autoplay sometimes.
gyorgy@0 514 } else if (autoplay) {
gyorgy@0 515 htmlMediaElement.load();
gyorgy@0 516 htmlMediaElement.play();
gyorgy@0 517 }
gyorgy@0 518 }
gyorgy@0 519 */
gyorgy@0 520
gyorgy@0 521 // fire success code
gyorgy@0 522 options.success(htmlMediaElement, htmlMediaElement);
gyorgy@0 523
gyorgy@0 524 return htmlMediaElement;
gyorgy@0 525 }
gyorgy@0 526 };
gyorgy@0 527
gyorgy@0 528 window.mejs = mejs;
gyorgy@0 529 window.MediaElement = mejs.MediaElement;