└── jquery.media.js /jquery.media.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Media Plugin for converting elements into rich media content. 3 | * 4 | * Examples and documentation at: http://malsup.com/jquery/media/ 5 | * Copyright (c) 2007-2010 M. Alsup 6 | * Dual licensed under the MIT and GPL licenses: 7 | * http://www.opensource.org/licenses/mit-license.php 8 | * http://www.gnu.org/licenses/gpl.html 9 | * 10 | * @author: M. Alsup 11 | * @version: 0.99 (05-JUN-2013) 12 | * @requires jQuery v1.1.2 or later 13 | * $Id: jquery.media.js 2460 2007-07-23 02:53:15Z malsup $ 14 | * 15 | * Supported Media Players: 16 | * - Flash 17 | * - Quicktime 18 | * - Real Player 19 | * - Silverlight 20 | * - Windows Media Player 21 | * - iframe 22 | * 23 | * Supported Media Formats: 24 | * Any types supported by the above players, such as: 25 | * Video: asf, avi, flv, mov, mpg, mpeg, mp4, qt, smil, swf, wmv, 3g2, 3gp 26 | * Audio: aif, aac, au, gsm, mid, midi, mov, mp3, m4a, snd, rm, wav, wma 27 | * Other: bmp, html, pdf, psd, qif, qtif, qti, tif, tiff, xaml 28 | * 29 | * Thanks to Mark Hicken and Brent Pedersen for helping me debug this on the Mac! 30 | * Thanks to Dan Rossi for numerous bug reports and code bits! 31 | * Thanks to Skye Giordano for several great suggestions! 32 | * Thanks to Richard Connamacher for excellent improvements to the non-IE behavior! 33 | */ 34 | /*global SWFObject alert Sys */ 35 | /*jshint forin:false */ 36 | ;(function($) { 37 | "use strict"; 38 | 39 | var mode = document.documentMode || 0; 40 | var msie = /MSIE/.test(navigator.userAgent); 41 | var lameIE = msie && (/MSIE (6|7|8)\.0/.test(navigator.userAgent) || mode < 9); 42 | 43 | /** 44 | * Chainable method for converting elements into rich media. 45 | * 46 | * @param options 47 | * @param callback fn invoked for each matched element before conversion 48 | * @param callback fn invoked for each matched element after conversion 49 | */ 50 | $.fn.media = function(options, f1, f2) { 51 | if (options == 'undo') { 52 | return this.each(function() { 53 | var $this = $(this); 54 | var html = $this.data('media.origHTML'); 55 | if (html) 56 | $this.replaceWith(html); 57 | }); 58 | } 59 | 60 | return this.each(function() { 61 | if (typeof options == 'function') { 62 | f2 = f1; 63 | f1 = options; 64 | options = {}; 65 | } 66 | var o = getSettings(this, options); 67 | // pre-conversion callback, passes original element and fully populated options 68 | if (typeof f1 == 'function') f1(this, o); 69 | 70 | var r = getTypesRegExp(); 71 | var m = r.exec(o.src.toLowerCase()) || ['']; 72 | var fn; 73 | 74 | if (o.type) 75 | m[0] = o.type; 76 | else 77 | m.shift(); 78 | 79 | for (var i=0; i < m.length; i++) { 80 | fn = m[i].toLowerCase(); 81 | if (isDigit(fn[0])) fn = 'fn' + fn; // fns can't begin with numbers 82 | if (!$.fn.media[fn]) 83 | continue; // unrecognized media type 84 | // normalize autoplay settings 85 | var player = $.fn.media[fn+'_player']; 86 | if (!o.params) o.params = {}; 87 | if (player) { 88 | var num = player.autoplayAttr == 'autostart'; 89 | o.params[player.autoplayAttr || 'autoplay'] = num ? (o.autoplay ? 1 : 0) : o.autoplay ? true : false; 90 | } 91 | var $div = $.fn.media[fn](this, o); 92 | 93 | $div.css('backgroundColor', o.bgColor).width(o.width); 94 | 95 | if (o.canUndo) { 96 | var $temp = $('
').append(this); 97 | $div.data('media.origHTML', $temp.html()); // store original markup 98 | } 99 | 100 | // post-conversion callback, passes original element, new div element and fully populated options 101 | if (typeof f2 == 'function') f2(this, $div[0], o, player.name); 102 | break; 103 | } 104 | }); 105 | }; 106 | 107 | /** 108 | * Non-chainable method for adding or changing file format / player mapping 109 | * @name mapFormat 110 | * @param String format File format extension (ie: mov, wav, mp3) 111 | * @param String player Player name to use for the format (one of: flash, quicktime, realplayer, winmedia, silverlight or iframe 112 | */ 113 | $.fn.media.mapFormat = function(format, player) { 114 | if (!format || !player || !$.fn.media.defaults.players[player]) return; // invalid 115 | format = format.toLowerCase(); 116 | if (isDigit(format[0])) format = 'fn' + format; 117 | $.fn.media[format] = $.fn.media[player]; 118 | $.fn.media[format+'_player'] = $.fn.media.defaults.players[player]; 119 | }; 120 | 121 | // global defautls; override as needed 122 | $.fn.media.defaults = { 123 | standards: true, // use object tags only (no embeds for non-IE browsers) 124 | canUndo: true, // tells plugin to store the original markup so it can be reverted via: $(sel).mediaUndo() 125 | width: 400, 126 | height: 400, 127 | autoplay: 0, // normalized cross-player setting 128 | bgColor: '#ffffff', // background color 129 | params: { wmode: 'transparent'}, // added to object element as param elements; added to embed element as attrs 130 | attrs: {}, // added to object and embed elements as attrs 131 | flvKeyName: 'file', // key used for object src param (thanks to Andrea Ercolino) 132 | flashvars: {}, // added to flash content as flashvars param/attr 133 | flashVersion: '7', // required flash version 134 | expressInstaller: null, // src for express installer 135 | 136 | // default flash video and mp3 player (@see: http://jeroenwijering.com/?item=Flash_Media_Player) 137 | flvPlayer: 'mediaplayer.swf', 138 | mp3Player: 'mediaplayer.swf', 139 | 140 | // @see http://msdn2.microsoft.com/en-us/library/bb412401.aspx 141 | silverlight: { 142 | inplaceInstallPrompt: 'true', // display in-place install prompt? 143 | isWindowless: 'true', // windowless mode (false for wrapping markup) 144 | framerate: '24', // maximum framerate 145 | version: '0.9', // Silverlight version 146 | onError: null, // onError callback 147 | onLoad: null, // onLoad callback 148 | initParams: null, // object init params 149 | userContext: null // callback arg passed to the load callback 150 | } 151 | }; 152 | 153 | // Media Players; think twice before overriding 154 | $.fn.media.defaults.players = { 155 | flash: { 156 | name: 'flash', 157 | title: 'Flash', 158 | types: 'flv,mp3,swf', 159 | mimetype: 'application/x-shockwave-flash', 160 | pluginspage: 'http://www.adobe.com/go/getflashplayer', 161 | ieAttrs: { 162 | classid: 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000', 163 | type: 'application/x-oleobject', 164 | codebase: 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + $.fn.media.defaults.flashVersion 165 | } 166 | }, 167 | quicktime: { 168 | name: 'quicktime', 169 | title: 'QuickTime', 170 | mimetype: 'video/quicktime', 171 | pluginspage: 'http://www.apple.com/quicktime/download/', 172 | types: 'aif,aiff,aac,au,bmp,gsm,mov,mid,midi,mpg,mpeg,mp4,m4a,psd,qt,qtif,qif,qti,snd,tif,tiff,wav,3g2,3gp', 173 | ieAttrs: { 174 | classid: 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B', 175 | codebase: 'http://www.apple.com/qtactivex/qtplugin.cab' 176 | } 177 | }, 178 | realplayer: { 179 | name: 'real', 180 | title: 'RealPlayer', 181 | types: 'ra,ram,rm,rpm,rv,smi,smil', 182 | mimetype: 'audio/x-pn-realaudio-plugin', 183 | pluginspage: 'http://www.real.com/player/', 184 | autoplayAttr: 'autostart', 185 | ieAttrs: { 186 | classid: 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA' 187 | } 188 | }, 189 | winmedia: { 190 | name: 'winmedia', 191 | title: 'Windows Media', 192 | types: 'asx,asf,avi,wma,wmv', 193 | mimetype: isFirefoxWMPPluginInstalled() ? 'application/x-ms-wmp' : 'application/x-mplayer2', 194 | pluginspage: 'http://www.microsoft.com/Windows/MediaPlayer/', 195 | autoplayAttr: 'autostart', 196 | oUrl: 'url', 197 | ieAttrs: { 198 | classid: 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6', 199 | type: 'application/x-oleobject' 200 | } 201 | }, 202 | // special cases 203 | img: { 204 | name: 'img', 205 | title: 'Image', 206 | types: 'gif,png,jpg' 207 | }, 208 | iframe: { 209 | name: 'iframe', 210 | types: 'html,pdf' 211 | }, 212 | silverlight: { 213 | name: 'silverlight', 214 | types: 'xaml' 215 | } 216 | }; 217 | 218 | // 219 | // everything below here is private 220 | // 221 | 222 | 223 | // detection script for FF WMP plugin (http://www.therossman.org/experiments/wmp_play.html) 224 | // (hat tip to Mark Ross for this script) 225 | function isFirefoxWMPPluginInstalled() { 226 | var plugs = navigator.plugins || []; 227 | for (var i = 0; i < plugs.length; i++) { 228 | var plugin = plugs[i]; 229 | if (plugin['filename'] == 'np-mswmp.dll') 230 | return true; 231 | } 232 | return false; 233 | } 234 | 235 | var counter = 1; 236 | 237 | for (var player in $.fn.media.defaults.players) { 238 | var types = $.fn.media.defaults.players[player].types; 239 | $.each(types.split(','), function(i,o) { 240 | if (isDigit(o[0])) o = 'fn' + o; 241 | $.fn.media[o] = $.fn.media[player] = getGenerator(player); 242 | $.fn.media[o+'_player'] = $.fn.media.defaults.players[player]; 243 | }); 244 | } 245 | 246 | function getTypesRegExp() { 247 | var types = ''; 248 | for (var player in $.fn.media.defaults.players) { 249 | if (types.length) types += ','; 250 | types += $.fn.media.defaults.players[player].types; 251 | } 252 | return new RegExp('\\.(' + types.replace(/,/ig,'|') + ')\\b'); 253 | } 254 | 255 | function getGenerator(player) { 256 | return function(el, options) { 257 | return generate(el, options, player); 258 | }; 259 | } 260 | 261 | function isDigit(c) { 262 | return '0123456789'.indexOf(c) > -1; 263 | } 264 | 265 | // flatten all possible options: global defaults, meta, option obj 266 | function getSettings(el, options) { 267 | options = options || {}; 268 | var a, n; 269 | var $el = $(el); 270 | var cls = el.className || ''; 271 | // support metadata plugin (v1.0 and v2.0) 272 | var meta = $.metadata ? $el.metadata() : $.meta ? $el.data() : {}; 273 | meta = meta || {}; 274 | var w = meta.width || parseInt(((cls.match(/\bw:(\d+)/)||[])[1]||0),10) || parseInt(((cls.match(/\bwidth:(\d+)/)||[])[1]||0),10); 275 | var h = meta.height || parseInt(((cls.match(/\bh:(\d+)/)||[])[1]||0),10) || parseInt(((cls.match(/\bheight:(\d+)/)||[])[1]||0),10); 276 | 277 | if (w) meta.width = w; 278 | if (h) meta.height = h; 279 | if (cls) meta.cls = cls; 280 | 281 | // crank html5 style data attributes 282 | var dataName = 'data-'; 283 | for (var i=0; i < el.attributes.length; i++) { 284 | a = el.attributes[i], n = $.trim(a.name); 285 | var index = n.indexOf(dataName); 286 | if (index === 0) { 287 | n = n.substring(dataName.length); 288 | meta[n] = a.value; 289 | } 290 | } 291 | 292 | a = $.fn.media.defaults; 293 | var b = options; 294 | var c = meta; 295 | 296 | var p = { params: { bgColor: options.bgColor || $.fn.media.defaults.bgColor } }; 297 | var opts = $.extend({}, a, b, c); 298 | $.each(['attrs','params','flashvars','silverlight'], function(i,o) { 299 | opts[o] = $.extend({}, p[o] || {}, a[o] || {}, b[o] || {}, c[o] || {}); 300 | }); 301 | 302 | if (typeof opts.caption == 'undefined') opts.caption = $el.text(); 303 | 304 | // make sure we have a source! 305 | opts.src = opts.src || $el.attr('href') || $el.attr('src') || 'unknown'; 306 | return opts; 307 | } 308 | 309 | // 310 | // Flash Player 311 | // 312 | 313 | // generate flash using SWFObject library if possible 314 | $.fn.media.swf = function(el, opts) { 315 | var f, p; 316 | if (!window.SWFObject && !window.swfobject) { 317 | // roll our own 318 | if (opts.flashvars) { 319 | var a = []; 320 | for (f in opts.flashvars) 321 | a.push(f + '=' + opts.flashvars[f]); 322 | if (!opts.params) opts.params = {}; 323 | opts.params.flashvars = a.join('&'); 324 | } 325 | return generate(el, opts, 'flash'); 326 | } 327 | 328 | var id = el.id ? (' id="'+el.id+'"') : ''; 329 | var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 330 | var $div = $('