app/assets/javascripts/mediaelement_rails/mediaelement.js in mediaelement_rails-0.8.0 vs app/assets/javascripts/mediaelement_rails/mediaelement.js in mediaelement_rails-0.8.1

- old
+ new

@@ -1,23 +1,24 @@ /*! -* MediaElement.js -* HTML5 <video> and <audio> shim and player -* http://mediaelementjs.com/ -* -* Creates a JavaScript object that mimics HTML5 MediaElement API -* for browsers that don't understand HTML5 or can't play the provided codec -* Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3 -* -* Copyright 2010-2014, John Dyer (http://j.hn) -* License: MIT -* -*/ + * + * MediaElement.js + * HTML5 <video> and <audio> shim and player + * http://mediaelementjs.com/ + * + * Creates a JavaScript object that mimics HTML5 MediaElement API + * for browsers that don't understand HTML5 or can't play the provided codec + * Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3 + * + * Copyright 2010-2014, John Dyer (http://j.hn) + * License: MIT + * + */ // Namespace var mejs = mejs || {}; // version number -mejs.version = '2.14.2'; +mejs.version = '2.16.4'; // player number (for missing, same id attr) mejs.meIndex = 0; @@ -25,11 +26,11 @@ 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/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']} + {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube', 'application/x-mpegURL']} //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!) ], youtube: [ {version: null, types: ['video/youtube', 'video/x-youtube', 'audio/youtube', 'audio/x-youtube']} ], @@ -318,10 +319,11 @@ t.isAndroid = (ua.match(/android/i) !== null); t.isBustedAndroid = (ua.match(/android 2\.[12]/) !== null); t.isBustedNativeHTTPS = (location.protocol === 'https:' && (ua.match(/android [12]\./) !== null || ua.match(/macintosh.* version.* safari/) !== null)); t.isIE = (nav.appName.toLowerCase().indexOf("microsoft") != -1 || nav.appName.toLowerCase().match(/trident/gi) !== null); t.isChrome = (ua.match(/chrome/gi) !== null); + t.isChromium = (ua.match(/chromium/gi) !== null); t.isFirefox = (ua.match(/firefox/gi) !== null); t.isWebkit = (ua.match(/webkit/gi) !== null); t.isGecko = (ua.match(/gecko/gi) !== null) && !t.isWebkit && !t.isIE; t.isOpera = (ua.match(/opera/gi) !== null); t.hasTouch = ('ontouchstart' in window); // && window.ontouchstart != null); // this breaks iOS 7 @@ -383,17 +385,17 @@ } else if (t.hasMsNativeFullScreen) { t.fullScreenEventName = 'MSFullscreenChange'; } t.isFullScreen = function() { - if (v.mozRequestFullScreen) { + if (t.hasMozNativeFullScreen) { return d.mozFullScreen; - } else if (v.webkitRequestFullScreen) { + } else if (t.hasWebkitNativeFullScreen) { return d.webkitIsFullScreen; - } else if (v.hasMsNativeFullScreen) { + } else if (t.hasMsNativeFullScreen) { return d.msFullscreenElement !== null; } } t.requestFullScreen = function(el) { @@ -649,21 +651,21 @@ } }, setVolume: function (volume) { if (this.pluginApi != null) { // same on YouTube and MEjs - if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') { + if (this.pluginType == 'youtube') { this.pluginApi.setVolume(volume * 100); } else { this.pluginApi.setVolume(volume); } this.volume = volume; } }, setMuted: function (muted) { if (this.pluginApi != null) { - if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') { + if (this.pluginType == 'youtube') { if (muted) { this.pluginApi.mute(); } else { this.pluginApi.unMute(); } @@ -678,11 +680,11 @@ // additional non-HTML5 methods setVideoSize: function (width, height) { //if (this.pluginType == 'flash' || this.pluginType == 'silverlight') { - if ( this.pluginElement.style) { + if (this.pluginElement && 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); @@ -733,11 +735,11 @@ callbacks = this.events[eventName]; if (callbacks) { args = Array.prototype.slice.call(arguments, 1); for (i = 0; i < callbacks.length; i++) { - callbacks[i].apply(null, args); + callbacks[i].apply(this, args); } } }, // end: fake events @@ -1030,10 +1032,16 @@ htmlMediaElement.canPlayType = function(type) { return (type.match(/video\/(mp4|m4v)/gi) !== null) ? 'maybe' : ''; }; } + // special case for Chromium to specify natively supported video codecs (i.e. WebM and Theora) + if (mejs.MediaFeatures.isChromium) { + htmlMediaElement.canPlayType = function(type) { + return (type.match(/video\/(webm|ogv|ogg)/gi) !== null) ? 'maybe' : ''; + }; + } // test for native playback first if (supportsMediaTag && (options.mode === 'auto' || options.mode === 'auto_plugin' || options.mode === 'native') && !(mejs.MediaFeatures.isBustedNativeHTTPS && options.httpsBasicAuthSite === true)) { if (!isMediaTag) { @@ -1047,11 +1055,11 @@ result.htmlMediaElement = htmlMediaElement = dummy; } for (i=0; i<mediaFiles.length; i++) { // normal check - if (htmlMediaElement.canPlayType(mediaFiles[i].type).replace(/no/, '') !== '' + if (mediaFiles[i].type == "video/m3u8" || htmlMediaElement.canPlayType(mediaFiles[i].type).replace(/no/, '') !== '' // special case for Mac/Safari 5.0.3 which answers '' to canPlayType('audio/mp3') but 'maybe' to canPlayType('audio/mpeg') || htmlMediaElement.canPlayType(mediaFiles[i].type.replace(/mp3/,'mpeg')).replace(/no/, '') !== '' // special case for m4a supported by detecting mp4 support || htmlMediaElement.canPlayType(mediaFiles[i].type.replace(/m4a/,'mp4')).replace(/no/, '') !== '') { result.method = 'native'; @@ -1144,11 +1152,11 @@ }, getTypeFromFile: function(url) { url = url.split('?')[0]; var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase(); - return (/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext); + return (/(mp4|m4v|ogg|ogv|m3u8|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext); }, getTypeFromExtension: function(ext) { switch (ext) { @@ -1258,19 +1266,21 @@ } // flash/silverlight vars initVars = [ 'id=' + pluginid, + 'jsinitfunction=' + "mejs.MediaPluginBridge.initPlugin", + 'jscallbackfunction=' + "mejs.MediaPluginBridge.fireEvent", 'isvideo=' + ((playback.isVideo) ? "true" : "false"), 'autoplay=' + ((autoplay) ? "true" : "false"), 'preload=' + preload, 'width=' + width, 'startvolume=' + options.startVolume, 'timerrate=' + options.timerRate, 'flashstreamer=' + options.flashStreamer, 'height=' + height, - 'pseudostreamstart=' + options.pseudoStreamingStartQueryParam]; + 'pseudostreamstart=' + options.pseudoStreamingStartQueryParam]; if (playback.url !== null) { if (playback.method == 'flash') { initVars.push('file=' + mejs.Utility.encodeUrl(playback.url)); } else { @@ -1380,23 +1390,41 @@ // DEMO Code. Does NOT work. case 'vimeo': var player_id = pluginid + "_player"; pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1); - container.innerHTML ='<iframe src="//player.vimeo.com/video/' + pluginMediaElement.vimeoid + '?api=1&portrait=0&byline=0&title=0&player_id=' + player_id + '" width="' + width +'" height="' + height +'" frameborder="0" class="mejs-shim" id="' + player_id + '"></iframe>'; + container.innerHTML ='<iframe src="//player.vimeo.com/video/' + pluginMediaElement.vimeoid + '?api=1&portrait=0&byline=0&title=0&player_id=' + player_id + '" width="' + width +'" height="' + height +'" frameborder="0" class="mejs-shim" id="' + player_id + '" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; if (typeof($f) == 'function') { // froogaloop available var player = $f(container.childNodes[0]); + player.addEvent('ready', function() { + player.playVideo = function() { - player.api('play'); - }; + player.api( 'play' ); + } + player.stopVideo = function() { + player.api( 'unload' ); + } player.pauseVideo = function() { - player.api('pause'); - }; - player.seekTo = function(seconds) { - player.api('seekTo', seconds); - }; + player.api( 'pause' ); + } + player.seekTo = function( seconds ) { + player.api( 'seekTo', seconds ); + } + player.setVolume = function( volume ) { + player.api( 'setVolume', volume ); + } + player.setMuted = function( muted ) { + if( muted ) { + player.lastVolume = player.api( 'getVolume' ); + player.api( 'setVolume', 0 ); + } else { + player.api( 'setVolume', player.lastVolume ); + delete player.lastVolume; + } + } + function createEvent(player, pluginMediaElement, eventName, e) { var obj = { type: eventName, target: pluginMediaElement }; @@ -1404,29 +1432,33 @@ pluginMediaElement.currentTime = obj.currentTime = e.seconds; pluginMediaElement.duration = obj.duration = e.duration; } pluginMediaElement.dispatchEvent(obj.type, obj); } + player.addEvent('play', function() { createEvent(player, pluginMediaElement, 'play'); createEvent(player, pluginMediaElement, 'playing'); }); + player.addEvent('pause', function() { createEvent(player, pluginMediaElement, 'pause'); }); player.addEvent('finish', function() { createEvent(player, pluginMediaElement, 'ended'); }); + player.addEvent('playProgress', function(e) { createEvent(player, pluginMediaElement, 'timeupdate', e); }); + + pluginMediaElement.pluginElement = container; pluginMediaElement.pluginApi = player; // init mejs mejs.MediaPluginBridge.initPlugin(pluginid); - }); } else { console.warn("You need to include froogaloop for vimeo to work"); } @@ -1666,10 +1698,12 @@ player.addEventListener('onStateChange', callbackName); setInterval(function() { mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'timeupdate'); }, 250); + + mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'canplay'); }, handleStateChange: function(youTubeState, player, pluginMediaElement) { switch (youTubeState) { case -1: // not started @@ -1715,24 +1749,25 @@ } window.mejs = mejs; window.MediaElement = mejs.MediaElement; -/*! +/* * Adds Internationalization and localization to mediaelement. * - * This file does not contain translations, you have to add the manually. - * The schema is always the same: me-i18n-locale-[ISO_639-1 Code].js + * This file does not contain translations, you have to add them manually. + * The schema is always the same: me-i18n-locale-[IETF-language-tag].js * * Examples are provided both for german and chinese translation. * * * What is the concept beyond i18n? * http://en.wikipedia.org/wiki/Internationalization_and_localization * * What langcode should i use? - * http://en.wikipedia.org/wiki/ISO_639-1 + * http://en.wikipedia.org/wiki/IETF_language_tag + * https://tools.ietf.org/html/rfc5646 * * * License? * * The i18n file uses methods from the Drupal project (drupal.js): @@ -1754,27 +1789,35 @@ * - exports - CommonJS, window .. * */ ;(function(context, exports, undefined) { "use strict"; + var i18n = { "locale": { - "language" : '', - "strings" : {} + // Ensure previous values aren't overwritten. + "language" : (exports.i18n && exports.i18n.locale.language) || '', + "strings" : (exports.i18n && exports.i18n.locale.strings) || {} }, + "ietf_lang_regex" : /^(x\-)?[a-z]{2,}(\-\w{2,})?(\-\w{2,})?$/, "methods" : {} }; // start i18n /** * Get language, fallback to browser's language if empty + * + * IETF: RFC 5646, https://tools.ietf.org/html/rfc5646 + * Examples: en, zh-CN, cmn-Hans-CN, sr-Latn-RS, es-419, x-private */ i18n.getLanguage = function () { var language = i18n.locale.language || window.navigator.userLanguage || window.navigator.language; - // convert to iso 639-1 (2-letters, lower case) - return language.substr(0, 2).toLowerCase(); + return i18n.ietf_lang_regex.exec(language) ? language : null; + + //(WAS: convert to iso 639-1 (2-letters, lower case)) + //return language.substr(0, 2).toLowerCase(); }; // i18n fixes for compatibility with WordPress if ( typeof mejsL10n != 'undefined' ) { i18n.locale.language = mejsL10n.language; @@ -1868,63 +1911,5 @@ if ( typeof mejsL10n != 'undefined' ) { exports[mejsL10n.language] = mejsL10n.strings; } }(mejs.i18n.locale.strings)); - -/*! - * This is a i18n.locale language object. - * - * German translation by Tim Latz, latz.tim@gmail.com - * - * @author - * Tim Latz (latz.tim@gmail.com) - * - * @see - * me-i18n.js - * - * @params - * - exports - CommonJS, window .. - */ -;(function(exports, undefined) { - - "use strict"; - - if (typeof exports.de === 'undefined') { - exports.de = { - "Fullscreen" : "Vollbild", - "Go Fullscreen" : "Vollbild an", - "Turn off Fullscreen" : "Vollbild aus", - "Close" : "Schließen" - }; - } - -}(mejs.i18n.locale.strings)); -/*! - * This is a i18n.locale language object. - * - * Traditional chinese translation by Tim Latz, latz.tim@gmail.com - * - * @author - * Tim Latz (latz.tim@gmail.com) - * - * @see - * me-i18n.js - * - * @params - * - exports - CommonJS, window .. - */ -;(function(exports, undefined) { - - "use strict"; - - if (typeof exports.zh === 'undefined') { - exports.zh = { - "Fullscreen" : "全螢幕", - "Go Fullscreen" : "全屏模式", - "Turn off Fullscreen" : "退出全屏模式", - "Close" : "關閉" - }; - } - -}(mejs.i18n.locale.strings)); -