Permalink
Browse files

Merge pull request #7 from hackeron/master

Bump mediaelement version to 2.6.4 and this version to 0.3.2
  • Loading branch information...
2 parents 6777055 + 87362e8 commit 533a40020aba2cea4784f51450d7ff8edba062f1 @tobsch committed Feb 20, 2012
View
1 .gitignore
@@ -1,3 +1,4 @@
+*.DS_Store
.bundle/
pkg/
Gemfile.lock
View
0 app/assets/images/mediaelement_rails/background.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 app/assets/images/mediaelement_rails/bigplay.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/assets/images/mediaelement_rails/controls-ted.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/assets/images/mediaelement_rails/controls-wmp-bg.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/assets/images/mediaelement_rails/controls-wmp.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 app/assets/images/mediaelement_rails/controls.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 app/assets/images/mediaelement_rails/loading.gif 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
695 app/assets/javascripts/mediaelement_rails/mediaelement.js 100644 → 100755
@@ -11,109 +11,145 @@
* Dual licensed under the MIT or GPL Version 2 licenses.
*
*/
-// Namespace
-var mejs = mejs || {};
-
-// version number
-mejs.version = '2.2.5';
-
-// player number (for missing, same id attr)
-mejs.meIndex = 0;
-
-// media types accepted by plugins
-mejs.plugins = {
- silverlight: [
- {version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
- ],
- flash: [
- {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg']}
- //,{version: [12,0], types: ['video/webm']} // for future reference
- ]
-};
-
-/*
-Utility methods
-*/
-mejs.Utility = {
- encodeUrl: function(url) {
- return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
- },
- escapeHTML: function(s) {
- return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
- },
- absolutizeUrl: function(url) {
- var el = document.createElement('div');
- el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
- return el.firstChild.href;
- },
- getScriptPath: function(scriptNames) {
- var
- i = 0,
- j,
- path = '',
- name = '',
- script,
- scripts = document.getElementsByTagName('script');
-
- for (; i < scripts.length; i++) {
- script = scripts[i].src;
- for (j = 0; j < scriptNames.length; j++) {
- name = scriptNames[j];
- if (script.indexOf(name) > -1) {
- path = script.substring(0, script.indexOf(name));
- break;
- }
- }
- if (path !== '') {
- break;
- }
- }
- return path;
- },
- secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
- //add framecount
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var hours = Math.floor(time / 3600) % 24,
- minutes = Math.floor(time / 60) % 60,
- seconds = Math.floor(time % 60),
- frames = Math.floor(((time % 1)*fps).toFixed(3)),
- result =
- ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
- + (minutes < 10 ? '0' + minutes : minutes) + ':'
- + (seconds < 10 ? '0' + seconds : seconds)
- + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
-
- return result;
- },
-
- timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
- if (typeof showFrameCount == 'undefined') {
- showFrameCount=false;
- } else if(typeof fps == 'undefined') {
- fps = 25;
- }
-
- var tc_array = hh_mm_ss_ff.split(":"),
- tc_hh = parseInt(tc_array[0]),
- tc_mm = parseInt(tc_array[1]),
- tc_ss = parseInt(tc_array[2]),
- tc_ff = 0,
- tc_in_seconds = 0;
-
- if (showFrameCount) {
- tc_ff = parseInt(tc_array[3])/fps;
- }
-
- tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
-
- return tc_in_seconds;
- }
+// Namespace
+var mejs = mejs || {};
+
+// version number
+mejs.version = '2.6.5';
+
+// player number (for missing, same id attr)
+mejs.meIndex = 0;
+
+// media types accepted by plugins
+mejs.plugins = {
+ silverlight: [
+ {version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
+ ],
+ flash: [
+ {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg']}
+ //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
+ ],
+ youtube: [
+ {version: null, types: ['video/youtube']}
+ ],
+ vimeo: [
+ {version: null, types: ['video/vimeo']}
+ ]
};
+
+/*
+Utility methods
+*/
+mejs.Utility = {
+ encodeUrl: function(url) {
+ return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
+ },
+ escapeHTML: function(s) {
+ return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
+ },
+ absolutizeUrl: function(url) {
+ var el = document.createElement('div');
+ el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
+ return el.firstChild.href;
+ },
+ getScriptPath: function(scriptNames) {
+ var
+ i = 0,
+ j,
+ path = '',
+ name = '',
+ script,
+ scripts = document.getElementsByTagName('script');
+
+ for (; i < scripts.length; i++) {
+ script = scripts[i].src;
+ for (j = 0; j < scriptNames.length; j++) {
+ name = scriptNames[j];
+ if (script.indexOf(name) > -1) {
+ path = script.substring(0, script.indexOf(name));
+ break;
+ }
+ }
+ if (path !== '') {
+ break;
+ }
+ }
+ return path;
+ },
+ secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
+ //add framecount
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var hours = Math.floor(time / 3600) % 24,
+ minutes = Math.floor(time / 60) % 60,
+ seconds = Math.floor(time % 60),
+ frames = Math.floor(((time % 1)*fps).toFixed(3)),
+ result =
+ ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
+ + (minutes < 10 ? '0' + minutes : minutes) + ':'
+ + (seconds < 10 ? '0' + seconds : seconds)
+ + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
+
+ return result;
+ },
+
+ timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
+ if (typeof showFrameCount == 'undefined') {
+ showFrameCount=false;
+ } else if(typeof fps == 'undefined') {
+ fps = 25;
+ }
+
+ var tc_array = hh_mm_ss_ff.split(":"),
+ tc_hh = parseInt(tc_array[0], 10),
+ tc_mm = parseInt(tc_array[1], 10),
+ tc_ss = parseInt(tc_array[2], 10),
+ tc_ff = 0,
+ tc_in_seconds = 0;
+
+ if (showFrameCount) {
+ tc_ff = parseInt(tc_array[3])/fps;
+ }
+
+ tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
+
+ return tc_in_seconds;
+ },
+
+ /* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
+ removeSwf: function(id) {
+ var obj = document.getElementById(id);
+ if (obj && obj.nodeName == "OBJECT") {
+ if (mejs.MediaFeatures.isIE) {
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ mejs.Utility.removeObjectInIE(id);
+ } else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ } else {
+ obj.parentNode.removeChild(obj);
+ }
+ }
+ },
+ removeObjectInIE: function(id) {
+ var obj = document.getElementById(id);
+ if (obj) {
+ for (var i in obj) {
+ if (typeof obj[i] == "function") {
+ obj[i] = null;
+ }
+ }
+ obj.parentNode.removeChild(obj);
+ }
+ }
+};
// Core detector, plugins are added below
@@ -238,8 +274,10 @@ mejs.MediaFeatures = {
t.isIE = (nav.appName.toLowerCase().indexOf("microsoft") != -1);
t.isChrome = (ua.match(/chrome/gi) !== null);
t.isFirefox = (ua.match(/firefox/gi) !== null);
- t.isGecko = (ua.match(/gecko/gi) !== null);
t.isWebkit = (ua.match(/webkit/gi) !== null);
+ t.isGecko = (ua.match(/gecko/gi) !== null) && !t.isWebkit;
+ t.isOpera = (ua.match(/opera/gi) !== null);
+ t.hasTouch = ('ontouchstart' in window);
// create HTML5 media elements for IE before 9, get a <video> element for fullscreen detection
for (i=0; i<html5Elements.length; i++) {
@@ -258,6 +296,10 @@ mejs.MediaFeatures = {
t.hasMozNativeFullScreen = (typeof v.mozRequestFullScreen !== 'undefined');
t.hasTrueNativeFullScreen = (t.hasWebkitNativeFullScreen || t.hasMozNativeFullScreen);
+ t.nativeFullScreenEnabled = t.hasTrueNativeFullScreen;
+ if (t.hasMozNativeFullScreen) {
+ t.nativeFullScreenEnabled = v.mozFullScreenEnabled;
+ }
if (this.isChrome) {
@@ -403,25 +445,43 @@ mejs.PluginMediaElement.prototype = {
// HTML5 methods
play: function () {
if (this.pluginApi != null) {
- this.pluginApi.playMedia();
+ if (this.pluginType == 'youtube') {
+ this.pluginApi.playVideo();
+ } else {
+ this.pluginApi.playMedia();
+ }
this.paused = false;
}
},
load: function () {
if (this.pluginApi != null) {
- this.pluginApi.loadMedia();
+ if (this.pluginType == 'youtube') {
+ } else {
+ this.pluginApi.loadMedia();
+ }
+
this.paused = false;
}
},
pause: function () {
if (this.pluginApi != null) {
- this.pluginApi.pauseMedia();
+ if (this.pluginType == 'youtube') {
+ this.pluginApi.pauseVideo();
+ } else {
+ this.pluginApi.pauseMedia();
+ }
+
+
this.paused = true;
}
},
stop: function () {
if (this.pluginApi != null) {
- this.pluginApi.stopMedia();
+ if (this.pluginType == 'youtube') {
+ this.pluginApi.stopVideo();
+ } else {
+ this.pluginApi.stopMedia();
+ }
this.paused = true;
}
},
@@ -449,6 +509,19 @@ mejs.PluginMediaElement.prototype = {
return false;
},
+
+ positionFullscreenButton: function(x,y,visibleAndAbove) {
+ if (this.pluginApi != null && this.pluginApi.positionFullscreenButton) {
+ this.pluginApi.positionFullscreenButton(x,y,visibleAndAbove);
+ }
+ },
+
+ hideFullscreenButton: function() {
+ if (this.pluginApi != null && this.pluginApi.hideFullscreenButton) {
+ this.pluginApi.hideFullscreenButton();
+ }
+ },
+
// custom methods since not all JavaScript implementations support get/set
@@ -473,46 +546,76 @@ mejs.PluginMediaElement.prototype = {
},
setCurrentTime: function (time) {
if (this.pluginApi != null) {
- this.pluginApi.setCurrentTime(time);
+ if (this.pluginType == 'youtube') {
+ this.pluginApi.seekTo(time);
+ } else {
+ this.pluginApi.setCurrentTime(time);
+ }
+
+
+
this.currentTime = time;
}
},
setVolume: function (volume) {
if (this.pluginApi != null) {
- this.pluginApi.setVolume(volume);
+ // same on YouTube and MEjs
+ if (this.pluginType == 'youtube') {
+ this.pluginApi.setVolume(volume * 100);
+ } else {
+ this.pluginApi.setVolume(volume);
+ }
this.volume = volume;
}
},
setMuted: function (muted) {
if (this.pluginApi != null) {
- this.pluginApi.setMuted(muted);
+ if (this.pluginType == 'youtube') {
+ if (muted) {
+ this.pluginApi.mute();
+ } else {
+ this.pluginApi.unMute();
+ }
+ this.muted = muted;
+ this.dispatchEvent('volumechange');
+ } else {
+ this.pluginApi.setMuted(muted);
+ }
this.muted = muted;
}
},
// additional non-HTML5 methods
setVideoSize: function (width, height) {
- if ( this.pluginElement.style) {
- this.pluginElement.style.width = width + 'px';
- this.pluginElement.style.height = height + 'px';
- }
- if (this.pluginApi != null) {
- this.pluginApi.setVideoSize(width, height);
- }
+
+ //if (this.pluginType == 'flash' || this.pluginType == 'silverlight') {
+ if ( this.pluginElement.style) {
+ this.pluginElement.style.width = width + 'px';
+ this.pluginElement.style.height = height + 'px';
+ }
+ if (this.pluginApi != null && this.pluginApi.setVideoSize) {
+ this.pluginApi.setVideoSize(width, height);
+ }
+ //}
},
setFullscreen: function (fullscreen) {
- if (this.pluginApi != null) {
+ if (this.pluginApi != null && this.pluginApi.setFullscreen) {
this.pluginApi.setFullscreen(fullscreen);
}
},
enterFullScreen: function() {
- this.setFullscreen(true);
+ if (this.pluginApi != null && this.pluginApi.setFullscreen) {
+ this.setFullscreen(true);
+ }
+
},
- enterFullScreen: function() {
- this.setFullscreen(false);
+ exitFullScreen: function() {
+ if (this.pluginApi != null && this.pluginApi.setFullscreen) {
+ this.setFullscreen(false);
+ }
},
// start: fake events
@@ -544,11 +647,14 @@ mejs.PluginMediaElement.prototype = {
callbacks[i].apply(null, args);
}
}
- }
+ },
// end: fake events
+
+ remove: function() {
+ mejs.Utility.removeSwf(this.pluginElement.id);
+ }
};
-
// Handles calls from Flash/Silverlight and reports them as native <video/audio> events and properties
mejs.MediaPluginBridge = {
@@ -566,19 +672,21 @@ mejs.MediaPluginBridge = {
var pluginMediaElement = this.pluginMediaElements[id],
htmlMediaElement = this.htmlMediaElements[id];
- // find the javascript bridge
- switch (pluginMediaElement.pluginType) {
- case "flash":
- pluginMediaElement.pluginElement = pluginMediaElement.pluginApi = document.getElementById(id);
- break;
- case "silverlight":
- pluginMediaElement.pluginElement = document.getElementById(pluginMediaElement.id);
- pluginMediaElement.pluginApi = pluginMediaElement.pluginElement.Content.MediaElementJS;
- break;
- }
-
- if (pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
- pluginMediaElement.success(pluginMediaElement, htmlMediaElement);
+ if (pluginMediaElement) {
+ // find the javascript bridge
+ switch (pluginMediaElement.pluginType) {
+ case "flash":
+ pluginMediaElement.pluginElement = pluginMediaElement.pluginApi = document.getElementById(id);
+ break;
+ case "silverlight":
+ pluginMediaElement.pluginElement = document.getElementById(pluginMediaElement.id);
+ pluginMediaElement.pluginApi = pluginMediaElement.pluginElement.Content.MediaElementJS;
+ break;
+ }
+
+ if (pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
+ pluginMediaElement.success(pluginMediaElement, htmlMediaElement);
+ }
}
},
@@ -635,7 +743,7 @@ mejs.MediaElementDefaults = {
// none: forces fallback view
mode: 'auto',
// remove or reorder to change plugin priority and availability
- plugins: ['flash','silverlight'],
+ plugins: ['flash','silverlight','youtube','vimeo'],
// shows debug errors on screen
enablePluginDebug: false,
// overrides the type specified, useful for dynamic instantiation
@@ -656,6 +764,8 @@ mejs.MediaElementDefaults = {
pluginWidth: -1,
// overrides <video height>
pluginHeight: -1,
+ // additional plugin variables in 'key=value' form
+ pluginVars: [],
// rate in milliseconds for Flash and Silverlight to fire the timeupdate event
// larger number is less accurate, but less strain on plugin->JavaScript bridge
timerRate: 250,
@@ -696,11 +806,11 @@ mejs.HtmlMediaElementShim = {
}
// clean up attributes
- src = (src == 'undefined' || src == '' || src === null) ? null : src;
- poster = (typeof poster == 'undefined' || poster === null) ? '' : poster;
- preload = (typeof preload == 'undefined' || preload === null || preload === 'false') ? 'none' : preload;
- autoplay = !(typeof autoplay == 'undefined' || autoplay === null || autoplay === 'false');
- controls = !(typeof controls == 'undefined' || controls === null || controls === 'false');
+ src = (typeof src == 'undefined' || src === null || src == '') ? null : src;
+ poster = (typeof poster == 'undefined' || poster === null) ? '' : poster;
+ preload = (typeof preload == 'undefined' || preload === null || preload === 'false') ? 'none' : preload;
+ autoplay = !(typeof autoplay == 'undefined' || autoplay === null || autoplay === 'false');
+ controls = !(typeof controls == 'undefined' || controls === null || controls === 'false');
// test for HTML5 and plugin capabilities
playback = this.determinePlayback(htmlMediaElement, options, mejs.MediaFeatures.supportsMediaTag, isMediaTag, src);
@@ -711,8 +821,8 @@ mejs.HtmlMediaElementShim = {
if (mejs.MediaFeatures.isBustedAndroid) {
htmlMediaElement.src = playback.url;
htmlMediaElement.addEventListener('click', function() {
- htmlMediaElement.play();
- }, true);
+ htmlMediaElement.play();
+ }, false);
}
// add methods to native HTMLMediaElement
@@ -724,6 +834,8 @@ mejs.HtmlMediaElementShim = {
} else {
// boo, no HTML5, no Flash, no Silverlight.
this.createErrorMessage( playback, options, poster );
+
+ return this;
}
},
@@ -835,14 +947,19 @@ mejs.HtmlMediaElementShim = {
for (j=0; j<options.plugins.length; j++) {
pluginName = options.plugins[j];
-
+
// test version of plugin (for future features)
- pluginVersions = mejs.plugins[pluginName];
+ pluginVersions = mejs.plugins[pluginName];
+
for (k=0; k<pluginVersions.length; k++) {
pluginInfo = pluginVersions[k];
-
+
// test if user has the correct plugin version
- if (mejs.PluginDetector.hasPluginVersion(pluginName, pluginInfo.version)) {
+
+ // for youtube/vimeo
+ if (pluginInfo.version == null ||
+
+ mejs.PluginDetector.hasPluginVersion(pluginName, pluginInfo.version)) {
// test for plugin playback types
for (l=0; l<pluginInfo.types.length; l++) {
@@ -860,7 +977,7 @@ mejs.HtmlMediaElementShim = {
}
// what if there's nothing to play? just grab the first available
- if (result.method === '') {
+ if (result.method === '' && mediaFiles.length > 0) {
result.url = mediaFiles[0].url;
}
@@ -956,7 +1073,13 @@ mejs.HtmlMediaElementShim = {
// add container (must be added to DOM before inserting HTML for IE)
container.className = 'me-plugin';
- htmlMediaElement.parentNode.insertBefore(container, htmlMediaElement);
+ container.id = pluginid + '_container';
+
+ if (playback.isVideo) {
+ htmlMediaElement.parentNode.insertBefore(container, htmlMediaElement);
+ } else {
+ document.body.insertBefore(container, document.body.childNodes[0]);
+ }
// flash/silverlight vars
initVars = [
@@ -985,6 +1108,9 @@ mejs.HtmlMediaElementShim = {
if (controls) {
initVars.push('controls=true'); // shows controls in the plugin if desired
}
+ if (options.pluginVars) {
+ initVars = initVars.concat(options.pluginVars);
+ }
switch (playback.method) {
case 'silverlight':
@@ -1005,7 +1131,7 @@ mejs.HtmlMediaElementShim = {
specialIEContainer = document.createElement('div');
container.appendChild(specialIEContainer);
specialIEContainer.outerHTML =
-'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
+'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
'id="' + pluginid + '" width="' + width + '" height="' + height + '">' +
'<param name="movie" value="' + options.pluginPath + options.flashName + '?x=' + (new Date()) + '" />' +
'<param name="flashvars" value="' + initVars.join('&amp;') + '" />' +
@@ -1027,13 +1153,53 @@ mejs.HtmlMediaElementShim = {
'wmode="transparent" ' +
'allowScriptAccess="always" ' +
'allowFullScreen="true" ' +
-'type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" ' +
+'type="application/x-shockwave-flash" pluginspage="//www.macromedia.com/go/getflashplayer" ' +
'src="' + options.pluginPath + options.flashName + '" ' +
'flashvars="' + initVars.join('&') + '" ' +
'width="' + width + '" ' +
'height="' + height + '"></embed>';
}
break;
+
+ case 'youtube':
+
+
+ var
+ videoId = playback.url.substr(playback.url.lastIndexOf('=')+1);
+ youtubeSettings = {
+ container: container,
+ containerId: container.id,
+ pluginMediaElement: pluginMediaElement,
+ pluginId: pluginid,
+ videoId: videoId,
+ height: height,
+ width: width
+ };
+
+ if (mejs.PluginDetector.hasPluginVersion('flash', [10,0,0]) ) {
+ mejs.YouTubeApi.createFlash(youtubeSettings);
+ } else {
+ mejs.YouTubeApi.enqueueIframe(youtubeSettings);
+ }
+
+ break;
+
+ // DEMO Code. Does NOT work.
+ case 'vimeo':
+ console.log('vimeoid');
+
+ pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1);
+
+ container.innerHTML =
+ '<object width="' + width + '" height="' + height + '">' +
+ '<param name="allowfullscreen" value="true" />' +
+ '<param name="allowscriptaccess" value="always" />' +
+ '<param name="flashvars" value="api=1" />' +
+ '<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" />' +
+ '<embed src="//vimeo.com/moogaloop.swf?api=1&amp;clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' + width + '" height="' + height + '"></embed>' +
+ '</object>';
+
+ break;
}
// hide original element
htmlMediaElement.style.display = 'none';
@@ -1089,5 +1255,230 @@ mejs.HtmlMediaElementShim = {
}
};
+/*
+ - test on IE (object vs. embed)
+ - determine when to use iframe (Firefox, Safari, Mobile) vs. Flash (Chrome, IE)
+ - fullscreen?
+*/
+
+// YouTube Flash and Iframe API
+mejs.YouTubeApi = {
+ isIframeStarted: false,
+ isIframeLoaded: false,
+ loadIframeApi: function() {
+ if (!this.isIframeStarted) {
+ var tag = document.createElement('script');
+ tag.src = "http://www.youtube.com/player_api";
+ var firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+ this.isIframeStarted = true;
+ }
+ },
+ iframeQueue: [],
+ enqueueIframe: function(yt) {
+
+ if (this.isLoaded) {
+ this.createIframe(yt);
+ } else {
+ this.loadIframeApi();
+ this.iframeQueue.push(yt);
+ }
+ },
+ createIframe: function(settings) {
+
+ var
+ pluginMediaElement = settings.pluginMediaElement,
+ player = new YT.Player(settings.containerId, {
+ height: settings.height,
+ width: settings.width,
+ videoId: settings.videoId,
+ playerVars: {controls:0},
+ events: {
+ 'onReady': function() {
+
+ // hook up iframe object to MEjs
+ settings.pluginMediaElement.pluginApi = player;
+
+ // init mejs
+ mejs.MediaPluginBridge.initPlugin(settings.pluginId);
+
+ // create timer
+ setInterval(function() {
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'timeupdate');
+ }, 250);
+ },
+ 'onStateChange': function(e) {
+
+ mejs.YouTubeApi.handleStateChange(e.data, player, pluginMediaElement);
+
+ }
+ }
+ });
+ },
+
+ createEvent: function (player, pluginMediaElement, eventName) {
+ var obj = {
+ type: eventName,
+ target: pluginMediaElement
+ };
+
+ if (player && player.getDuration) {
+
+ // time
+ pluginMediaElement.currentTime = obj.currentTime = player.getCurrentTime();
+ pluginMediaElement.duration = obj.duration = player.getDuration();
+
+ // state
+ obj.paused = pluginMediaElement.paused;
+ obj.ended = pluginMediaElement.ended;
+
+ // sound
+ obj.muted = player.isMuted();
+ obj.volume = player.getVolume() / 100;
+
+ // progress
+ obj.bytesTotal = player.getVideoBytesTotal();
+ obj.bufferedBytes = player.getVideoBytesLoaded();
+
+ // fake the W3C buffered TimeRange
+ var bufferedTime = obj.bufferedBytes / obj.bytesTotal * obj.duration;
+
+ obj.target.buffered = obj.buffered = {
+ start: function(index) {
+ return 0;
+ },
+ end: function (index) {
+ return bufferedTime;
+ },
+ length: 1
+ };
+
+ }
+
+ // send event up the chain
+ pluginMediaElement.dispatchEvent(obj.type, obj);
+ },
+
+ iFrameReady: function() {
+
+ this.isIframeLoaded = true;
+
+ while (this.iframeQueue.length > 0) {
+ var settings = this.iframeQueue.pop();
+ this.createIframe(settings);
+ }
+ },
+
+ // FLASH!
+ flashPlayers: {},
+ createFlash: function(settings) {
+
+ this.flashPlayers[settings.pluginId] = settings;
+
+ /*
+ settings.container.innerHTML =
+ '<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="//www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=' + settings.pluginId + '&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0" ' +
+ 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; ">' +
+ '<param name="allowScriptAccess" value="always">' +
+ '<param name="wmode" value="transparent">' +
+ '</object>';
+ */
+
+ var specialIEContainer,
+ youtubeUrl = 'http://www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=' + settings.pluginId + '&amp;version=3&amp;autoplay=0&amp;controls=0&amp;modestbranding=1&loop=0';
+
+ if (mejs.MediaFeatures.isIE) {
+
+ specialIEContainer = document.createElement('div');
+ settings.container.appendChild(specialIEContainer);
+ specialIEContainer.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" ' +
+'id="' + settings.pluginId + '" width="' + settings.width + '" height="' + settings.height + '">' +
+ '<param name="movie" value="' + youtubeUrl + '" />' +
+ '<param name="wmode" value="transparent" />' +
+ '<param name="allowScriptAccess" value="always" />' +
+ '<param name="allowFullScreen" value="true" />' +
+'</object>';
+ } else {
+ settings.container.innerHTML =
+ '<object type="application/x-shockwave-flash" id="' + settings.pluginId + '" data="' + youtubeUrl + '" ' +
+ 'width="' + settings.width + '" height="' + settings.height + '" style="visibility: visible; ">' +
+ '<param name="allowScriptAccess" value="always">' +
+ '<param name="wmode" value="transparent">' +
+ '</object>';
+ }
+
+ },
+
+ flashReady: function(id) {
+ var
+ settings = this.flashPlayers[id],
+ player = document.getElementById(id),
+ pluginMediaElement = settings.pluginMediaElement;
+
+ // hook up and return to MediaELementPlayer.success
+ pluginMediaElement.pluginApi =
+ pluginMediaElement.pluginElement = player;
+ mejs.MediaPluginBridge.initPlugin(id);
+
+ // load the youtube video
+ player.cueVideoById(settings.videoId);
+
+ var callbackName = settings.containerId + '_callback'
+
+ window[callbackName] = function(e) {
+ mejs.YouTubeApi.handleStateChange(e, player, pluginMediaElement);
+ }
+
+ player.addEventListener('onStateChange', callbackName);
+
+ setInterval(function() {
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'timeupdate');
+ }, 250);
+ },
+
+ handleStateChange: function(youTubeState, player, pluginMediaElement) {
+ switch (youTubeState) {
+ case -1: // not started
+ pluginMediaElement.paused = true;
+ pluginMediaElement.ended = true;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'loadedmetadata');
+ //createYouTubeEvent(player, pluginMediaElement, 'loadeddata');
+ break;
+ case 0:
+ pluginMediaElement.paused = false;
+ pluginMediaElement.ended = true;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'ended');
+ break;
+ case 1:
+ pluginMediaElement.paused = false;
+ pluginMediaElement.ended = false;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'play');
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'playing');
+ break;
+ case 2:
+ pluginMediaElement.paused = true;
+ pluginMediaElement.ended = false;
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'pause');
+ break;
+ case 3: // buffering
+ mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'progress');
+ break;
+ case 5:
+ // cued?
+ break;
+
+ }
+
+ }
+}
+// IFRAME
+function onYouTubePlayerAPIReady() {
+ mejs.YouTubeApi.iFrameReady();
+}
+// FLASH
+function onYouTubePlayerReady(id) {
+ mejs.YouTubeApi.flashReady(id);
+}
+
window.mejs = mejs;
window.MediaElement = mejs.MediaElement;
View
3,184 app/assets/javascripts/mediaelement_rails/mediaelementplayer.js 100644 → 100755
1,798 additions, 1,386 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN app/assets/plugins/mediaelement_rails/flashmediaelement.swf 100644 → 100755
Binary file not shown.
View
0 app/assets/plugins/mediaelement_rails/silverlightmediaelement.xap 100644 → 100755
File mode changed.
View
94 app/assets/stylesheets/mediaelement_rails/mediaelementplayer.css.erb
@@ -4,6 +4,10 @@
font-family: Helvetica, Arial;
}
+.me-plugin {
+ position: absolute;
+}
+
.mejs-embed, .mejs-embed body {
width: 100%;
height: 100%;
@@ -46,6 +50,12 @@
top: 0;
left: 0;
}
+.mejs-poster img {
+ border: 0;
+ padding: 0;
+ border: 0;
+ display: block;
+}
.mejs-overlay {
position: absolute;
top: 0;
@@ -61,7 +71,7 @@
width: 100px;
height: 100px;
margin: -50px 0 0 -50px;
- background: url(<%= asset_path "mediaelement_rails/bigplay.png" %>) top left no-repeat;
+ background: url(<%= asset_path "mediaelement_rails/bigplay.png" %>) no-repeat;
}
.mejs-overlay:hover .mejs-overlay-button{
background-position: 0 -100px ;
@@ -76,15 +86,18 @@
background: #333;
background: url(<%= asset_path "mediaelement_rails/background.png" %>);
background: rgba(0, 0, 0, 0.9);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(50,50,50,0.9)), to(rgba(0,0,0,0.9)));
- background: -moz-linear-gradient(top, rgba(50,50,50,0.9), rgba(0,0,0,0.9));
- background: linear-gradient(rgba(50,50,50,0.9), rgba(0,0,0,0.9));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(50,50,50,0.9)), to(rgba(0,0,0,0.9)));
+ background: -webkit-linear-gradient(top, rgba(50,50,50,0.9), rgba(0,0,0,0.9));
+ background: -moz-linear-gradient(top, rgba(50,50,50,0.9), rgba(0,0,0,0.9));
+ background: -o-linear-gradient(top, rgba(50,50,50,0.9), rgba(0,0,0,0.9));
+ background: -ms-linear-gradient(top, rgba(50,50,50,0.9), rgba(0,0,0,0.9));
+ background: linear-gradient(rgba(50,50,50,0.9), rgba(0,0,0,0.9));
}
.mejs-overlay-loading span {
display:block;
width: 80px;
height: 80px;
- background: transparent url(<%= asset_path "mediaelement_rails/loading.gif" %>) center center no-repeat;
+ background: transparent url(<%= asset_path "mediaelement_rails/loading.gif" %>) 50% 50% no-repeat;
}
/* End: LAYERS */
@@ -100,9 +113,12 @@
left: 0;
background: url(<%= asset_path "mediaelement_rails/background.png" %>);
background: rgba(0, 0, 0, 0.7);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(50,50,50,0.7)), to(rgba(0,0,0,0.7)));
- background: -moz-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
- background: linear-gradient(rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(50,50,50,0.7)), to(rgba(0,0,0,0.7)));
+ background: -webkit-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -moz-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -o-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -ms-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: linear-gradient(rgba(50,50,50,0.7), rgba(0,0,0,0.7));
height: 30px;
width: 100%;
}
@@ -125,7 +141,7 @@
.mejs-controls .mejs-button button {
cursor: pointer;
display: block;
- font-size: 0px;
+ font-size: 0;
line-height: 0;
text-decoration: none;
margin: 7px 5px;
@@ -134,7 +150,7 @@
height: 16px;
width: 16px;
border: 0;
- background: transparent url(<%= asset_path "mediaelement_rails/controls.png" %>) 0 0 no-repeat;
+ background: transparent url(<%= asset_path "mediaelement_rails/controls.png" %>) no-repeat;
}
/* :focus for accessibility */
@@ -202,26 +218,36 @@
margin: 5px;
background: #333;
background: rgba(50,50,50,0.8);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(30,30,30,0.8)), to(rgba(60,60,60,0.8)));
- background: -moz-linear-gradient(top, rgba(30,30,30,0.8), rgba(60,60,60,0.8));
- background: linear-gradient(rgba(30,30,30,0.8), rgba(60,60,60,0.8));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(30,30,30,0.8)), to(rgba(60,60,60,0.8)));
+ background: -webkit-linear-gradient(top, rgba(30,30,30,0.8), rgba(60,60,60,0.8));
+ background: -moz-linear-gradient(top, rgba(30,30,30,0.8), rgba(60,60,60,0.8));
+ background: -o-linear-gradient(top, rgba(30,30,30,0.8), rgba(60,60,60,0.8));
+ background: -ms-linear-gradient(top, rgba(30,30,30,0.8), rgba(60,60,60,0.8));
+ background: linear-gradient(rgba(30,30,30,0.8), rgba(60,60,60,0.8));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr=#1E1E1E,endColorstr=#3C3C3C);
}
.mejs-controls .mejs-time-rail .mejs-time-loaded {
background: #3caac8;
background: rgba(60,170,200,0.8);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(44,124,145,0.8)), to(rgba(78,183,212,0.8)));
- background: -moz-linear-gradient(top, rgba(44,124,145,0.8), rgba(78,183,212,0.8));
- background: linear-gradient(rgba(44,124,145,0.8), rgba(78,183,212,0.8));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(44,124,145,0.8)), to(rgba(78,183,212,0.8)));
+ background: -webkit-linear-gradient(top, rgba(44,124,145,0.8), rgba(78,183,212,0.8));
+ background: -moz-linear-gradient(top, rgba(44,124,145,0.8), rgba(78,183,212,0.8));
+ background: -o-linear-gradient(top, rgba(44,124,145,0.8), rgba(78,183,212,0.8));
+ background: -ms-linear-gradient(top, rgba(44,124,145,0.8), rgba(78,183,212,0.8));
+ background: linear-gradient(rgba(44,124,145,0.8), rgba(78,183,212,0.8));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr=#2C7C91,endColorstr=#4EB7D4);
width: 0;
}
.mejs-controls .mejs-time-rail .mejs-time-current {
width: 0;
background: #fff;
background: rgba(255,255,255,0.8);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0.9)), to(rgba(200,200,200,0.8)));
- background: -moz-linear-gradient(top, rgba(255,255,255,0.9), rgba(200,200,200,0.8));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255,255,255,0.9)), to(rgba(200,200,200,0.8)));
+ background: -webkit-linear-gradient(top, rgba(255,255,255,0.9), rgba(200,200,200,0.8));
+ background: -moz-linear-gradient(top, rgba(255,255,255,0.9), rgba(200,200,200,0.8));
+ background: -o-linear-gradient(top, rgba(255,255,255,0.9), rgba(200,200,200,0.8));
+ background: -ms-linear-gradient(top, rgba(255,255,255,0.9), rgba(200,200,200,0.8));
+ background: linear-gradient(rgba(255,255,255,0.9), rgba(200,200,200,0.8));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr=#FFFFFF,endColorstr=#C8C8C8);
}
@@ -241,9 +267,8 @@
}
.mejs-controls .mejs-time-rail .mejs-time-float {
- visibility: hidden;
position: absolute;
- display: block;
+ display: none;
background: #eee;
width: 36px;
height: 17px;
@@ -253,9 +278,7 @@
text-align: center;
color: #111;
}
-.mejs-controls .mejs-time-total:hover .mejs-time-float {
- visibility: visible;
-}
+
.mejs-controls .mejs-time-rail .mejs-time-float-current {
margin: 2px;
width: 30px;
@@ -331,9 +354,9 @@
margin: 0;
}
.mejs-controls .mejs-volume-button:hover {
- -webkit-border-radius: 0 0 4px 4px ;
- -moz-border-radius: 0 0 4px 4px ;
- border-radius: 0 0 4px 4px ;
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
}
/*
.mejs-controls .mejs-volume-button:hover .mejs-volume-slider {
@@ -431,7 +454,7 @@
.mejs-controls .mejs-captions-button .mejs-captions-selector ul li input{
clear: both;
float: left;
- margin: 3px 3px 0px 5px;
+ margin: 3px 3px 0 5px;
}
.mejs-controls .mejs-captions-button .mejs-captions-selector ul li label{
width: 100px;
@@ -460,9 +483,12 @@
float: left;
background: #222;
background: rgba(0, 0, 0, 0.7);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(50,50,50,0.7)), to(rgba(0,0,0,0.7)));
- background: -moz-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
- background: linear-gradient(rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(50,50,50,0.7)), to(rgba(0,0,0,0.7)));
+ background: -webkit-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -moz-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -o-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: -ms-linear-gradient(top, rgba(50,50,50,0.7), rgba(0,0,0,0.7));
+ background: linear-gradient(rgba(50,50,50,0.7), rgba(0,0,0,0.7));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr=#323232,endColorstr=#000000);
overflow: hidden;
border: 0;
@@ -484,8 +510,12 @@
/*background: #333;*/
background: #666;
background: rgba(102,102,102, 0.7);
- background: -webkit-gradient(linear, left top, left bottom, from(rgba(102,102,102,0.7)), to(rgba(50,50,50,0.6)));
- background: -moz-linear-gradient(top, rgba(102,102,102,0.7), rgba(50,50,50,0.6));
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(102,102,102,0.7)), to(rgba(50,50,50,0.6)));
+ background: -webkit-linear-gradient(top, rgba(102,102,102,0.7), rgba(50,50,50,0.6));
+ background: -moz-linear-gradient(top, rgba(102,102,102,0.7), rgba(50,50,50,0.6));
+ background: -o-linear-gradient(top, rgba(102,102,102,0.7), rgba(50,50,50,0.6));
+ background: -ms-linear-gradient(top, rgba(102,102,102,0.7), rgba(50,50,50,0.6));
+ background: linear-gradient(rgba(102,102,102,0.7), rgba(50,50,50,0.6));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr=#666666,endColorstr=#323232);
}
.mejs-chapters .mejs-chapter .mejs-chapter-block .ch-title{
View
2 lib/mediaelement_rails/engine.rb
@@ -3,7 +3,7 @@
module MediaelementRails
class Engine < Rails::Engine
- config.after_initialize do |app|
+ initializer 'mediaelement_rails', :after => "sprockets.environment" do |app|
next unless app.assets
app.assets.register_mime_type "application/x-silverlight-app", ".xap"
end
View
2 lib/mediaelement_rails/version.rb
@@ -1,3 +1,3 @@
module MediaelementRails
- VERSION = "0.3.1"
+ VERSION = "0.3.2"
end
View
6 mediaelement_rails.gemspec
@@ -11,10 +11,10 @@ Gem::Specification.new do |s|
s.summary = %q{MediaElement.js for Rails}
s.description = %q{A MediaElement gem(engine) for Rails. Makes embedding HTML5 video easy.}
- s.add_dependency "railties", "~> 3.1"
- s.add_dependency "jquery-rails", "~> 1.0"
+ s.add_dependency "railties", ">= 3.1"
+ s.add_dependency "jquery-rails", ">= 1.0"
- s.add_development_dependency "rails", "~> 3.1"
+ s.add_development_dependency "rails", ">= 3.1"
s.add_development_dependency "i18n"
s.add_development_dependency "turn"
s.add_development_dependency "sqlite3"

0 comments on commit 533a400

Please sign in to comment.