└── 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 = $(''); 331 | 332 | // swfobject v2+ 333 | if (window.swfobject) { 334 | $(el).after($div).appendTo($div); 335 | if (!el.id) el.id = 'movie_player_' + counter++; 336 | 337 | // replace el with swfobject content 338 | window.swfobject.embedSWF(opts.src, el.id, opts.width, opts.height, opts.flashVersion, 339 | opts.expressInstaller, opts.flashvars, opts.params, opts.attrs); 340 | } 341 | // swfobject < v2 342 | else { 343 | $(el).after($div).remove(); 344 | var so = new SWFObject(opts.src, 'movie_player_' + counter++, opts.width, opts.height, opts.flashVersion, opts.bgColor); 345 | if (opts.expressInstaller) so.useExpressInstall(opts.expressInstaller); 346 | 347 | for (p in opts.params) 348 | if (p != 'bgColor') so.addParam(p, opts.params[p]); 349 | for (f in opts.flashvars) 350 | so.addVariable(f, opts.flashvars[f]); 351 | so.write($div[0]); 352 | } 353 | 354 | if (opts.caption) $('
').appendTo($div).html(opts.caption); 355 | return $div; 356 | }; 357 | 358 | // map flv and mp3 files to the swf player by default 359 | $.fn.media.flv = $.fn.media.mp3 = function(el, opts) { 360 | var src = opts.src; 361 | var player = /\.mp3\b/i.test(src) ? opts.mp3Player : opts.flvPlayer; 362 | var key = opts.flvKeyName; 363 | src = encodeURIComponent(src); 364 | opts.src = player; 365 | opts.src = opts.src + '?'+key+'=' + (src); 366 | var srcObj = {}; 367 | srcObj[key] = src; 368 | opts.flashvars = $.extend({}, srcObj, opts.flashvars ); 369 | return $.fn.media.swf(el, opts); 370 | }; 371 | 372 | // 373 | // Silverlight 374 | // 375 | $.fn.media.xaml = function(el, opts) { 376 | if (!window.Sys || !window.Sys.Silverlight) { 377 | if ($.fn.media.xaml.warning) return; 378 | $.fn.media.xaml.warning = 1; 379 | alert('You must include the Silverlight.js script.'); 380 | return; 381 | } 382 | 383 | var props = { 384 | width: opts.width, 385 | height: opts.height, 386 | background: opts.bgColor, 387 | inplaceInstallPrompt: opts.silverlight.inplaceInstallPrompt, 388 | isWindowless: opts.silverlight.isWindowless, 389 | framerate: opts.silverlight.framerate, 390 | version: opts.silverlight.version 391 | }; 392 | var events = { 393 | onError: opts.silverlight.onError, 394 | onLoad: opts.silverlight.onLoad 395 | }; 396 | 397 | var id1 = el.id ? (' id="'+el.id+'"') : ''; 398 | var id2 = opts.id || 'AG' + counter++; 399 | // convert element to div 400 | var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 401 | var $div = $(''); 402 | $(el).after($div).remove(); 403 | 404 | Sys.Silverlight.createObjectEx({ 405 | source: opts.src, 406 | initParams: opts.silverlight.initParams, 407 | userContext: opts.silverlight.userContext, 408 | id: id2, 409 | parentElement: $div[0], 410 | properties: props, 411 | events: events 412 | }); 413 | 414 | if (opts.caption) $('
').appendTo($div).html(opts.caption); 415 | return $div; 416 | }; 417 | 418 | // 419 | // generate object/embed markup 420 | // 421 | function generate(el, opts, player) { 422 | var $el = $(el); 423 | var o = $.fn.media.defaults.players[player]; 424 | var a, key, v; 425 | 426 | if (player == 'iframe') { 427 | o = $(''); 428 | o.attr('src', opts.src); 429 | o.css('backgroundColor', o.bgColor); 430 | } 431 | else if (player == 'img') { 432 | o = $(''); 433 | o.attr('src', opts.src); 434 | if (opts.width) 435 | o.attr('width', opts.width); 436 | if (opts.height) 437 | o.attr('height', opts.height); 438 | o.css('backgroundColor', o.bgColor); 439 | } 440 | else if (lameIE) { 441 | a = [''); 451 | var p = ['']; 452 | for (key in opts.params) 453 | p.push(''); 454 | o = document.createElement(a.join('')); 455 | for (var i=0; i < p.length; i++) 456 | o.appendChild(document.createElement(p[i])); 457 | } 458 | else if (opts.standards) { 459 | // Rewritten to be standards compliant by Richard Connamacher 460 | a = [''); 471 | a.push(''); 472 | for (key in opts.params) { 473 | if (key == 'wmode' && player != 'flash') // FF3/Quicktime borks on wmode 474 | continue; 475 | a.push(''); 476 | } 477 | // Alternate HTML 478 | a.push('

'+o.title+' Required

'+o.title+' is required to view this media. Download Here.

'); 479 | a.push(''); 480 | } 481 | else { 482 | a = [''); 494 | } 495 | // convert element to div 496 | var id = el.id ? (' id="'+el.id+'"') : ''; 497 | var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 498 | var $div = $(''); 499 | $el.after($div).remove(); 500 | if (lameIE || player == 'iframe' || player == 'img') 501 | $div.append(o); 502 | else 503 | $div.html(a.join('')); 504 | 505 | if (opts.caption) 506 | $('
').appendTo($div).html(opts.caption); 507 | return $div; 508 | } 509 | 510 | 511 | })(jQuery); 512 | --------------------------------------------------------------------------------