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('&') + '" />' +
|
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; |