Changeset 863995
- Timestamp:
- 02/24/2014 11:18:42 AM (12 years ago)
- Location:
- soundslides/trunk
- Files:
-
- 2 added
- 1 deleted
- 2 edited
-
README.md (added)
-
index.html (deleted)
-
index.php (added)
-
js/Jplayer.swf (modified) (previous)
-
js/jquery.jplayer.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
soundslides/trunk/js/jquery.jplayer.js
r574407 r863995 3 3 * http://www.jplayer.org 4 4 * 5 * Copyright (c) 2009 - 2011 Happyworm Ltd 6 * Dual licensed under the MIT and GPL licenses. 7 * - http://www.opensource.org/licenses/mit-license.php 8 * - http://www.gnu.org/copyleft/gpl.html 5 * Copyright (c) 2009 - 2013 Happyworm Ltd 6 * Licensed under the MIT license. 7 * http://opensource.org/licenses/MIT 9 8 * 10 9 * Author: Mark J Panaghiston 11 * Version: 2. 1.012 * Date: 1st September 201110 * Version: 2.5.0 11 * Date: 7th November 2013 13 12 */ 14 13 15 /* Code verified using http://www.jshint.com/ */ 16 /*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, nomem:false, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false */ 17 /*global jQuery:false, ActiveXObject:false, alert:false */ 18 19 (function($, undefined) { 20 21 // Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge 22 $.fn.jPlayer = function( options ) { 23 var name = "jPlayer"; 24 var isMethodCall = typeof options === "string", 25 args = Array.prototype.slice.call( arguments, 1 ), 26 returnValue = this; 27 28 // allow multiple hashes to be passed on init 29 options = !isMethodCall && args.length ? 30 $.extend.apply( null, [ true, options ].concat(args) ) : 31 options; 32 33 // prevent calls to internal methods 34 if ( isMethodCall && options.charAt( 0 ) === "_" ) { 35 return returnValue; 36 } 37 38 if ( isMethodCall ) { 39 this.each(function() { 40 var instance = $.data( this, name ), 41 methodValue = instance && $.isFunction( instance[options] ) ? 42 instance[ options ].apply( instance, args ) : 43 instance; 44 if ( methodValue !== instance && methodValue !== undefined ) { 45 returnValue = methodValue; 46 return false; 47 } 48 }); 49 } else { 50 this.each(function() { 51 var instance = $.data( this, name ); 52 if ( instance ) { 53 // instance.option( options || {} )._init(); // Orig jquery.ui.widget.js code: Not recommend for jPlayer. ie., Applying new options to an existing instance (via the jPlayer constructor) and performing the _init(). The _init() is what concerns me. It would leave a lot of event handlers acting on jPlayer instance and the interface. 54 instance.option( options || {} ); // The new constructor only changes the options. Changing options only has basic support atm. 55 } else { 56 $.data( this, name, new $.jPlayer( options, this ) ); 57 } 58 }); 59 } 60 61 return returnValue; 62 }; 63 64 $.jPlayer = function( options, element ) { 65 // allow instantiation without initializing for simple inheritance 66 if ( arguments.length ) { 67 this.element = $(element); 68 this.options = $.extend(true, {}, 69 this.options, 70 options 71 ); 72 var self = this; 73 this.element.bind( "remove.jPlayer", function() { 74 self.destroy(); 75 }); 76 this._init(); 77 } 78 }; 79 // End of: (Adapted from jquery.ui.widget.js (1.8.7)) 80 81 // Emulated HTML5 methods and properties 82 $.jPlayer.emulateMethods = "load play pause"; 83 $.jPlayer.emulateStatus = "src readyState networkState currentTime duration paused ended playbackRate"; 84 $.jPlayer.emulateOptions = "muted volume"; 85 86 // Reserved event names generated by jPlayer that are not part of the HTML5 Media element spec 87 $.jPlayer.reservedEvent = "ready flashreset resize repeat error warning"; 88 89 // Events generated by jPlayer 90 $.jPlayer.event = { 91 ready: "jPlayer_ready", 92 flashreset: "jPlayer_flashreset", // Similar to the ready event if the Flash solution is set to display:none and then shown again or if it's reloaded for another reason by the browser. For example, using CSS position:fixed on Firefox for the full screen feature. 93 resize: "jPlayer_resize", // Occurs when the size changes through a full/restore screen operation or if the size/sizeFull options are changed. 94 repeat: "jPlayer_repeat", // Occurs when the repeat status changes. Usually through clicks on the repeat button of the interface. 95 click: "jPlayer_click", // Occurs when the user clicks on one of the following: poster image, html video, flash video. 96 error: "jPlayer_error", // Event error code in event.jPlayer.error.type. See $.jPlayer.error 97 warning: "jPlayer_warning", // Event warning code in event.jPlayer.warning.type. See $.jPlayer.warning 98 99 // Other events match HTML5 spec. 100 loadstart: "jPlayer_loadstart", 101 progress: "jPlayer_progress", 102 suspend: "jPlayer_suspend", 103 abort: "jPlayer_abort", 104 emptied: "jPlayer_emptied", 105 stalled: "jPlayer_stalled", 106 play: "jPlayer_play", 107 pause: "jPlayer_pause", 108 loadedmetadata: "jPlayer_loadedmetadata", 109 loadeddata: "jPlayer_loadeddata", 110 waiting: "jPlayer_waiting", 111 playing: "jPlayer_playing", 112 canplay: "jPlayer_canplay", 113 canplaythrough: "jPlayer_canplaythrough", 114 seeking: "jPlayer_seeking", 115 seeked: "jPlayer_seeked", 116 timeupdate: "jPlayer_timeupdate", 117 ended: "jPlayer_ended", 118 ratechange: "jPlayer_ratechange", 119 durationchange: "jPlayer_durationchange", 120 volumechange: "jPlayer_volumechange" 121 }; 122 123 $.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPlayer event, without any internal action. 124 "loadstart", 125 // "progress", // jPlayer uses internally before bubbling. 126 // "suspend", // jPlayer uses internally before bubbling. 127 "abort", 128 // "error", // jPlayer uses internally before bubbling. 129 "emptied", 130 "stalled", 131 // "play", // jPlayer uses internally before bubbling. 132 // "pause", // jPlayer uses internally before bubbling. 133 "loadedmetadata", 134 "loadeddata", 135 // "waiting", // jPlayer uses internally before bubbling. 136 // "playing", // jPlayer uses internally before bubbling. 137 "canplay", 138 "canplaythrough", 139 // "seeking", // jPlayer uses internally before bubbling. 140 // "seeked", // jPlayer uses internally before bubbling. 141 // "timeupdate", // jPlayer uses internally before bubbling. 142 // "ended", // jPlayer uses internally before bubbling. 143 "ratechange" 144 // "durationchange" // jPlayer uses internally before bubbling. 145 // "volumechange" // jPlayer uses internally before bubbling. 146 ]; 147 148 $.jPlayer.pause = function() { 149 $.each($.jPlayer.prototype.instances, function(i, element) { 150 if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. 151 element.jPlayer("pause"); 152 } 153 }); 154 }; 155 156 $.jPlayer.timeFormat = { 157 showHour: false, 158 showMin: true, 159 showSec: true, 160 padHour: false, 161 padMin: true, 162 padSec: true, 163 sepHour: ":", 164 sepMin: ":", 165 sepSec: "" 166 }; 167 168 $.jPlayer.convertTime = function(s) { 169 var myTime = new Date(s * 1000); 170 var hour = myTime.getUTCHours(); 171 var min = myTime.getUTCMinutes(); 172 var sec = myTime.getUTCSeconds(); 173 var strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour : hour; 174 var strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min; 175 var strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec; 176 return (($.jPlayer.timeFormat.showHour) ? strHour + $.jPlayer.timeFormat.sepHour : "") + (($.jPlayer.timeFormat.showMin) ? strMin + $.jPlayer.timeFormat.sepMin : "") + (($.jPlayer.timeFormat.showSec) ? strSec + $.jPlayer.timeFormat.sepSec : ""); 177 }; 178 179 // Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.2 does not detect Chrome as webkit. 180 $.jPlayer.uaBrowser = function( userAgent ) { 181 var ua = userAgent.toLowerCase(); 182 183 // Useragent RegExp 184 var rwebkit = /(webkit)[ \/]([\w.]+)/; 185 var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/; 186 var rmsie = /(msie) ([\w.]+)/; 187 var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/; 188 189 var match = rwebkit.exec( ua ) || 190 ropera.exec( ua ) || 191 rmsie.exec( ua ) || 192 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 193 []; 194 195 return { browser: match[1] || "", version: match[2] || "0" }; 196 }; 197 198 // Platform sniffer for detecting mobile devices 199 $.jPlayer.uaPlatform = function( userAgent ) { 200 var ua = userAgent.toLowerCase(); 201 202 // Useragent RegExp 203 var rplatform = /(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/; 204 var rtablet = /(ipad|playbook)/; 205 var randroid = /(android)/; 206 var rmobile = /(mobile)/; 207 208 var platform = rplatform.exec( ua ) || []; 209 var tablet = rtablet.exec( ua ) || 210 !rmobile.exec( ua ) && randroid.exec( ua ) || 211 []; 212 213 if(platform[1]) { 214 platform[1] = platform[1].replace(/\s/g, "_"); // Change whitespace to underscore. Enables dot notation. 215 } 216 217 return { platform: platform[1] || "", tablet: tablet[1] || "" }; 218 }; 219 220 $.jPlayer.browser = { 221 }; 222 $.jPlayer.platform = { 223 }; 224 225 var browserMatch = $.jPlayer.uaBrowser(navigator.userAgent); 226 if ( browserMatch.browser ) { 227 $.jPlayer.browser[ browserMatch.browser ] = true; 228 $.jPlayer.browser.version = browserMatch.version; 229 } 230 var platformMatch = $.jPlayer.uaPlatform(navigator.userAgent); 231 if ( platformMatch.platform ) { 232 $.jPlayer.platform[ platformMatch.platform ] = true; 233 $.jPlayer.platform.mobile = !platformMatch.tablet; 234 $.jPlayer.platform.tablet = !!platformMatch.tablet; 235 } 236 237 $.jPlayer.prototype = { 238 count: 0, // Static Variable: Change it via prototype. 239 version: { // Static Object 240 script: "2.1.0", 241 needFlash: "2.1.0", 242 flash: "unknown" 243 }, 244 options: { // Instanced in $.jPlayer() constructor 245 swfPath: "js", // Path to Jplayer.swf. Can be relative, absolute or server root relative. 246 solution: "html, flash", // Valid solutions: html, flash. Order defines priority. 1st is highest, 247 supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest, 248 preload: 'metadata', // HTML5 Spec values: none, metadata, auto. 249 volume: 0.8, // The volume. Number 0 to 1. 250 muted: false, 251 wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu. 252 backgroundColor: "#000000", // To define the jPlayer div and Flash background color. 253 cssSelectorAncestor: "#jp_container_1", 254 cssSelector: { // * denotes properties that should only be required when video media type required. _cssSelector() would require changes to enable splitting these into Audio and Video defaults. 255 videoPlay: ".jp-video-play", // * 256 play: ".jp-play", 257 pause: ".jp-pause", 258 stop: ".jp-stop", 259 seekBar: ".jp-seek-bar", 260 playBar: ".jp-play-bar", 261 mute: ".jp-mute", 262 unmute: ".jp-unmute", 263 volumeBar: ".jp-volume-bar", 264 volumeBarValue: ".jp-volume-bar-value", 265 volumeMax: ".jp-volume-max", 266 currentTime: ".jp-current-time", 267 duration: ".jp-duration", 268 fullScreen: ".jp-full-screen", // * 269 restoreScreen: ".jp-restore-screen", // * 270 repeat: ".jp-repeat", 271 repeatOff: ".jp-repeat-off", 272 gui: ".jp-gui", // The interface used with autohide feature. 273 noSolution: ".jp-no-solution" // For error feedback when jPlayer cannot find a solution. 274 }, 275 fullScreen: false, 276 autohide: { 277 restored: false, // Controls the interface autohide feature. 278 full: true, // Controls the interface autohide feature. 279 fadeIn: 200, // Milliseconds. The period of the fadeIn anim. 280 fadeOut: 600, // Milliseconds. The period of the fadeOut anim. 281 hold: 1000 // Milliseconds. The period of the pause before autohide beings. 282 }, 283 loop: false, 284 repeat: function(event) { // The default jPlayer repeat event handler 285 if(event.jPlayer.options.loop) { 286 $(this).unbind(".jPlayerRepeat").bind($.jPlayer.event.ended + ".jPlayer.jPlayerRepeat", function() { 287 $(this).jPlayer("play"); 288 }); 289 } else { 290 $(this).unbind(".jPlayerRepeat"); 291 } 292 }, 293 nativeVideoControls: { 294 // Works well on standard browsers. 295 // Phone and tablet browsers can have problems with the controls disappearing. 296 }, 297 noFullScreen: { 298 msie: /msie [0-6]/, 299 ipad: /ipad.*?os [0-4]/, 300 iphone: /iphone/, 301 ipod: /ipod/, 302 android_pad: /android [0-3](?!.*?mobile)/, 303 android_phone: /android.*?mobile/, 304 blackberry: /blackberry/, 305 windows_ce: /windows ce/, 306 webos: /webos/ 307 }, 308 noVolume: { 309 ipad: /ipad/, 310 iphone: /iphone/, 311 ipod: /ipod/, 312 android_pad: /android(?!.*?mobile)/, 313 android_phone: /android.*?mobile/, 314 blackberry: /blackberry/, 315 windows_ce: /windows ce/, 316 webos: /webos/, 317 playbook: /playbook/ 318 }, 319 verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height. 320 // globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances 321 // globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances 322 idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ 323 noConflict: "jQuery", 324 emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element. 325 errorAlerts: false, 326 warningAlerts: false 327 }, 328 optionsAudio: { 329 size: { 330 width: "0px", 331 height: "0px", 332 cssClass: "" 333 }, 334 sizeFull: { 335 width: "0px", 336 height: "0px", 337 cssClass: "" 338 } 339 }, 340 optionsVideo: { 341 size: { 342 width: "480px", 343 height: "270px", 344 cssClass: "jp-video-270p" 345 }, 346 sizeFull: { 347 width: "100%", 348 height: "100%", 349 cssClass: "jp-video-full" 350 } 351 }, 352 instances: {}, // Static Object 353 status: { // Instanced in _init() 354 src: "", 355 media: {}, 356 paused: true, 357 format: {}, 358 formatType: "", 359 waitForPlay: true, // Same as waitForLoad except in case where preloading. 360 waitForLoad: true, 361 srcSet: false, 362 video: false, // True if playing a video 363 seekPercent: 0, 364 currentPercentRelative: 0, 365 currentPercentAbsolute: 0, 366 currentTime: 0, 367 duration: 0, 368 readyState: 0, 369 networkState: 0, 370 playbackRate: 1, 371 ended: 0 372 373 /* Persistant status properties created dynamically at _init(): 374 width 375 height 376 cssClass 377 nativeVideoControls 378 noFullScreen 379 noVolume 380 */ 381 }, 382 383 internal: { // Instanced in _init() 384 ready: false 385 // instance: undefined 386 // domNode: undefined 387 // htmlDlyCmdId: undefined 388 // autohideId: undefined 389 }, 390 solution: { // Static Object: Defines the solutions built in jPlayer. 391 html: true, 392 flash: true 393 }, 394 // 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"') 395 format: { // Static Object 396 mp3: { 397 codec: 'audio/mpeg; codecs="mp3"', 398 flashCanPlay: true, 399 media: 'audio' 400 }, 401 m4a: { // AAC / MP4 402 codec: 'audio/mp4; codecs="mp4a.40.2"', 403 flashCanPlay: true, 404 media: 'audio' 405 }, 406 oga: { // OGG 407 codec: 'audio/ogg; codecs="vorbis"', 408 flashCanPlay: false, 409 media: 'audio' 410 }, 411 wav: { // PCM 412 codec: 'audio/wav; codecs="1"', 413 flashCanPlay: false, 414 media: 'audio' 415 }, 416 webma: { // WEBM 417 codec: 'audio/webm; codecs="vorbis"', 418 flashCanPlay: false, 419 media: 'audio' 420 }, 421 fla: { // FLV / F4A 422 codec: 'audio/x-flv', 423 flashCanPlay: true, 424 media: 'audio' 425 }, 426 m4v: { // H.264 / MP4 427 codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', 428 flashCanPlay: true, 429 media: 'video' 430 }, 431 ogv: { // OGG 432 codec: 'video/ogg; codecs="theora, vorbis"', 433 flashCanPlay: false, 434 media: 'video' 435 }, 436 webmv: { // WEBM 437 codec: 'video/webm; codecs="vorbis, vp8"', 438 flashCanPlay: false, 439 media: 'video' 440 }, 441 flv: { // FLV / F4V 442 codec: 'video/x-flv', 443 flashCanPlay: true, 444 media: 'video' 445 } 446 }, 447 _init: function() { 448 var self = this; 449 450 this.element.empty(); 451 452 this.status = $.extend({}, this.status); // Copy static to unique instance. 453 this.internal = $.extend({}, this.internal); // Copy static to unique instance. 454 455 this.internal.domNode = this.element.get(0); 456 457 this.formats = []; // Array based on supplied string option. Order defines priority. 458 this.solutions = []; // Array based on solution string option. Order defines priority. 459 this.require = {}; // Which media types are required: video, audio. 460 461 this.htmlElement = {}; // DOM elements created by jPlayer 462 this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array. 463 this.html.audio = {}; 464 this.html.video = {}; 465 this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array. 466 467 this.css = {}; 468 this.css.cs = {}; // Holds the css selector strings 469 this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method) 470 471 this.ancestorJq = []; // Holds jQuery selector of cssSelectorAncestor. Init would use $() instead of [], but it is only 1.4+ 472 473 this.options.volume = this._limitValue(this.options.volume, 0, 1); // Limit volume value's bounds. 474 475 // Create the formats array, with prority based on the order of the supplied formats string 476 $.each(this.options.supplied.toLowerCase().split(","), function(index1, value1) { 477 var format = value1.replace(/^\s+|\s+$/g, ""); //trim 478 if(self.format[format]) { // Check format is valid. 479 var dupFound = false; 480 $.each(self.formats, function(index2, value2) { // Check for duplicates 481 if(format === value2) { 482 dupFound = true; 483 return false; 484 } 485 }); 486 if(!dupFound) { 487 self.formats.push(format); 488 } 489 } 490 }); 491 492 // Create the solutions array, with prority based on the order of the solution string 493 $.each(this.options.solution.toLowerCase().split(","), function(index1, value1) { 494 var solution = value1.replace(/^\s+|\s+$/g, ""); //trim 495 if(self.solution[solution]) { // Check solution is valid. 496 var dupFound = false; 497 $.each(self.solutions, function(index2, value2) { // Check for duplicates 498 if(solution === value2) { 499 dupFound = true; 500 return false; 501 } 502 }); 503 if(!dupFound) { 504 self.solutions.push(solution); 505 } 506 } 507 }); 508 509 this.internal.instance = "jp_" + this.count; 510 this.instances[this.internal.instance] = this.element; 511 512 // Check the jPlayer div has an id and create one if required. Important for Flash to know the unique id for comms. 513 if(!this.element.attr("id")) { 514 this.element.attr("id", this.options.idPrefix + "_jplayer_" + this.count); 515 } 516 517 this.internal.self = $.extend({}, { 518 id: this.element.attr("id"), 519 jq: this.element 520 }); 521 this.internal.audio = $.extend({}, { 522 id: this.options.idPrefix + "_audio_" + this.count, 523 jq: undefined 524 }); 525 this.internal.video = $.extend({}, { 526 id: this.options.idPrefix + "_video_" + this.count, 527 jq: undefined 528 }); 529 this.internal.flash = $.extend({}, { 530 id: this.options.idPrefix + "_flash_" + this.count, 531 jq: undefined, 532 swf: this.options.swfPath + (this.options.swfPath.toLowerCase().slice(-4) !== ".swf" ? (this.options.swfPath && this.options.swfPath.slice(-1) !== "/" ? "/" : "") + "Jplayer.swf" : "") 533 }); 534 this.internal.poster = $.extend({}, { 535 id: this.options.idPrefix + "_poster_" + this.count, 536 jq: undefined 537 }); 538 539 // Register listeners defined in the constructor 540 $.each($.jPlayer.event, function(eventName,eventType) { 541 if(self.options[eventName] !== undefined) { 542 self.element.bind(eventType + ".jPlayer", self.options[eventName]); // With .jPlayer namespace. 543 self.options[eventName] = undefined; // Destroy the handler pointer copy on the options. Reason, events can be added/removed in other ways so this could be obsolete and misleading. 544 } 545 }); 546 547 // Determine if we require solutions for audio, video or both media types. 548 this.require.audio = false; 549 this.require.video = false; 550 $.each(this.formats, function(priority, format) { 551 self.require[self.format[format].media] = true; 552 }); 553 554 // Now required types are known, finish the options default settings. 555 if(this.require.video) { 556 this.options = $.extend(true, {}, 557 this.optionsVideo, 558 this.options 559 ); 560 } else { 561 this.options = $.extend(true, {}, 562 this.optionsAudio, 563 this.options 564 ); 565 } 566 this._setSize(); // update status and jPlayer element size 567 568 // Determine the status for Blocklisted options. 569 this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); 570 this.status.noFullScreen = this._uaBlocklist(this.options.noFullScreen); 571 this.status.noVolume = this._uaBlocklist(this.options.noVolume); 572 573 // The native controls are only for video and are disabled when audio is also used. 574 this._restrictNativeVideoControls(); 575 576 // Create the poster image. 577 this.htmlElement.poster = document.createElement('img'); 578 this.htmlElement.poster.id = this.internal.poster.id; 579 this.htmlElement.poster.onload = function() { // Note that this did not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false); Did not investigate x-browser. 580 if(!self.status.video || self.status.waitForPlay) { 581 self.internal.poster.jq.show(); 582 } 583 }; 584 this.element.append(this.htmlElement.poster); 585 this.internal.poster.jq = $("#" + this.internal.poster.id); 586 this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height}); 587 this.internal.poster.jq.hide(); 588 this.internal.poster.jq.bind("click.jPlayer", function() { 589 self._trigger($.jPlayer.event.click); 590 }); 591 592 // Generate the required media elements 593 this.html.audio.available = false; 594 if(this.require.audio) { // If a supplied format is audio 595 this.htmlElement.audio = document.createElement('audio'); 596 this.htmlElement.audio.id = this.internal.audio.id; 597 this.html.audio.available = !!this.htmlElement.audio.canPlayType && this._testCanPlayType(this.htmlElement.audio); // Test is for IE9 on Win Server 2008. 598 } 599 this.html.video.available = false; 600 if(this.require.video) { // If a supplied format is video 601 this.htmlElement.video = document.createElement('video'); 602 this.htmlElement.video.id = this.internal.video.id; 603 this.html.video.available = !!this.htmlElement.video.canPlayType && this._testCanPlayType(this.htmlElement.video); // Test is for IE9 on Win Server 2008. 604 } 605 606 this.flash.available = this._checkForFlash(10); 607 608 this.html.canPlay = {}; 609 this.flash.canPlay = {}; 610 $.each(this.formats, function(priority, format) { 611 self.html.canPlay[format] = self.html[self.format[format].media].available && "" !== self.htmlElement[self.format[format].media].canPlayType(self.format[format].codec); 612 self.flash.canPlay[format] = self.format[format].flashCanPlay && self.flash.available; 613 }); 614 this.html.desired = false; 615 this.flash.desired = false; 616 $.each(this.solutions, function(solutionPriority, solution) { 617 if(solutionPriority === 0) { 618 self[solution].desired = true; 619 } else { 620 var audioCanPlay = false; 621 var videoCanPlay = false; 622 $.each(self.formats, function(formatPriority, format) { 623 if(self[self.solutions[0]].canPlay[format]) { // The other solution can play 624 if(self.format[format].media === 'video') { 625 videoCanPlay = true; 626 } else { 627 audioCanPlay = true; 628 } 629 } 630 }); 631 self[solution].desired = (self.require.audio && !audioCanPlay) || (self.require.video && !videoCanPlay); 632 } 633 }); 634 // This is what jPlayer will support, based on solution and supplied. 635 this.html.support = {}; 636 this.flash.support = {}; 637 $.each(this.formats, function(priority, format) { 638 self.html.support[format] = self.html.canPlay[format] && self.html.desired; 639 self.flash.support[format] = self.flash.canPlay[format] && self.flash.desired; 640 }); 641 // If jPlayer is supporting any format in a solution, then the solution is used. 642 this.html.used = false; 643 this.flash.used = false; 644 $.each(this.solutions, function(solutionPriority, solution) { 645 $.each(self.formats, function(formatPriority, format) { 646 if(self[solution].support[format]) { 647 self[solution].used = true; 648 return false; 649 } 650 }); 651 }); 652 653 // Init solution active state and the event gates to false. 654 this._resetActive(); 655 this._resetGate(); 656 657 // Set up the css selectors for the control and feedback entities. 658 this._cssSelectorAncestor(this.options.cssSelectorAncestor); 659 660 // If neither html nor flash are being used by this browser, then media playback is not possible. Trigger an error event. 661 if(!(this.html.used || this.flash.used)) { 662 this._error( { 663 type: $.jPlayer.error.NO_SOLUTION, 664 context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}", 665 message: $.jPlayer.errorMsg.NO_SOLUTION, 666 hint: $.jPlayer.errorHint.NO_SOLUTION 667 }); 668 if(this.css.jq.noSolution.length) { 669 this.css.jq.noSolution.show(); 670 } 671 } else { 672 if(this.css.jq.noSolution.length) { 673 this.css.jq.noSolution.hide(); 674 } 675 } 676 677 // Add the flash solution if it is being used. 678 if(this.flash.used) { 679 var htmlObj, 680 flashVars = 'jQuery=' + encodeURI(this.options.noConflict) + '&id=' + encodeURI(this.internal.self.id) + '&vol=' + this.options.volume + '&muted=' + this.options.muted; 681 682 // Code influenced by SWFObject 2.2: http://code.google.com/p/swfobject/ 683 // Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event. 684 685 if($.browser.msie && Number($.browser.version) <= 8) { 686 var objStr = '<object id="' + this.internal.flash.id + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0"></object>'; 687 688 var paramStr = [ 689 '<param name="movie" value="' + this.internal.flash.swf + '" />', 690 '<param name="FlashVars" value="' + flashVars + '" />', 691 '<param name="allowScriptAccess" value="always" />', 692 '<param name="bgcolor" value="' + this.options.backgroundColor + '" />', 693 '<param name="wmode" value="' + this.options.wmode + '" />' 694 ]; 695 696 htmlObj = document.createElement(objStr); 697 for(var i=0; i < paramStr.length; i++) { 698 htmlObj.appendChild(document.createElement(paramStr[i])); 699 } 700 } else { 701 var createParam = function(el, n, v) { 702 var p = document.createElement("param"); 703 p.setAttribute("name", n); 704 p.setAttribute("value", v); 705 el.appendChild(p); 706 }; 707 708 htmlObj = document.createElement("object"); 709 htmlObj.setAttribute("id", this.internal.flash.id); 710 htmlObj.setAttribute("data", this.internal.flash.swf); 711 htmlObj.setAttribute("type", "application/x-shockwave-flash"); 712 htmlObj.setAttribute("width", "1"); // Non-zero 713 htmlObj.setAttribute("height", "1"); // Non-zero 714 createParam(htmlObj, "flashvars", flashVars); 715 createParam(htmlObj, "allowscriptaccess", "always"); 716 createParam(htmlObj, "bgcolor", this.options.backgroundColor); 717 createParam(htmlObj, "wmode", this.options.wmode); 718 } 719 720 this.element.append(htmlObj); 721 this.internal.flash.jq = $(htmlObj); 722 } 723 724 // Add the HTML solution if being used. 725 if(this.html.used) { 726 727 // The HTML Audio handlers 728 if(this.html.audio.available) { 729 this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio); 730 this.element.append(this.htmlElement.audio); 731 this.internal.audio.jq = $("#" + this.internal.audio.id); 732 } 733 734 // The HTML Video handlers 735 if(this.html.video.available) { 736 this._addHtmlEventListeners(this.htmlElement.video, this.html.video); 737 this.element.append(this.htmlElement.video); 738 this.internal.video.jq = $("#" + this.internal.video.id); 739 if(this.status.nativeVideoControls) { 740 this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); 741 } else { 742 this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS 743 } 744 this.internal.video.jq.bind("click.jPlayer", function() { 745 self._trigger($.jPlayer.event.click); 746 }); 747 } 748 } 749 750 // Create the bridge that emulates the HTML Media element on the jPlayer DIV 751 if( this.options.emulateHtml ) { 752 this._emulateHtmlBridge(); 753 } 754 755 if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms. 756 setTimeout( function() { 757 self.internal.ready = true; 758 self.version.flash = "n/a"; 759 self._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option. 760 self._trigger($.jPlayer.event.ready); 761 }, 100); 762 } 763 764 // Initialize the interface components with the options. 765 this._updateNativeVideoControls(); // Must do this first, otherwise there is a bizarre bug in iOS 4.3.2, where the native controls are not shown. Fails in iOS if called after _updateButtons() below. Works if called later in setMedia too, so it odd. 766 this._updateInterface(); 767 this._updateButtons(false); 768 this._updateAutohide(); 769 this._updateVolume(this.options.volume); 770 this._updateMute(this.options.muted); 771 if(this.css.jq.videoPlay.length) { 772 this.css.jq.videoPlay.hide(); 773 } 774 775 $.jPlayer.prototype.count++; // Change static variable via prototype. 776 }, 777 destroy: function() { 778 // MJP: The background change remains. Would need to store the original to restore it correctly. 779 // MJP: The jPlayer element's size change remains. 780 781 // Clear the media to reset the GUI and stop any downloads. Streams on some browsers had persited. (Chrome) 782 this.clearMedia(); 783 // Remove the size/sizeFull cssClass from the cssSelectorAncestor 784 this._removeUiClass(); 785 // Remove the times from the GUI 786 if(this.css.jq.currentTime.length) { 787 this.css.jq.currentTime.text(""); 788 } 789 if(this.css.jq.duration.length) { 790 this.css.jq.duration.text(""); 791 } 792 // Remove any bindings from the interface controls. 793 $.each(this.css.jq, function(fn, jq) { 794 // Check selector is valid before trying to execute method. 795 if(jq.length) { 796 jq.unbind(".jPlayer"); 797 } 798 }); 799 // Remove the click handlers for $.jPlayer.event.click 800 this.internal.poster.jq.unbind(".jPlayer"); 801 if(this.internal.video.jq) { 802 this.internal.video.jq.unbind(".jPlayer"); 803 } 804 // Destroy the HTML bridge. 805 if(this.options.emulateHtml) { 806 this._destroyHtmlBridge(); 807 } 808 this.element.removeData("jPlayer"); // Remove jPlayer data 809 this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor 810 this.element.empty(); // Remove the inserted child elements 811 812 delete this.instances[this.internal.instance]; // Clear the instance on the static instance object 813 }, 814 enable: function() { // Plan to implement 815 // options.disabled = false 816 }, 817 disable: function () { // Plan to implement 818 // options.disabled = true 819 }, 820 _testCanPlayType: function(elem) { 821 // IE9 on Win Server 2008 did not implement canPlayType(), but it has the property. 822 try { 823 elem.canPlayType(this.format.mp3.codec); // The type is irrelevant. 824 return true; 825 } catch(err) { 826 return false; 827 } 828 }, 829 _uaBlocklist: function(list) { 830 // list : object with properties that are all regular expressions. Property names are irrelevant. 831 // Returns true if the user agent is matched in list. 832 var ua = navigator.userAgent.toLowerCase(), 833 block = false; 834 835 $.each(list, function(p, re) { 836 if(re && re.test(ua)) { 837 block = true; 838 return false; // exit $.each. 839 } 840 }); 841 return block; 842 }, 843 _restrictNativeVideoControls: function() { 844 // Fallback to noFullScreen when nativeVideoControls is true and audio media is being used. Affects when both media types are used. 845 if(this.require.audio) { 846 if(this.status.nativeVideoControls) { 847 this.status.nativeVideoControls = false; 848 this.status.noFullScreen = true; 849 } 850 } 851 }, 852 _updateNativeVideoControls: function() { 853 if(this.html.video.available && this.html.used) { 854 // Turn the HTML Video controls on/off 855 this.htmlElement.video.controls = this.status.nativeVideoControls; 856 // Show/hide the jPlayer GUI. 857 this._updateAutohide(); 858 // For when option changed. The poster image is not updated, as it is dealt with in setMedia(). Acceptable degradation since seriously doubt these options will change on the fly. Can again review later. 859 if(this.status.nativeVideoControls && this.require.video) { 860 this.internal.poster.jq.hide(); 861 this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); 862 } else if(this.status.waitForPlay && this.status.video) { 863 this.internal.poster.jq.show(); 864 this.internal.video.jq.css({'width': '0px', 'height': '0px'}); 865 } 866 } 867 }, 868 _addHtmlEventListeners: function(mediaElement, entity) { 869 var self = this; 870 mediaElement.preload = this.options.preload; 871 mediaElement.muted = this.options.muted; 872 mediaElement.volume = this.options.volume; 873 874 // Create the event listeners 875 // Only want the active entity to affect jPlayer and bubble events. 876 // Using entity.gate so that object is referenced and gate property always current 877 878 mediaElement.addEventListener("progress", function() { 879 if(entity.gate) { 880 self._getHtmlStatus(mediaElement); 881 self._updateInterface(); 882 self._trigger($.jPlayer.event.progress); 883 } 884 }, false); 885 mediaElement.addEventListener("timeupdate", function() { 886 if(entity.gate) { 887 self._getHtmlStatus(mediaElement); 888 self._updateInterface(); 889 self._trigger($.jPlayer.event.timeupdate); 890 } 891 }, false); 892 mediaElement.addEventListener("durationchange", function() { 893 if(entity.gate) { 894 self.status.duration = this.duration; 895 self._getHtmlStatus(mediaElement); 896 self._updateInterface(); 897 self._trigger($.jPlayer.event.durationchange); 898 } 899 }, false); 900 mediaElement.addEventListener("play", function() { 901 if(entity.gate) { 902 self._updateButtons(true); 903 self._html_checkWaitForPlay(); // So the native controls update this variable and puts the hidden interface in the correct state. Affects toggling native controls. 904 self._trigger($.jPlayer.event.play); 905 } 906 }, false); 907 mediaElement.addEventListener("playing", function() { 908 if(entity.gate) { 909 self._updateButtons(true); 910 self._seeked(); 911 self._trigger($.jPlayer.event.playing); 912 } 913 }, false); 914 mediaElement.addEventListener("pause", function() { 915 if(entity.gate) { 916 self._updateButtons(false); 917 self._trigger($.jPlayer.event.pause); 918 } 919 }, false); 920 mediaElement.addEventListener("waiting", function() { 921 if(entity.gate) { 922 self._seeking(); 923 self._trigger($.jPlayer.event.waiting); 924 } 925 }, false); 926 mediaElement.addEventListener("seeking", function() { 927 if(entity.gate) { 928 self._seeking(); 929 self._trigger($.jPlayer.event.seeking); 930 } 931 }, false); 932 mediaElement.addEventListener("seeked", function() { 933 if(entity.gate) { 934 self._seeked(); 935 self._trigger($.jPlayer.event.seeked); 936 } 937 }, false); 938 mediaElement.addEventListener("volumechange", function() { 939 if(entity.gate) { 940 // Read the values back from the element as the Blackberry PlayBook shares the volume with the physical buttons master volume control. 941 // However, when tested 6th July 2011, those buttons do not generate an event. The physical play/pause button does though. 942 self.options.volume = mediaElement.volume; 943 self.options.muted = mediaElement.muted; 944 self._updateMute(); 945 self._updateVolume(); 946 self._trigger($.jPlayer.event.volumechange); 947 } 948 }, false); 949 mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture. 950 if(entity.gate) { 951 self._seeked(); 952 self._trigger($.jPlayer.event.suspend); 953 } 954 }, false); 955 mediaElement.addEventListener("ended", function() { 956 if(entity.gate) { 957 // Order of the next few commands are important. Change the time and then pause. 958 // Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored. 959 if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo. 960 self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.) 961 } 962 self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback. 963 self._updateButtons(false); 964 self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full. 965 self._updateInterface(); 966 self._trigger($.jPlayer.event.ended); 967 } 968 }, false); 969 mediaElement.addEventListener("error", function() { 970 if(entity.gate) { 971 self._updateButtons(false); 972 self._seeked(); 973 if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event. 974 clearTimeout(self.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution. 975 self.status.waitForLoad = true; // Allows the load operation to try again. 976 self.status.waitForPlay = true; // Reset since a play was captured. 977 if(self.status.video && !self.status.nativeVideoControls) { 978 self.internal.video.jq.css({'width':'0px', 'height':'0px'}); 979 } 980 if(self._validString(self.status.media.poster) && !self.status.nativeVideoControls) { 981 self.internal.poster.jq.show(); 982 } 983 if(self.css.jq.videoPlay.length) { 984 self.css.jq.videoPlay.show(); 985 } 986 self._error( { 987 type: $.jPlayer.error.URL, 988 context: self.status.src, // this.src shows absolute urls. Want context to show the url given. 989 message: $.jPlayer.errorMsg.URL, 990 hint: $.jPlayer.errorHint.URL 991 }); 992 } 993 } 994 }, false); 995 // Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer. 996 $.each($.jPlayer.htmlEvent, function(i, eventType) { 997 mediaElement.addEventListener(this, function() { 998 if(entity.gate) { 999 self._trigger($.jPlayer.event[eventType]); 1000 } 1001 }, false); 1002 }); 1003 }, 1004 _getHtmlStatus: function(media, override) { 1005 var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0; 1006 1007 if(media.duration) { // Fixes the duration bug in iOS, where the durationchange event occurs when media.duration is not always correct. 1008 this.status.duration = media.duration; 1009 } 1010 ct = media.currentTime; 1011 cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0; 1012 if((typeof media.seekable === "object") && (media.seekable.length > 0)) { 1013 sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100; 1014 cpr = 100 * media.currentTime / media.seekable.end(media.seekable.length-1); 1015 } else { 1016 sp = 100; 1017 cpr = cpa; 1018 } 1019 1020 if(override) { 1021 ct = 0; 1022 cpr = 0; 1023 cpa = 0; 1024 } 1025 1026 this.status.seekPercent = sp; 1027 this.status.currentPercentRelative = cpr; 1028 this.status.currentPercentAbsolute = cpa; 1029 this.status.currentTime = ct; 1030 1031 this.status.readyState = media.readyState; 1032 this.status.networkState = media.networkState; 1033 this.status.playbackRate = media.playbackRate; 1034 this.status.ended = media.ended; 1035 }, 1036 _resetStatus: function() { 1037 this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset. 1038 }, 1039 _trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType 1040 var event = $.Event(eventType); 1041 event.jPlayer = {}; 1042 event.jPlayer.version = $.extend({}, this.version); 1043 event.jPlayer.options = $.extend(true, {}, this.options); // Deep copy 1044 event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy 1045 event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy 1046 event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy 1047 if(error) { 1048 event.jPlayer.error = $.extend({}, error); 1049 } 1050 if(warning) { 1051 event.jPlayer.warning = $.extend({}, warning); 1052 } 1053 this.element.trigger(event); 1054 }, 1055 jPlayerFlashEvent: function(eventType, status) { // Called from Flash 1056 if(eventType === $.jPlayer.event.ready) { 1057 if(!this.internal.ready) { 1058 this.internal.ready = true; 1059 this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Once Flash generates the ready event, minimise to zero as it is not affected by wmode anymore. 1060 1061 this.version.flash = status.version; 1062 if(this.version.needFlash !== this.version.flash) { 1063 this._error( { 1064 type: $.jPlayer.error.VERSION, 1065 context: this.version.flash, 1066 message: $.jPlayer.errorMsg.VERSION + this.version.flash, 1067 hint: $.jPlayer.errorHint.VERSION 1068 }); 1069 } 1070 this._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option. 1071 this._trigger(eventType); 1072 } else { 1073 // This condition occurs if the Flash is hidden and then shown again. 1074 // Firefox also reloads the Flash if the CSS position changes. position:fixed is used for full screen. 1075 1076 // Only do this if the Flash is the solution being used at the moment. Affects Media players where both solution may be being used. 1077 if(this.flash.gate) { 1078 1079 // Send the current status to the Flash now that it is ready (available) again. 1080 if(this.status.srcSet) { 1081 1082 // Need to read original status before issuing the setMedia command. 1083 var currentTime = this.status.currentTime, 1084 paused = this.status.paused; 1085 1086 this.setMedia(this.status.media); 1087 if(currentTime > 0) { 1088 if(paused) { 1089 this.pause(currentTime); 1090 } else { 1091 this.play(currentTime); 1092 } 1093 } 1094 } 1095 this._trigger($.jPlayer.event.flashreset); 1096 } 1097 } 1098 } 1099 if(this.flash.gate) { 1100 switch(eventType) { 1101 case $.jPlayer.event.progress: 1102 this._getFlashStatus(status); 1103 this._updateInterface(); 1104 this._trigger(eventType); 1105 break; 1106 case $.jPlayer.event.timeupdate: 1107 this._getFlashStatus(status); 1108 this._updateInterface(); 1109 this._trigger(eventType); 1110 break; 1111 case $.jPlayer.event.play: 1112 this._seeked(); 1113 this._updateButtons(true); 1114 this._trigger(eventType); 1115 break; 1116 case $.jPlayer.event.pause: 1117 this._updateButtons(false); 1118 this._trigger(eventType); 1119 break; 1120 case $.jPlayer.event.ended: 1121 this._updateButtons(false); 1122 this._trigger(eventType); 1123 break; 1124 case $.jPlayer.event.click: 1125 this._trigger(eventType); // This could be dealt with by the default 1126 break; 1127 case $.jPlayer.event.error: 1128 this.status.waitForLoad = true; // Allows the load operation to try again. 1129 this.status.waitForPlay = true; // Reset since a play was captured. 1130 if(this.status.video) { 1131 this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); 1132 } 1133 if(this._validString(this.status.media.poster)) { 1134 this.internal.poster.jq.show(); 1135 } 1136 if(this.css.jq.videoPlay.length && this.status.video) { 1137 this.css.jq.videoPlay.show(); 1138 } 1139 if(this.status.video) { // Set up for another try. Execute before error event. 1140 this._flash_setVideo(this.status.media); 1141 } else { 1142 this._flash_setAudio(this.status.media); 1143 } 1144 this._updateButtons(false); 1145 this._error( { 1146 type: $.jPlayer.error.URL, 1147 context:status.src, 1148 message: $.jPlayer.errorMsg.URL, 1149 hint: $.jPlayer.errorHint.URL 1150 }); 1151 break; 1152 case $.jPlayer.event.seeking: 1153 this._seeking(); 1154 this._trigger(eventType); 1155 break; 1156 case $.jPlayer.event.seeked: 1157 this._seeked(); 1158 this._trigger(eventType); 1159 break; 1160 case $.jPlayer.event.ready: 1161 // The ready event is handled outside the switch statement. 1162 // Captured here otherwise 2 ready events would be generated if the ready event handler used setMedia. 1163 break; 1164 default: 1165 this._trigger(eventType); 1166 } 1167 } 1168 return false; 1169 }, 1170 _getFlashStatus: function(status) { 1171 this.status.seekPercent = status.seekPercent; 1172 this.status.currentPercentRelative = status.currentPercentRelative; 1173 this.status.currentPercentAbsolute = status.currentPercentAbsolute; 1174 this.status.currentTime = status.currentTime; 1175 this.status.duration = status.duration; 1176 1177 // The Flash does not generate this information in this release 1178 this.status.readyState = 4; // status.readyState; 1179 this.status.networkState = 0; // status.networkState; 1180 this.status.playbackRate = 1; // status.playbackRate; 1181 this.status.ended = false; // status.ended; 1182 }, 1183 _updateButtons: function(playing) { 1184 if(playing !== undefined) { 1185 this.status.paused = !playing; 1186 if(this.css.jq.play.length && this.css.jq.pause.length) { 1187 if(playing) { 1188 this.css.jq.play.hide(); 1189 this.css.jq.pause.show(); 1190 } else { 1191 this.css.jq.play.show(); 1192 this.css.jq.pause.hide(); 1193 } 1194 } 1195 } 1196 if(this.css.jq.restoreScreen.length && this.css.jq.fullScreen.length) { 1197 if(this.status.noFullScreen) { 1198 this.css.jq.fullScreen.hide(); 1199 this.css.jq.restoreScreen.hide(); 1200 } else if(this.options.fullScreen) { 1201 this.css.jq.fullScreen.hide(); 1202 this.css.jq.restoreScreen.show(); 1203 } else { 1204 this.css.jq.fullScreen.show(); 1205 this.css.jq.restoreScreen.hide(); 1206 } 1207 } 1208 if(this.css.jq.repeat.length && this.css.jq.repeatOff.length) { 1209 if(this.options.loop) { 1210 this.css.jq.repeat.hide(); 1211 this.css.jq.repeatOff.show(); 1212 } else { 1213 this.css.jq.repeat.show(); 1214 this.css.jq.repeatOff.hide(); 1215 } 1216 } 1217 }, 1218 _updateInterface: function() { 1219 if(this.css.jq.seekBar.length) { 1220 this.css.jq.seekBar.width(this.status.seekPercent+"%"); 1221 } 1222 if(this.css.jq.playBar.length) { 1223 this.css.jq.playBar.width(this.status.currentPercentRelative+"%"); 1224 } 1225 if(this.css.jq.currentTime.length) { 1226 this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime)); 1227 } 1228 if(this.css.jq.duration.length) { 1229 this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration)); 1230 } 1231 }, 1232 _seeking: function() { 1233 if(this.css.jq.seekBar.length) { 1234 this.css.jq.seekBar.addClass("jp-seeking-bg"); 1235 } 1236 }, 1237 _seeked: function() { 1238 if(this.css.jq.seekBar.length) { 1239 this.css.jq.seekBar.removeClass("jp-seeking-bg"); 1240 } 1241 }, 1242 _resetGate: function() { 1243 this.html.audio.gate = false; 1244 this.html.video.gate = false; 1245 this.flash.gate = false; 1246 }, 1247 _resetActive: function() { 1248 this.html.active = false; 1249 this.flash.active = false; 1250 }, 1251 setMedia: function(media) { 1252 1253 /* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats. 1254 * media.poster = String: Video poster URL. 1255 * media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file 1256 * media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file 1257 * media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often. 1258 */ 1259 1260 var self = this, 1261 supported = false, 1262 posterChanged = this.status.media.poster !== media.poster; // Compare before reset. Important for OSX Safari as this.htmlElement.poster.src is absolute, even if original poster URL was relative. 1263 1264 this._resetMedia(); 1265 this._resetGate(); 1266 this._resetActive(); 1267 1268 $.each(this.formats, function(formatPriority, format) { 1269 var isVideo = self.format[format].media === 'video'; 1270 $.each(self.solutions, function(solutionPriority, solution) { 1271 if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format. 1272 var isHtml = solution === 'html'; 1273 1274 if(isVideo) { 1275 if(isHtml) { 1276 self.html.video.gate = true; 1277 self._html_setVideo(media); 1278 self.html.active = true; 1279 } else { 1280 self.flash.gate = true; 1281 self._flash_setVideo(media); 1282 self.flash.active = true; 1283 } 1284 if(self.css.jq.videoPlay.length) { 1285 self.css.jq.videoPlay.show(); 1286 } 1287 self.status.video = true; 1288 } else { 1289 if(isHtml) { 1290 self.html.audio.gate = true; 1291 self._html_setAudio(media); 1292 self.html.active = true; 1293 } else { 1294 self.flash.gate = true; 1295 self._flash_setAudio(media); 1296 self.flash.active = true; 1297 } 1298 if(self.css.jq.videoPlay.length) { 1299 self.css.jq.videoPlay.hide(); 1300 } 1301 self.status.video = false; 1302 } 1303 1304 supported = true; 1305 return false; // Exit $.each 1306 } 1307 }); 1308 if(supported) { 1309 return false; // Exit $.each 1310 } 1311 }); 1312 1313 if(supported) { 1314 if(!(this.status.nativeVideoControls && this.html.video.gate)) { 1315 // Set poster IMG if native video controls are not being used 1316 // Note: With IE the IMG onload event occurs immediately when cached. 1317 // Note: Poster hidden by default in _resetMedia() 1318 if(this._validString(media.poster)) { 1319 if(posterChanged) { // Since some browsers do not generate img onload event. 1320 this.htmlElement.poster.src = media.poster; 1321 } else { 1322 this.internal.poster.jq.show(); 1323 } 1324 } 1325 } 1326 this.status.srcSet = true; 1327 this.status.media = $.extend({}, media); 1328 this._updateButtons(false); 1329 this._updateInterface(); 1330 } else { // jPlayer cannot support any formats provided in this browser 1331 // Send an error event 1332 this._error( { 1333 type: $.jPlayer.error.NO_SUPPORT, 1334 context: "{supplied:'" + this.options.supplied + "'}", 1335 message: $.jPlayer.errorMsg.NO_SUPPORT, 1336 hint: $.jPlayer.errorHint.NO_SUPPORT 1337 }); 1338 } 1339 }, 1340 _resetMedia: function() { 1341 this._resetStatus(); 1342 this._updateButtons(false); 1343 this._updateInterface(); 1344 this._seeked(); 1345 this.internal.poster.jq.hide(); 1346 1347 clearTimeout(this.internal.htmlDlyCmdId); 1348 1349 if(this.html.active) { 1350 this._html_resetMedia(); 1351 } else if(this.flash.active) { 1352 this._flash_resetMedia(); 1353 } 1354 }, 1355 clearMedia: function() { 1356 this._resetMedia(); 1357 1358 if(this.html.active) { 1359 this._html_clearMedia(); 1360 } else if(this.flash.active) { 1361 this._flash_clearMedia(); 1362 } 1363 1364 this._resetGate(); 1365 this._resetActive(); 1366 }, 1367 load: function() { 1368 if(this.status.srcSet) { 1369 if(this.html.active) { 1370 this._html_load(); 1371 } else if(this.flash.active) { 1372 this._flash_load(); 1373 } 1374 } else { 1375 this._urlNotSetError("load"); 1376 } 1377 }, 1378 play: function(time) { 1379 time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler 1380 if(this.status.srcSet) { 1381 if(this.html.active) { 1382 this._html_play(time); 1383 } else if(this.flash.active) { 1384 this._flash_play(time); 1385 } 1386 } else { 1387 this._urlNotSetError("play"); 1388 } 1389 }, 1390 videoPlay: function(e) { // Handles clicks on the play button over the video poster 1391 this.play(); 1392 }, 1393 pause: function(time) { 1394 time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler 1395 if(this.status.srcSet) { 1396 if(this.html.active) { 1397 this._html_pause(time); 1398 } else if(this.flash.active) { 1399 this._flash_pause(time); 1400 } 1401 } else { 1402 this._urlNotSetError("pause"); 1403 } 1404 }, 1405 pauseOthers: function() { 1406 var self = this; 1407 $.each(this.instances, function(i, element) { 1408 if(self.element !== element) { // Do not this instance. 1409 if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. 1410 element.jPlayer("pause"); 1411 } 1412 } 1413 }); 1414 }, 1415 stop: function() { 1416 if(this.status.srcSet) { 1417 if(this.html.active) { 1418 this._html_pause(0); 1419 } else if(this.flash.active) { 1420 this._flash_pause(0); 1421 } 1422 } else { 1423 this._urlNotSetError("stop"); 1424 } 1425 }, 1426 playHead: function(p) { 1427 p = this._limitValue(p, 0, 100); 1428 if(this.status.srcSet) { 1429 if(this.html.active) { 1430 this._html_playHead(p); 1431 } else if(this.flash.active) { 1432 this._flash_playHead(p); 1433 } 1434 } else { 1435 this._urlNotSetError("playHead"); 1436 } 1437 }, 1438 _muted: function(muted) { 1439 this.options.muted = muted; 1440 if(this.html.used) { 1441 this._html_mute(muted); 1442 } 1443 if(this.flash.used) { 1444 this._flash_mute(muted); 1445 } 1446 1447 // The HTML solution generates this event from the media element itself. 1448 if(!this.html.video.gate && !this.html.audio.gate) { 1449 this._updateMute(muted); 1450 this._updateVolume(this.options.volume); 1451 this._trigger($.jPlayer.event.volumechange); 1452 } 1453 }, 1454 mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted). 1455 mute = mute === undefined ? true : !!mute; 1456 this._muted(mute); 1457 }, 1458 unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted). 1459 unmute = unmute === undefined ? true : !!unmute; 1460 this._muted(!unmute); 1461 }, 1462 _updateMute: function(mute) { 1463 if(mute === undefined) { 1464 mute = this.options.muted; 1465 } 1466 if(this.css.jq.mute.length && this.css.jq.unmute.length) { 1467 if(this.status.noVolume) { 1468 this.css.jq.mute.hide(); 1469 this.css.jq.unmute.hide(); 1470 } else if(mute) { 1471 this.css.jq.mute.hide(); 1472 this.css.jq.unmute.show(); 1473 } else { 1474 this.css.jq.mute.show(); 1475 this.css.jq.unmute.hide(); 1476 } 1477 } 1478 }, 1479 volume: function(v) { 1480 v = this._limitValue(v, 0, 1); 1481 this.options.volume = v; 1482 1483 if(this.html.used) { 1484 this._html_volume(v); 1485 } 1486 if(this.flash.used) { 1487 this._flash_volume(v); 1488 } 1489 1490 // The HTML solution generates this event from the media element itself. 1491 if(!this.html.video.gate && !this.html.audio.gate) { 1492 this._updateVolume(v); 1493 this._trigger($.jPlayer.event.volumechange); 1494 } 1495 }, 1496 volumeBar: function(e) { // Handles clicks on the volumeBar 1497 if(this.css.jq.volumeBar.length) { 1498 var offset = this.css.jq.volumeBar.offset(), 1499 x = e.pageX - offset.left, 1500 w = this.css.jq.volumeBar.width(), 1501 y = this.css.jq.volumeBar.height() - e.pageY + offset.top, 1502 h = this.css.jq.volumeBar.height(); 1503 1504 if(this.options.verticalVolume) { 1505 this.volume(y/h); 1506 } else { 1507 this.volume(x/w); 1508 } 1509 } 1510 if(this.options.muted) { 1511 this._muted(false); 1512 } 1513 }, 1514 volumeBarValue: function(e) { // Handles clicks on the volumeBarValue 1515 this.volumeBar(e); 1516 }, 1517 _updateVolume: function(v) { 1518 if(v === undefined) { 1519 v = this.options.volume; 1520 } 1521 v = this.options.muted ? 0 : v; 1522 1523 if(this.status.noVolume) { 1524 if(this.css.jq.volumeBar.length) { 1525 this.css.jq.volumeBar.hide(); 1526 } 1527 if(this.css.jq.volumeBarValue.length) { 1528 this.css.jq.volumeBarValue.hide(); 1529 } 1530 if(this.css.jq.volumeMax.length) { 1531 this.css.jq.volumeMax.hide(); 1532 } 1533 } else { 1534 if(this.css.jq.volumeBar.length) { 1535 this.css.jq.volumeBar.show(); 1536 } 1537 if(this.css.jq.volumeBarValue.length) { 1538 this.css.jq.volumeBarValue.show(); 1539 this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((v*100)+"%"); 1540 } 1541 if(this.css.jq.volumeMax.length) { 1542 this.css.jq.volumeMax.show(); 1543 } 1544 } 1545 }, 1546 volumeMax: function() { // Handles clicks on the volume max 1547 this.volume(1); 1548 if(this.options.muted) { 1549 this._muted(false); 1550 } 1551 }, 1552 _cssSelectorAncestor: function(ancestor) { 1553 var self = this; 1554 this.options.cssSelectorAncestor = ancestor; 1555 this._removeUiClass(); 1556 this.ancestorJq = ancestor ? $(ancestor) : []; // Would use $() instead of [], but it is only 1.4+ 1557 if(ancestor && this.ancestorJq.length !== 1) { // So empty strings do not generate the warning. 1558 this._warning( { 1559 type: $.jPlayer.warning.CSS_SELECTOR_COUNT, 1560 context: ancestor, 1561 message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.ancestorJq.length + " found for cssSelectorAncestor.", 1562 hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT 1563 }); 1564 } 1565 this._addUiClass(); 1566 $.each(this.options.cssSelector, function(fn, cssSel) { 1567 self._cssSelector(fn, cssSel); 1568 }); 1569 }, 1570 _cssSelector: function(fn, cssSel) { 1571 var self = this; 1572 if(typeof cssSel === 'string') { 1573 if($.jPlayer.prototype.options.cssSelector[fn]) { 1574 if(this.css.jq[fn] && this.css.jq[fn].length) { 1575 this.css.jq[fn].unbind(".jPlayer"); 1576 } 1577 this.options.cssSelector[fn] = cssSel; 1578 this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel; 1579 1580 if(cssSel) { // Checks for empty string 1581 this.css.jq[fn] = $(this.css.cs[fn]); 1582 } else { 1583 this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set. 1584 } 1585 1586 if(this.css.jq[fn].length) { 1587 var handler = function(e) { 1588 self[fn](e); 1589 $(this).blur(); 1590 return false; 1591 }; 1592 this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace 1593 } 1594 1595 if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one. 1596 this._warning( { 1597 type: $.jPlayer.warning.CSS_SELECTOR_COUNT, 1598 context: this.css.cs[fn], 1599 message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.", 1600 hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT 1601 }); 1602 } 1603 } else { 1604 this._warning( { 1605 type: $.jPlayer.warning.CSS_SELECTOR_METHOD, 1606 context: fn, 1607 message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD, 1608 hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD 1609 }); 1610 } 1611 } else { 1612 this._warning( { 1613 type: $.jPlayer.warning.CSS_SELECTOR_STRING, 1614 context: cssSel, 1615 message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING, 1616 hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING 1617 }); 1618 } 1619 }, 1620 seekBar: function(e) { // Handles clicks on the seekBar 1621 if(this.css.jq.seekBar) { 1622 var offset = this.css.jq.seekBar.offset(); 1623 var x = e.pageX - offset.left; 1624 var w = this.css.jq.seekBar.width(); 1625 var p = 100*x/w; 1626 this.playHead(p); 1627 } 1628 }, 1629 playBar: function(e) { // Handles clicks on the playBar 1630 this.seekBar(e); 1631 }, 1632 repeat: function() { // Handle clicks on the repeat button 1633 this._loop(true); 1634 }, 1635 repeatOff: function() { // Handle clicks on the repeatOff button 1636 this._loop(false); 1637 }, 1638 _loop: function(loop) { 1639 if(this.options.loop !== loop) { 1640 this.options.loop = loop; 1641 this._updateButtons(); 1642 this._trigger($.jPlayer.event.repeat); 1643 } 1644 }, 1645 1646 // Plan to review the cssSelector method to cope with missing associated functions accordingly. 1647 1648 currentTime: function(e) { // Handles clicks on the text 1649 // Added to avoid errors using cssSelector system for the text 1650 }, 1651 duration: function(e) { // Handles clicks on the text 1652 // Added to avoid errors using cssSelector system for the text 1653 }, 1654 gui: function(e) { // Handles clicks on the gui 1655 // Added to avoid errors using cssSelector system for the gui 1656 }, 1657 noSolution: function(e) { // Handles clicks on the error message 1658 // Added to avoid errors using cssSelector system for no-solution 1659 }, 1660 1661 // Options code adapted from ui.widget.js (1.8.7). Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1. 1662 option: function(key, value) { 1663 var options = key; 1664 1665 // Enables use: options(). Returns a copy of options object 1666 if ( arguments.length === 0 ) { 1667 return $.extend( true, {}, this.options ); 1668 } 1669 1670 if(typeof key === "string") { 1671 var keys = key.split("."); 1672 1673 // Enables use: options("someOption") Returns a copy of the option. Supports dot notation. 1674 if(value === undefined) { 1675 1676 var opt = $.extend(true, {}, this.options); 1677 for(var i = 0; i < keys.length; i++) { 1678 if(opt[keys[i]] !== undefined) { 1679 opt = opt[keys[i]]; 1680 } else { 1681 this._warning( { 1682 type: $.jPlayer.warning.OPTION_KEY, 1683 context: key, 1684 message: $.jPlayer.warningMsg.OPTION_KEY, 1685 hint: $.jPlayer.warningHint.OPTION_KEY 1686 }); 1687 return undefined; 1688 } 1689 } 1690 return opt; 1691 } 1692 1693 // Enables use: options("someOptionObject", someObject}). Creates: {someOptionObject:someObject} 1694 // Enables use: options("someOption", someValue). Creates: {someOption:someValue} 1695 // Enables use: options("someOptionObject.someOption", someValue). Creates: {someOptionObject:{someOption:someValue}} 1696 1697 options = {}; 1698 var opts = options; 1699 1700 for(var j = 0; j < keys.length; j++) { 1701 if(j < keys.length - 1) { 1702 opts[keys[j]] = {}; 1703 opts = opts[keys[j]]; 1704 } else { 1705 opts[keys[j]] = value; 1706 } 1707 } 1708 } 1709 1710 // Otherwise enables use: options(optionObject). Uses original object (the key) 1711 1712 this._setOptions(options); 1713 1714 return this; 1715 }, 1716 _setOptions: function(options) { 1717 var self = this; 1718 $.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth. 1719 self._setOption(key, value); 1720 }); 1721 1722 return this; 1723 }, 1724 _setOption: function(key, value) { 1725 var self = this; 1726 1727 // The ability to set options is limited at this time. 1728 1729 switch(key) { 1730 case "volume" : 1731 this.volume(value); 1732 break; 1733 case "muted" : 1734 this._muted(value); 1735 break; 1736 case "cssSelectorAncestor" : 1737 this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor. 1738 break; 1739 case "cssSelector" : 1740 $.each(value, function(fn, cssSel) { 1741 self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks. 1742 }); 1743 break; 1744 case "fullScreen" : 1745 if(this.options[key] !== value) { // if changed 1746 this._removeUiClass(); 1747 this.options[key] = value; 1748 this._refreshSize(); 1749 } 1750 break; 1751 case "size" : 1752 if(!this.options.fullScreen && this.options[key].cssClass !== value.cssClass) { 1753 this._removeUiClass(); 1754 } 1755 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1756 this._refreshSize(); 1757 break; 1758 case "sizeFull" : 1759 if(this.options.fullScreen && this.options[key].cssClass !== value.cssClass) { 1760 this._removeUiClass(); 1761 } 1762 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1763 this._refreshSize(); 1764 break; 1765 case "autohide" : 1766 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1767 this._updateAutohide(); 1768 break; 1769 case "loop" : 1770 this._loop(value); 1771 break; 1772 case "nativeVideoControls" : 1773 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1774 this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); 1775 this._restrictNativeVideoControls(); 1776 this._updateNativeVideoControls(); 1777 break; 1778 case "noFullScreen" : 1779 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1780 this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); // Need to check again as noFullScreen can depend on this flag and the restrict() can override it. 1781 this.status.noFullScreen = this._uaBlocklist(this.options.noFullScreen); 1782 this._restrictNativeVideoControls(); 1783 this._updateButtons(); 1784 break; 1785 case "noVolume" : 1786 this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. 1787 this.status.noVolume = this._uaBlocklist(this.options.noVolume); 1788 this._updateVolume(); 1789 this._updateMute(); 1790 break; 1791 case "emulateHtml" : 1792 if(this.options[key] !== value) { // To avoid multiple event handlers being created, if true already. 1793 this.options[key] = value; 1794 if(value) { 1795 this._emulateHtmlBridge(); 1796 } else { 1797 this._destroyHtmlBridge(); 1798 } 1799 } 1800 break; 1801 } 1802 1803 return this; 1804 }, 1805 // End of: (Options code adapted from ui.widget.js) 1806 1807 _refreshSize: function() { 1808 this._setSize(); // update status and jPlayer element size 1809 this._addUiClass(); // update the ui class 1810 this._updateSize(); // update internal sizes 1811 this._updateButtons(); 1812 this._updateAutohide(); 1813 this._trigger($.jPlayer.event.resize); 1814 }, 1815 _setSize: function() { 1816 // Determine the current size from the options 1817 if(this.options.fullScreen) { 1818 this.status.width = this.options.sizeFull.width; 1819 this.status.height = this.options.sizeFull.height; 1820 this.status.cssClass = this.options.sizeFull.cssClass; 1821 } else { 1822 this.status.width = this.options.size.width; 1823 this.status.height = this.options.size.height; 1824 this.status.cssClass = this.options.size.cssClass; 1825 } 1826 1827 // Set the size of the jPlayer area. 1828 this.element.css({'width': this.status.width, 'height': this.status.height}); 1829 }, 1830 _addUiClass: function() { 1831 if(this.ancestorJq.length) { 1832 this.ancestorJq.addClass(this.status.cssClass); 1833 } 1834 }, 1835 _removeUiClass: function() { 1836 if(this.ancestorJq.length) { 1837 this.ancestorJq.removeClass(this.status.cssClass); 1838 } 1839 }, 1840 _updateSize: function() { 1841 // The poster uses show/hide so can simply resize it. 1842 this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height}); 1843 1844 // Video html or flash resized if necessary at this time, or if native video controls being used. 1845 if(!this.status.waitForPlay && this.html.active && this.status.video || this.html.video.available && this.html.used && this.status.nativeVideoControls) { 1846 this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); 1847 } 1848 else if(!this.status.waitForPlay && this.flash.active && this.status.video) { 1849 this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); 1850 } 1851 }, 1852 _updateAutohide: function() { 1853 var self = this, 1854 event = "mousemove.jPlayer", 1855 namespace = ".jPlayerAutohide", 1856 eventType = event + namespace, 1857 handler = function() { 1858 self.css.jq.gui.fadeIn(self.options.autohide.fadeIn, function() { 1859 clearTimeout(self.internal.autohideId); 1860 self.internal.autohideId = setTimeout( function() { 1861 self.css.jq.gui.fadeOut(self.options.autohide.fadeOut); 1862 }, self.options.autohide.hold); 1863 }); 1864 }; 1865 1866 if(this.css.jq.gui.length) { 1867 1868 // End animations first so that its callback is executed now. 1869 // Otherwise an in progress fadeIn animation still has the callback to fadeOut again. 1870 this.css.jq.gui.stop(true, true); 1871 1872 // Removes the fadeOut operation from the fadeIn callback. 1873 clearTimeout(this.internal.autohideId); 1874 1875 this.element.unbind(namespace); 1876 this.css.jq.gui.unbind(namespace); 1877 1878 if(!this.status.nativeVideoControls) { 1879 if(this.options.fullScreen && this.options.autohide.full || !this.options.fullScreen && this.options.autohide.restored) { 1880 this.element.bind(eventType, handler); 1881 this.css.jq.gui.bind(eventType, handler); 1882 this.css.jq.gui.hide(); 1883 } else { 1884 this.css.jq.gui.show(); 1885 } 1886 } else { 1887 this.css.jq.gui.hide(); 1888 } 1889 } 1890 }, 1891 fullScreen: function() { 1892 this._setOption("fullScreen", true); 1893 }, 1894 restoreScreen: function() { 1895 this._setOption("fullScreen", false); 1896 }, 1897 _html_initMedia: function() { 1898 this.htmlElement.media.src = this.status.src; 1899 1900 if(this.options.preload !== 'none') { 1901 this._html_load(); // See function for comments 1902 } 1903 this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution. 1904 }, 1905 _html_setAudio: function(media) { 1906 var self = this; 1907 // Always finds a format due to checks in setMedia() 1908 $.each(this.formats, function(priority, format) { 1909 if(self.html.support[format] && media[format]) { 1910 self.status.src = media[format]; 1911 self.status.format[format] = true; 1912 self.status.formatType = format; 1913 return false; 1914 } 1915 }); 1916 this.htmlElement.media = this.htmlElement.audio; 1917 this._html_initMedia(); 1918 }, 1919 _html_setVideo: function(media) { 1920 var self = this; 1921 // Always finds a format due to checks in setMedia() 1922 $.each(this.formats, function(priority, format) { 1923 if(self.html.support[format] && media[format]) { 1924 self.status.src = media[format]; 1925 self.status.format[format] = true; 1926 self.status.formatType = format; 1927 return false; 1928 } 1929 }); 1930 if(this.status.nativeVideoControls) { 1931 this.htmlElement.video.poster = this._validString(media.poster) ? media.poster : ""; 1932 } 1933 this.htmlElement.media = this.htmlElement.video; 1934 this._html_initMedia(); 1935 }, 1936 _html_resetMedia: function() { 1937 if(this.htmlElement.media) { 1938 if(this.htmlElement.media.id === this.internal.video.id && !this.status.nativeVideoControls) { 1939 this.internal.video.jq.css({'width':'0px', 'height':'0px'}); 1940 } 1941 this.htmlElement.media.pause(); 1942 } 1943 }, 1944 _html_clearMedia: function() { 1945 if(this.htmlElement.media) { 1946 this.htmlElement.media.src = ""; 1947 this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress. 1948 } 1949 }, 1950 _html_load: function() { 1951 // This function remains to allow the early HTML5 browsers to work, such as Firefox 3.6 1952 // A change in the W3C spec for the media.load() command means that this is no longer necessary. 1953 // This command should be removed and actually causes minor undesirable effects on some browsers. Such as loading the whole file and not only the metadata. 1954 if(this.status.waitForLoad) { 1955 this.status.waitForLoad = false; 1956 this.htmlElement.media.load(); 1957 } 1958 clearTimeout(this.internal.htmlDlyCmdId); 1959 }, 1960 _html_play: function(time) { 1961 var self = this; 1962 this._html_load(); // Loads if required and clears any delayed commands. 1963 1964 this.htmlElement.media.play(); // Before currentTime attempt otherwise Firefox 4 Beta never loads. 1965 1966 if(!isNaN(time)) { 1967 try { 1968 this.htmlElement.media.currentTime = time; 1969 } catch(err) { 1970 this.internal.htmlDlyCmdId = setTimeout(function() { 1971 self.play(time); 1972 }, 100); 1973 return; // Cancel execution and wait for the delayed command. 1974 } 1975 } 1976 this._html_checkWaitForPlay(); 1977 }, 1978 _html_pause: function(time) { 1979 var self = this; 1980 1981 if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation. 1982 this._html_load(); // Loads if required and clears any delayed commands. 1983 } else { 1984 clearTimeout(this.internal.htmlDlyCmdId); 1985 } 1986 1987 // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime. 1988 this.htmlElement.media.pause(); 1989 1990 if(!isNaN(time)) { 1991 try { 1992 this.htmlElement.media.currentTime = time; 1993 } catch(err) { 1994 this.internal.htmlDlyCmdId = setTimeout(function() { 1995 self.pause(time); 1996 }, 100); 1997 return; // Cancel execution and wait for the delayed command. 1998 } 1999 } 2000 if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. 2001 this._html_checkWaitForPlay(); 2002 } 2003 }, 2004 _html_playHead: function(percent) { 2005 var self = this; 2006 this._html_load(); // Loads if required and clears any delayed commands. 2007 try { 2008 if((typeof this.htmlElement.media.seekable === "object") && (this.htmlElement.media.seekable.length > 0)) { 2009 this.htmlElement.media.currentTime = percent * this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1) / 100; 2010 } else if(this.htmlElement.media.duration > 0 && !isNaN(this.htmlElement.media.duration)) { 2011 this.htmlElement.media.currentTime = percent * this.htmlElement.media.duration / 100; 2012 } else { 2013 throw "e"; 2014 } 2015 } catch(err) { 2016 this.internal.htmlDlyCmdId = setTimeout(function() { 2017 self.playHead(percent); 2018 }, 100); 2019 return; // Cancel execution and wait for the delayed command. 2020 } 2021 if(!this.status.waitForLoad) { 2022 this._html_checkWaitForPlay(); 2023 } 2024 }, 2025 _html_checkWaitForPlay: function() { 2026 if(this.status.waitForPlay) { 2027 this.status.waitForPlay = false; 2028 if(this.css.jq.videoPlay.length) { 2029 this.css.jq.videoPlay.hide(); 2030 } 2031 if(this.status.video) { 2032 this.internal.poster.jq.hide(); 2033 this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); 2034 } 2035 } 2036 }, 2037 _html_volume: function(v) { 2038 if(this.html.audio.available) { 2039 this.htmlElement.audio.volume = v; 2040 } 2041 if(this.html.video.available) { 2042 this.htmlElement.video.volume = v; 2043 } 2044 }, 2045 _html_mute: function(m) { 2046 if(this.html.audio.available) { 2047 this.htmlElement.audio.muted = m; 2048 } 2049 if(this.html.video.available) { 2050 this.htmlElement.video.muted = m; 2051 } 2052 }, 2053 _flash_setAudio: function(media) { 2054 var self = this; 2055 try { 2056 // Always finds a format due to checks in setMedia() 2057 $.each(this.formats, function(priority, format) { 2058 if(self.flash.support[format] && media[format]) { 2059 switch (format) { 2060 case "m4a" : 2061 case "fla" : 2062 self._getMovie().fl_setAudio_m4a(media[format]); 2063 break; 2064 case "mp3" : 2065 self._getMovie().fl_setAudio_mp3(media[format]); 2066 break; 2067 } 2068 self.status.src = media[format]; 2069 self.status.format[format] = true; 2070 self.status.formatType = format; 2071 return false; 2072 } 2073 }); 2074 2075 if(this.options.preload === 'auto') { 2076 this._flash_load(); 2077 this.status.waitForLoad = false; 2078 } 2079 } catch(err) { this._flashError(err); } 2080 }, 2081 _flash_setVideo: function(media) { 2082 var self = this; 2083 try { 2084 // Always finds a format due to checks in setMedia() 2085 $.each(this.formats, function(priority, format) { 2086 if(self.flash.support[format] && media[format]) { 2087 switch (format) { 2088 case "m4v" : 2089 case "flv" : 2090 self._getMovie().fl_setVideo_m4v(media[format]); 2091 break; 2092 } 2093 self.status.src = media[format]; 2094 self.status.format[format] = true; 2095 self.status.formatType = format; 2096 return false; 2097 } 2098 }); 2099 2100 if(this.options.preload === 'auto') { 2101 this._flash_load(); 2102 this.status.waitForLoad = false; 2103 } 2104 } catch(err) { this._flashError(err); } 2105 }, 2106 _flash_resetMedia: function() { 2107 this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE. 2108 this._flash_pause(NaN); 2109 }, 2110 _flash_clearMedia: function() { 2111 try { 2112 this._getMovie().fl_clearMedia(); 2113 } catch(err) { this._flashError(err); } 2114 }, 2115 _flash_load: function() { 2116 try { 2117 this._getMovie().fl_load(); 2118 } catch(err) { this._flashError(err); } 2119 this.status.waitForLoad = false; 2120 }, 2121 _flash_play: function(time) { 2122 try { 2123 this._getMovie().fl_play(time); 2124 } catch(err) { this._flashError(err); } 2125 this.status.waitForLoad = false; 2126 this._flash_checkWaitForPlay(); 2127 }, 2128 _flash_pause: function(time) { 2129 try { 2130 this._getMovie().fl_pause(time); 2131 } catch(err) { this._flashError(err); } 2132 if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. 2133 this.status.waitForLoad = false; 2134 this._flash_checkWaitForPlay(); 2135 } 2136 }, 2137 _flash_playHead: function(p) { 2138 try { 2139 this._getMovie().fl_play_head(p); 2140 } catch(err) { this._flashError(err); } 2141 if(!this.status.waitForLoad) { 2142 this._flash_checkWaitForPlay(); 2143 } 2144 }, 2145 _flash_checkWaitForPlay: function() { 2146 if(this.status.waitForPlay) { 2147 this.status.waitForPlay = false; 2148 if(this.css.jq.videoPlay.length) { 2149 this.css.jq.videoPlay.hide(); 2150 } 2151 if(this.status.video) { 2152 this.internal.poster.jq.hide(); 2153 this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); 2154 } 2155 } 2156 }, 2157 _flash_volume: function(v) { 2158 try { 2159 this._getMovie().fl_volume(v); 2160 } catch(err) { this._flashError(err); } 2161 }, 2162 _flash_mute: function(m) { 2163 try { 2164 this._getMovie().fl_mute(m); 2165 } catch(err) { this._flashError(err); } 2166 }, 2167 _getMovie: function() { 2168 return document[this.internal.flash.id]; 2169 }, 2170 _checkForFlash: function (version) { 2171 // Function checkForFlash adapted from FlashReplace by Robert Nyman 2172 // http://code.google.com/p/flashreplace/ 2173 var flashIsInstalled = false; 2174 var flash; 2175 if(window.ActiveXObject){ 2176 try{ 2177 flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version)); 2178 flashIsInstalled = true; 2179 } 2180 catch(e){ 2181 // Throws an error if the version isn't available 2182 } 2183 } 2184 else if(navigator.plugins && navigator.mimeTypes.length > 0){ 2185 flash = navigator.plugins["Shockwave Flash"]; 2186 if(flash){ 2187 var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1"); 2188 if(flashVersion >= version){ 2189 flashIsInstalled = true; 2190 } 2191 } 2192 } 2193 return flashIsInstalled; 2194 }, 2195 _validString: function(url) { 2196 return (url && typeof url === "string"); // Empty strings return false 2197 }, 2198 _limitValue: function(value, min, max) { 2199 return (value < min) ? min : ((value > max) ? max : value); 2200 }, 2201 _urlNotSetError: function(context) { 2202 this._error( { 2203 type: $.jPlayer.error.URL_NOT_SET, 2204 context: context, 2205 message: $.jPlayer.errorMsg.URL_NOT_SET, 2206 hint: $.jPlayer.errorHint.URL_NOT_SET 2207 }); 2208 }, 2209 _flashError: function(error) { 2210 var errorType; 2211 if(!this.internal.ready) { 2212 errorType = "FLASH"; 2213 } else { 2214 errorType = "FLASH_DISABLED"; 2215 } 2216 this._error( { 2217 type: $.jPlayer.error[errorType], 2218 context: this.internal.flash.swf, 2219 message: $.jPlayer.errorMsg[errorType] + error.message, 2220 hint: $.jPlayer.errorHint[errorType] 2221 }); 2222 // Allow the audio player to recover if display:none and then shown again, or with position:fixed on Firefox. 2223 // This really only affects audio in a media player, as an audio player could easily move the jPlayer element away from such issues. 2224 this.internal.flash.jq.css({'width':'1px', 'height':'1px'}); 2225 }, 2226 _error: function(error) { 2227 this._trigger($.jPlayer.event.error, error); 2228 if(this.options.errorAlerts) { 2229 this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context); 2230 } 2231 }, 2232 _warning: function(warning) { 2233 this._trigger($.jPlayer.event.warning, undefined, warning); 2234 if(this.options.warningAlerts) { 2235 this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context); 2236 } 2237 }, 2238 _alert: function(message) { 2239 alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message); 2240 }, 2241 _emulateHtmlBridge: function() { 2242 var self = this, 2243 methods = $.jPlayer.emulateMethods; 2244 2245 // Emulate methods on jPlayer's DOM element. 2246 $.each( $.jPlayer.emulateMethods.split(/\s+/g), function(i, name) { 2247 self.internal.domNode[name] = function(arg) { 2248 self[name](arg); 2249 }; 2250 2251 }); 2252 2253 // Bubble jPlayer events to its DOM element. 2254 $.each($.jPlayer.event, function(eventName,eventType) { 2255 var nativeEvent = true; 2256 $.each( $.jPlayer.reservedEvent.split(/\s+/g), function(i, name) { 2257 if(name === eventName) { 2258 nativeEvent = false; 2259 return false; 2260 } 2261 }); 2262 if(nativeEvent) { 2263 self.element.bind(eventType + ".jPlayer.jPlayerHtml", function() { // With .jPlayer & .jPlayerHtml namespaces. 2264 self._emulateHtmlUpdate(); 2265 var domEvent = document.createEvent("Event"); 2266 domEvent.initEvent(eventName, false, true); 2267 self.internal.domNode.dispatchEvent(domEvent); 2268 }); 2269 } 2270 // The error event would require a special case 2271 }); 2272 2273 // IE9 has a readyState property on all elements. The document should have it, but all (except media) elements inherit it in IE9. This conflicts with Popcorn, which polls the readyState. 2274 }, 2275 _emulateHtmlUpdate: function() { 2276 var self = this; 2277 2278 $.each( $.jPlayer.emulateStatus.split(/\s+/g), function(i, name) { 2279 self.internal.domNode[name] = self.status[name]; 2280 }); 2281 $.each( $.jPlayer.emulateOptions.split(/\s+/g), function(i, name) { 2282 self.internal.domNode[name] = self.options[name]; 2283 }); 2284 }, 2285 _destroyHtmlBridge: function() { 2286 var self = this; 2287 2288 // Bridge event handlers are also removed by destroy() through .jPlayer namespace. 2289 this.element.unbind(".jPlayerHtml"); // Remove all event handlers created by the jPlayer bridge. So you can change the emulateHtml option. 2290 2291 // Remove the methods and properties 2292 var emulated = $.jPlayer.emulateMethods + " " + $.jPlayer.emulateStatus + " " + $.jPlayer.emulateOptions; 2293 $.each( emulated.split(/\s+/g), function(i, name) { 2294 delete self.internal.domNode[name]; 2295 }); 2296 } 2297 }; 2298 2299 $.jPlayer.error = { 2300 FLASH: "e_flash", 2301 FLASH_DISABLED: "e_flash_disabled", 2302 NO_SOLUTION: "e_no_solution", 2303 NO_SUPPORT: "e_no_support", 2304 URL: "e_url", 2305 URL_NOT_SET: "e_url_not_set", 2306 VERSION: "e_version" 2307 }; 2308 2309 $.jPlayer.errorMsg = { 2310 FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError() 2311 FLASH_DISABLED: "jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ", // Used in: _flashError() 2312 NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init() 2313 NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia() 2314 URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners() 2315 URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead() 2316 VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady() 2317 }; 2318 2319 $.jPlayer.errorHint = { 2320 FLASH: "Check your swfPath option and that Jplayer.swf is there.", 2321 FLASH_DISABLED: "Check that you have not display:none; the jPlayer entity or any ancestor.", 2322 NO_SOLUTION: "Review the jPlayer options: support and supplied.", 2323 NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.", 2324 URL: "Check media URL is valid.", 2325 URL_NOT_SET: "Use setMedia() to set the media URL.", 2326 VERSION: "Update jPlayer files." 2327 }; 2328 2329 $.jPlayer.warning = { 2330 CSS_SELECTOR_COUNT: "e_css_selector_count", 2331 CSS_SELECTOR_METHOD: "e_css_selector_method", 2332 CSS_SELECTOR_STRING: "e_css_selector_string", 2333 OPTION_KEY: "e_option_key" 2334 }; 2335 2336 $.jPlayer.warningMsg = { 2337 CSS_SELECTOR_COUNT: "The number of css selectors found did not equal one: ", 2338 CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.", 2339 CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.", 2340 OPTION_KEY: "The option requested in jPlayer('option') is undefined." 2341 }; 2342 2343 $.jPlayer.warningHint = { 2344 CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.", 2345 CSS_SELECTOR_METHOD: "Check your method name.", 2346 CSS_SELECTOR_STRING: "Check your css selector is a string.", 2347 OPTION_KEY: "Check your option name." 2348 }; 2349 })(jQuery); 14 (function(b,f){"function"===typeof define&&define.amd?define(["jquery"],f):b.jQuery?f(b.jQuery):f(b.Zepto)})(this,function(b,f){b.fn.jPlayer=function(a){var c="string"===typeof a,d=Array.prototype.slice.call(arguments,1),e=this;a=!c&&d.length?b.extend.apply(null,[!0,a].concat(d)):a;if(c&&"_"===a.charAt(0))return e;c?this.each(function(){var c=b(this).data("jPlayer"),h=c&&b.isFunction(c[a])?c[a].apply(c,d):c;if(h!==c&&h!==f)return e=h,!1}):this.each(function(){var c=b(this).data("jPlayer");c?c.option(a|| 15 {}):b(this).data("jPlayer",new b.jPlayer(a,this))});return e};b.jPlayer=function(a,c){if(arguments.length){this.element=b(c);this.options=b.extend(!0,{},this.options,a);var d=this;this.element.bind("remove.jPlayer",function(){d.destroy()});this._init()}};"function"!==typeof b.fn.stop&&(b.fn.stop=function(){});b.jPlayer.emulateMethods="load play pause";b.jPlayer.emulateStatus="src readyState networkState currentTime duration paused ended playbackRate";b.jPlayer.emulateOptions="muted volume";b.jPlayer.reservedEvent= 16 "ready flashreset resize repeat error warning";b.jPlayer.event={};b.each("ready flashreset resize repeat click error warning loadstart progress suspend abort emptied stalled play pause loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange".split(" "),function(){b.jPlayer.event[this]="jPlayer_"+this});b.jPlayer.htmlEvent="loadstart abort emptied stalled loadedmetadata loadeddata canplay canplaythrough".split(" ");b.jPlayer.pause= 17 function(){b.each(b.jPlayer.prototype.instances,function(a,c){c.data("jPlayer").status.srcSet&&c.jPlayer("pause")})};b.jPlayer.timeFormat={showHour:!1,showMin:!0,showSec:!0,padHour:!1,padMin:!0,padSec:!0,sepHour:":",sepMin:":",sepSec:""};var m=function(){this.init()};m.prototype={init:function(){this.options={timeFormat:b.jPlayer.timeFormat}},time:function(a){var c=new Date(1E3*(a&&"number"===typeof a?a:0)),b=c.getUTCHours();a=this.options.timeFormat.showHour?c.getUTCMinutes():c.getUTCMinutes()+60* 18 b;c=this.options.timeFormat.showMin?c.getUTCSeconds():c.getUTCSeconds()+60*a;b=this.options.timeFormat.padHour&&10>b?"0"+b:b;a=this.options.timeFormat.padMin&&10>a?"0"+a:a;c=this.options.timeFormat.padSec&&10>c?"0"+c:c;b=""+(this.options.timeFormat.showHour?b+this.options.timeFormat.sepHour:"");b+=this.options.timeFormat.showMin?a+this.options.timeFormat.sepMin:"";return b+=this.options.timeFormat.showSec?c+this.options.timeFormat.sepSec:""}};var n=new m;b.jPlayer.convertTime=function(a){return n.time(a)}; 19 b.jPlayer.uaBrowser=function(a){a=a.toLowerCase();var c=/(opera)(?:.*version)?[ \/]([\w.]+)/,b=/(msie) ([\w.]+)/,e=/(mozilla)(?:.*? rv:([\w.]+))?/;a=/(webkit)[ \/]([\w.]+)/.exec(a)||c.exec(a)||b.exec(a)||0>a.indexOf("compatible")&&e.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};b.jPlayer.uaPlatform=function(a){var c=a.toLowerCase(),b=/(android)/,e=/(mobile)/;a=/(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/.exec(c)||[];c=/(ipad|playbook)/.exec(c)||!e.exec(c)&&b.exec(c)|| 20 [];a[1]&&(a[1]=a[1].replace(/\s/g,"_"));return{platform:a[1]||"",tablet:c[1]||""}};b.jPlayer.browser={};b.jPlayer.platform={};var k=b.jPlayer.uaBrowser(navigator.userAgent);k.browser&&(b.jPlayer.browser[k.browser]=!0,b.jPlayer.browser.version=k.version);k=b.jPlayer.uaPlatform(navigator.userAgent);k.platform&&(b.jPlayer.platform[k.platform]=!0,b.jPlayer.platform.mobile=!k.tablet,b.jPlayer.platform.tablet=!!k.tablet);b.jPlayer.getDocMode=function(){var a;b.jPlayer.browser.msie&&(document.documentMode? 21 a=document.documentMode:(a=5,document.compatMode&&"CSS1Compat"===document.compatMode&&(a=7)));return a};b.jPlayer.browser.documentMode=b.jPlayer.getDocMode();b.jPlayer.nativeFeatures={init:function(){var a=document,c=a.createElement("video"),b={w3c:"fullscreenEnabled fullscreenElement requestFullscreen exitFullscreen fullscreenchange fullscreenerror".split(" "),moz:"mozFullScreenEnabled mozFullScreenElement mozRequestFullScreen mozCancelFullScreen mozfullscreenchange mozfullscreenerror".split(" "), 22 webkit:" webkitCurrentFullScreenElement webkitRequestFullScreen webkitCancelFullScreen webkitfullscreenchange ".split(" "),webkitVideo:"webkitSupportsFullscreen webkitDisplayingFullscreen webkitEnterFullscreen webkitExitFullscreen ".split(" ")},e=["w3c","moz","webkit","webkitVideo"],g,h;this.fullscreen=c={support:{w3c:!!a[b.w3c[0]],moz:!!a[b.moz[0]],webkit:"function"===typeof a[b.webkit[3]],webkitVideo:"function"===typeof c[b.webkitVideo[2]]},used:{}};g=0;for(h=e.length;g<h;g++){var f=e[g];if(c.support[f]){c.spec= 23 f;c.used[f]=!0;break}}if(c.spec){var l=b[c.spec];c.api={fullscreenEnabled:!0,fullscreenElement:function(c){c=c?c:a;return c[l[1]]},requestFullscreen:function(a){return a[l[2]]()},exitFullscreen:function(c){c=c?c:a;return c[l[3]]()}};c.event={fullscreenchange:l[4],fullscreenerror:l[5]}}else c.api={fullscreenEnabled:!1,fullscreenElement:function(){return null},requestFullscreen:function(){},exitFullscreen:function(){}},c.event={}}};b.jPlayer.nativeFeatures.init();b.jPlayer.focus=null;b.jPlayer.keyIgnoreElementNames= 24 "INPUT TEXTAREA";var p=function(a){var c=b.jPlayer.focus,d;c&&(b.each(b.jPlayer.keyIgnoreElementNames.split(/\s+/g),function(c,b){if(a.target.nodeName.toUpperCase()===b.toUpperCase())return d=!0,!1}),d||b.each(c.options.keyBindings,function(d,g){if(g&&a.which===g.key&&b.isFunction(g.fn))return a.preventDefault(),g.fn(c),!1}))};b.jPlayer.keys=function(a){b(document.documentElement).unbind("keydown.jPlayer");a&&b(document.documentElement).bind("keydown.jPlayer",p)};b.jPlayer.keys(!0);b.jPlayer.prototype= 25 {count:0,version:{script:"2.5.0",needFlash:"2.5.0",flash:"unknown"},options:{swfPath:"js",solution:"html, flash",supplied:"mp3",preload:"metadata",volume:0.8,muted:!1,playbackRate:1,defaultPlaybackRate:1,minPlaybackRate:0.5,maxPlaybackRate:4,wmode:"opaque",backgroundColor:"#000000",cssSelectorAncestor:"#jp_container_1",cssSelector:{videoPlay:".jp-video-play",play:".jp-play",pause:".jp-pause",stop:".jp-stop",seekBar:".jp-seek-bar",playBar:".jp-play-bar",mute:".jp-mute",unmute:".jp-unmute",volumeBar:".jp-volume-bar", 26 volumeBarValue:".jp-volume-bar-value",volumeMax:".jp-volume-max",playbackRateBar:".jp-playback-rate-bar",playbackRateBarValue:".jp-playback-rate-bar-value",currentTime:".jp-current-time",duration:".jp-duration",fullScreen:".jp-full-screen",restoreScreen:".jp-restore-screen",repeat:".jp-repeat",repeatOff:".jp-repeat-off",gui:".jp-gui",noSolution:".jp-no-solution"},smoothPlayBar:!1,fullScreen:!1,fullWindow:!1,autohide:{restored:!1,full:!0,fadeIn:200,fadeOut:600,hold:1E3},loop:!1,repeat:function(a){a.jPlayer.options.loop? 27 b(this).unbind(".jPlayerRepeat").bind(b.jPlayer.event.ended+".jPlayer.jPlayerRepeat",function(){b(this).jPlayer("play")}):b(this).unbind(".jPlayerRepeat")},nativeVideoControls:{},noFullWindow:{msie:/msie [0-6]\./,ipad:/ipad.*?os [0-4]\./,iphone:/iphone/,ipod:/ipod/,android_pad:/android [0-3]\.(?!.*?mobile)/,android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/},noVolume:{ipad:/ipad/,iphone:/iphone/,ipod:/ipod/,android_pad:/android(?!.*?mobile)/, 28 android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/,playbook:/playbook/},timeFormat:{},keyEnabled:!1,audioFullScreen:!1,keyBindings:{play:{key:32,fn:function(a){a.status.paused?a.play():a.pause()}},fullScreen:{key:13,fn:function(a){(a.status.video||a.options.audioFullScreen)&&a._setOption("fullScreen",!a.options.fullScreen)}},muted:{key:8,fn:function(a){a._muted(!a.options.muted)}},volumeUp:{key:38,fn:function(a){a.volume(a.options.volume+ 29 0.1)}},volumeDown:{key:40,fn:function(a){a.volume(a.options.volume-0.1)}}},verticalVolume:!1,verticalPlaybackRate:!1,globalVolume:!1,idPrefix:"jp",noConflict:"jQuery",emulateHtml:!1,consoleAlerts:!0,errorAlerts:!1,warningAlerts:!1},optionsAudio:{size:{width:"0px",height:"0px",cssClass:""},sizeFull:{width:"0px",height:"0px",cssClass:""}},optionsVideo:{size:{width:"480px",height:"270px",cssClass:"jp-video-270p"},sizeFull:{width:"100%",height:"100%",cssClass:"jp-video-full"}},instances:{},status:{src:"", 30 media:{},paused:!0,format:{},formatType:"",waitForPlay:!0,waitForLoad:!0,srcSet:!1,video:!1,seekPercent:0,currentPercentRelative:0,currentPercentAbsolute:0,currentTime:0,duration:0,videoWidth:0,videoHeight:0,readyState:0,networkState:0,playbackRate:1,ended:0},internal:{ready:!1},solution:{html:!0,flash:!0},format:{mp3:{codec:'audio/mpeg; codecs="mp3"',flashCanPlay:!0,media:"audio"},m4a:{codec:'audio/mp4; codecs="mp4a.40.2"',flashCanPlay:!0,media:"audio"},m3u8a:{codec:'application/vnd.apple.mpegurl; codecs="mp4a.40.2"', 31 flashCanPlay:!1,media:"audio"},m3ua:{codec:"audio/mpegurl",flashCanPlay:!1,media:"audio"},oga:{codec:'audio/ogg; codecs="vorbis, opus"',flashCanPlay:!1,media:"audio"},flac:{codec:"audio/x-flac",flashCanPlay:!1,media:"audio"},wav:{codec:'audio/wav; codecs="1"',flashCanPlay:!1,media:"audio"},webma:{codec:'audio/webm; codecs="vorbis"',flashCanPlay:!1,media:"audio"},fla:{codec:"audio/x-flv",flashCanPlay:!0,media:"audio"},rtmpa:{codec:'audio/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"audio"},m4v:{codec:'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', 32 flashCanPlay:!0,media:"video"},m3u8v:{codec:'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!1,media:"video"},m3uv:{codec:"audio/mpegurl",flashCanPlay:!1,media:"video"},ogv:{codec:'video/ogg; codecs="theora, vorbis"',flashCanPlay:!1,media:"video"},webmv:{codec:'video/webm; codecs="vorbis, vp8"',flashCanPlay:!1,media:"video"},flv:{codec:"video/x-flv",flashCanPlay:!0,media:"video"},rtmpv:{codec:'video/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"video"}},_init:function(){var a= 33 this;this.element.empty();this.status=b.extend({},this.status);this.internal=b.extend({},this.internal);this.options.timeFormat=b.extend({},b.jPlayer.timeFormat,this.options.timeFormat);this.internal.cmdsIgnored=b.jPlayer.platform.ipad||b.jPlayer.platform.iphone||b.jPlayer.platform.ipod;this.internal.domNode=this.element.get(0);this.options.keyEnabled&&!b.jPlayer.focus&&(b.jPlayer.focus=this);this.formats=[];this.solutions=[];this.require={};this.htmlElement={};this.html={};this.html.audio={};this.html.video= 34 {};this.flash={};this.css={};this.css.cs={};this.css.jq={};this.ancestorJq=[];this.options.volume=this._limitValue(this.options.volume,0,1);b.each(this.options.supplied.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.format[e]){var f=!1;b.each(a.formats,function(a,c){if(e===c)return f=!0,!1});f||a.formats.push(e)}});b.each(this.options.solution.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.solution[e]){var f=!1;b.each(a.solutions,function(a, 35 c){if(e===c)return f=!0,!1});f||a.solutions.push(e)}});this.internal.instance="jp_"+this.count;this.instances[this.internal.instance]=this.element;this.element.attr("id")||this.element.attr("id",this.options.idPrefix+"_jplayer_"+this.count);this.internal.self=b.extend({},{id:this.element.attr("id"),jq:this.element});this.internal.audio=b.extend({},{id:this.options.idPrefix+"_audio_"+this.count,jq:f});this.internal.video=b.extend({},{id:this.options.idPrefix+"_video_"+this.count,jq:f});this.internal.flash= 36 b.extend({},{id:this.options.idPrefix+"_flash_"+this.count,jq:f,swf:this.options.swfPath+(".swf"!==this.options.swfPath.toLowerCase().slice(-4)?(this.options.swfPath&&"/"!==this.options.swfPath.slice(-1)?"/":"")+"Jplayer.swf":"")});this.internal.poster=b.extend({},{id:this.options.idPrefix+"_poster_"+this.count,jq:f});b.each(b.jPlayer.event,function(c,b){a.options[c]!==f&&(a.element.bind(b+".jPlayer",a.options[c]),a.options[c]=f)});this.require.audio=!1;this.require.video=!1;b.each(this.formats,function(c, 37 b){a.require[a.format[b].media]=!0});this.options=this.require.video?b.extend(!0,{},this.optionsVideo,this.options):b.extend(!0,{},this.optionsAudio,this.options);this._setSize();this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullWindow=this._uaBlocklist(this.options.noFullWindow);this.status.noVolume=this._uaBlocklist(this.options.noVolume);b.jPlayer.nativeFeatures.fullscreen.api.fullscreenEnabled&&this._fullscreenAddEventListeners();this._restrictNativeVideoControls(); 38 this.htmlElement.poster=document.createElement("img");this.htmlElement.poster.id=this.internal.poster.id;this.htmlElement.poster.onload=function(){a.status.video&&!a.status.waitForPlay||a.internal.poster.jq.show()};this.element.append(this.htmlElement.poster);this.internal.poster.jq=b("#"+this.internal.poster.id);this.internal.poster.jq.css({width:this.status.width,height:this.status.height});this.internal.poster.jq.hide();this.internal.poster.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)}); 39 this.html.audio.available=!1;this.require.audio&&(this.htmlElement.audio=document.createElement("audio"),this.htmlElement.audio.id=this.internal.audio.id,this.html.audio.available=!!this.htmlElement.audio.canPlayType&&this._testCanPlayType(this.htmlElement.audio));this.html.video.available=!1;this.require.video&&(this.htmlElement.video=document.createElement("video"),this.htmlElement.video.id=this.internal.video.id,this.html.video.available=!!this.htmlElement.video.canPlayType&&this._testCanPlayType(this.htmlElement.video)); 40 this.flash.available=this._checkForFlash(10.1);this.html.canPlay={};this.flash.canPlay={};b.each(this.formats,function(c,b){a.html.canPlay[b]=a.html[a.format[b].media].available&&""!==a.htmlElement[a.format[b].media].canPlayType(a.format[b].codec);a.flash.canPlay[b]=a.format[b].flashCanPlay&&a.flash.available});this.html.desired=!1;this.flash.desired=!1;b.each(this.solutions,function(c,d){if(0===c)a[d].desired=!0;else{var e=!1,f=!1;b.each(a.formats,function(c,b){a[a.solutions[0]].canPlay[b]&&("video"=== 41 a.format[b].media?f=!0:e=!0)});a[d].desired=a.require.audio&&!e||a.require.video&&!f}});this.html.support={};this.flash.support={};b.each(this.formats,function(c,b){a.html.support[b]=a.html.canPlay[b]&&a.html.desired;a.flash.support[b]=a.flash.canPlay[b]&&a.flash.desired});this.html.used=!1;this.flash.used=!1;b.each(this.solutions,function(c,d){b.each(a.formats,function(c,b){if(a[d].support[b])return a[d].used=!0,!1})});this._resetActive();this._resetGate();this._cssSelectorAncestor(this.options.cssSelectorAncestor); 42 this.html.used||this.flash.used?this.css.jq.noSolution.length&&this.css.jq.noSolution.hide():(this._error({type:b.jPlayer.error.NO_SOLUTION,context:"{solution:'"+this.options.solution+"', supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SOLUTION,hint:b.jPlayer.errorHint.NO_SOLUTION}),this.css.jq.noSolution.length&&this.css.jq.noSolution.show());if(this.flash.used){var c,d="jQuery="+encodeURI(this.options.noConflict)+"&id="+encodeURI(this.internal.self.id)+"&vol="+this.options.volume+ 43 "&muted="+this.options.muted;if(b.jPlayer.browser.msie&&(9>Number(b.jPlayer.browser.version)||9>b.jPlayer.browser.documentMode)){d=['<param name="movie" value="'+this.internal.flash.swf+'" />','<param name="FlashVars" value="'+d+'" />','<param name="allowScriptAccess" value="always" />','<param name="bgcolor" value="'+this.options.backgroundColor+'" />','<param name="wmode" value="'+this.options.wmode+'" />'];c=document.createElement('<object id="'+this.internal.flash.id+'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0" tabindex="-1"></object>'); 44 for(var e=0;e<d.length;e++)c.appendChild(document.createElement(d[e]))}else e=function(a,c,b){var d=document.createElement("param");d.setAttribute("name",c);d.setAttribute("value",b);a.appendChild(d)},c=document.createElement("object"),c.setAttribute("id",this.internal.flash.id),c.setAttribute("name",this.internal.flash.id),c.setAttribute("data",this.internal.flash.swf),c.setAttribute("type","application/x-shockwave-flash"),c.setAttribute("width","1"),c.setAttribute("height","1"),c.setAttribute("tabindex", 45 "-1"),e(c,"flashvars",d),e(c,"allowscriptaccess","always"),e(c,"bgcolor",this.options.backgroundColor),e(c,"wmode",this.options.wmode);this.element.append(c);this.internal.flash.jq=b(c)}this.status.playbackRateEnabled=this.html.used&&!this.flash.used?this._testPlaybackRate("audio"):!1;this._updatePlaybackRate();this.html.used&&(this.html.audio.available&&(this._addHtmlEventListeners(this.htmlElement.audio,this.html.audio),this.element.append(this.htmlElement.audio),this.internal.audio.jq=b("#"+this.internal.audio.id)), 46 this.html.video.available&&(this._addHtmlEventListeners(this.htmlElement.video,this.html.video),this.element.append(this.htmlElement.video),this.internal.video.jq=b("#"+this.internal.video.id),this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):this.internal.video.jq.css({width:"0px",height:"0px"}),this.internal.video.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)})));this.options.emulateHtml&&this._emulateHtmlBridge(); 47 this.html.used&&!this.flash.used&&setTimeout(function(){a.internal.ready=!0;a.version.flash="n/a";a._trigger(b.jPlayer.event.repeat);a._trigger(b.jPlayer.event.ready)},100);this._updateNativeVideoControls();this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();b.jPlayer.prototype.count++},destroy:function(){this.clearMedia();this._removeUiClass();this.css.jq.currentTime.length&&this.css.jq.currentTime.text("");this.css.jq.duration.length&&this.css.jq.duration.text("");b.each(this.css.jq,function(a, 48 c){c.length&&c.unbind(".jPlayer")});this.internal.poster.jq.unbind(".jPlayer");this.internal.video.jq&&this.internal.video.jq.unbind(".jPlayer");this._fullscreenRemoveEventListeners();this===b.jPlayer.focus&&(b.jPlayer.focus=null);this.options.emulateHtml&&this._destroyHtmlBridge();this.element.removeData("jPlayer");this.element.unbind(".jPlayer");this.element.empty();delete this.instances[this.internal.instance]},enable:function(){},disable:function(){},_testCanPlayType:function(a){try{return a.canPlayType(this.format.mp3.codec), 49 !0}catch(c){return!1}},_testPlaybackRate:function(a){a=document.createElement("string"===typeof a?a:"audio");try{return"playbackRate"in a?(a.playbackRate=0.5,0.5===a.playbackRate):!1}catch(c){return!1}},_uaBlocklist:function(a){var c=navigator.userAgent.toLowerCase(),d=!1;b.each(a,function(a,b){if(b&&b.test(c))return d=!0,!1});return d},_restrictNativeVideoControls:function(){this.require.audio&&this.status.nativeVideoControls&&(this.status.nativeVideoControls=!1,this.status.noFullWindow=!0)},_updateNativeVideoControls:function(){this.html.video.available&& 50 this.html.used&&(this.htmlElement.video.controls=this.status.nativeVideoControls,this._updateAutohide(),this.status.nativeVideoControls&&this.require.video?(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})):this.status.waitForPlay&&this.status.video&&(this.internal.poster.jq.show(),this.internal.video.jq.css({width:"0px",height:"0px"})))},_addHtmlEventListeners:function(a,c){var d=this;a.preload=this.options.preload;a.muted=this.options.muted; 51 a.volume=this.options.volume;this.status.playbackRateEnabled&&(a.defaultPlaybackRate=this.options.defaultPlaybackRate,a.playbackRate=this.options.playbackRate);a.addEventListener("progress",function(){c.gate&&(d.internal.cmdsIgnored&&0<this.readyState&&(d.internal.cmdsIgnored=!1),d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.progress))},!1);a.addEventListener("timeupdate",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.timeupdate))},!1); 52 a.addEventListener("durationchange",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.durationchange))},!1);a.addEventListener("play",function(){c.gate&&(d._updateButtons(!0),d._html_checkWaitForPlay(),d._trigger(b.jPlayer.event.play))},!1);a.addEventListener("playing",function(){c.gate&&(d._updateButtons(!0),d._seeked(),d._trigger(b.jPlayer.event.playing))},!1);a.addEventListener("pause",function(){c.gate&&(d._updateButtons(!1),d._trigger(b.jPlayer.event.pause))}, 53 !1);a.addEventListener("waiting",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.waiting))},!1);a.addEventListener("seeking",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.seeking))},!1);a.addEventListener("seeked",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.seeked))},!1);a.addEventListener("volumechange",function(){c.gate&&(d.options.volume=a.volume,d.options.muted=a.muted,d._updateMute(),d._updateVolume(),d._trigger(b.jPlayer.event.volumechange))},!1);a.addEventListener("ratechange", 54 function(){c.gate&&(d.options.defaultPlaybackRate=a.defaultPlaybackRate,d.options.playbackRate=a.playbackRate,d._updatePlaybackRate(),d._trigger(b.jPlayer.event.ratechange))},!1);a.addEventListener("suspend",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.suspend))},!1);a.addEventListener("ended",function(){c.gate&&(b.jPlayer.browser.webkit||(d.htmlElement.media.currentTime=0),d.htmlElement.media.pause(),d._updateButtons(!1),d._getHtmlStatus(a,!0),d._updateInterface(),d._trigger(b.jPlayer.event.ended))}, 55 !1);a.addEventListener("error",function(){c.gate&&(d._updateButtons(!1),d._seeked(),d.status.srcSet&&(clearTimeout(d.internal.htmlDlyCmdId),d.status.waitForLoad=!0,d.status.waitForPlay=!0,d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"}),d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show(),d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show(),d._error({type:b.jPlayer.error.URL,context:d.status.src,message:b.jPlayer.errorMsg.URL, 56 hint:b.jPlayer.errorHint.URL})))},!1);b.each(b.jPlayer.htmlEvent,function(e,g){a.addEventListener(this,function(){c.gate&&d._trigger(b.jPlayer.event[g])},!1)})},_getHtmlStatus:function(a,c){var b=0,e=0,g=0,f=0;isFinite(a.duration)&&(this.status.duration=a.duration);b=a.currentTime;e=0<this.status.duration?100*b/this.status.duration:0;"object"===typeof a.seekable&&0<a.seekable.length?(g=0<this.status.duration?100*a.seekable.end(a.seekable.length-1)/this.status.duration:100,f=0<this.status.duration? 57 100*a.currentTime/a.seekable.end(a.seekable.length-1):0):(g=100,f=e);c&&(e=f=b=0);this.status.seekPercent=g;this.status.currentPercentRelative=f;this.status.currentPercentAbsolute=e;this.status.currentTime=b;this.status.videoWidth=a.videoWidth;this.status.videoHeight=a.videoHeight;this.status.readyState=a.readyState;this.status.networkState=a.networkState;this.status.playbackRate=a.playbackRate;this.status.ended=a.ended},_resetStatus:function(){this.status=b.extend({},this.status,b.jPlayer.prototype.status)}, 58 _trigger:function(a,c,d){a=b.Event(a);a.jPlayer={};a.jPlayer.version=b.extend({},this.version);a.jPlayer.options=b.extend(!0,{},this.options);a.jPlayer.status=b.extend(!0,{},this.status);a.jPlayer.html=b.extend(!0,{},this.html);a.jPlayer.flash=b.extend(!0,{},this.flash);c&&(a.jPlayer.error=b.extend({},c));d&&(a.jPlayer.warning=b.extend({},d));this.element.trigger(a)},jPlayerFlashEvent:function(a,c){if(a===b.jPlayer.event.ready)if(!this.internal.ready)this.internal.ready=!0,this.internal.flash.jq.css({width:"0px", 59 height:"0px"}),this.version.flash=c.version,this.version.needFlash!==this.version.flash&&this._error({type:b.jPlayer.error.VERSION,context:this.version.flash,message:b.jPlayer.errorMsg.VERSION+this.version.flash,hint:b.jPlayer.errorHint.VERSION}),this._trigger(b.jPlayer.event.repeat),this._trigger(a);else if(this.flash.gate){if(this.status.srcSet){var d=this.status.currentTime,e=this.status.paused;this.setMedia(this.status.media);this.volumeWorker(this.options.volume);0<d&&(e?this.pause(d):this.play(d))}this._trigger(b.jPlayer.event.flashreset)}if(this.flash.gate)switch(a){case b.jPlayer.event.progress:this._getFlashStatus(c); 60 this._updateInterface();this._trigger(a);break;case b.jPlayer.event.timeupdate:this._getFlashStatus(c);this._updateInterface();this._trigger(a);break;case b.jPlayer.event.play:this._seeked();this._updateButtons(!0);this._trigger(a);break;case b.jPlayer.event.pause:this._updateButtons(!1);this._trigger(a);break;case b.jPlayer.event.ended:this._updateButtons(!1);this._trigger(a);break;case b.jPlayer.event.click:this._trigger(a);break;case b.jPlayer.event.error:this.status.waitForLoad=!0;this.status.waitForPlay= 61 !0;this.status.video&&this.internal.flash.jq.css({width:"0px",height:"0px"});this._validString(this.status.media.poster)&&this.internal.poster.jq.show();this.css.jq.videoPlay.length&&this.status.video&&this.css.jq.videoPlay.show();this.status.video?this._flash_setVideo(this.status.media):this._flash_setAudio(this.status.media);this._updateButtons(!1);this._error({type:b.jPlayer.error.URL,context:c.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL});break;case b.jPlayer.event.seeking:this._seeking(); 62 this._trigger(a);break;case b.jPlayer.event.seeked:this._seeked();this._trigger(a);break;case b.jPlayer.event.ready:break;default:this._trigger(a)}return!1},_getFlashStatus:function(a){this.status.seekPercent=a.seekPercent;this.status.currentPercentRelative=a.currentPercentRelative;this.status.currentPercentAbsolute=a.currentPercentAbsolute;this.status.currentTime=a.currentTime;this.status.duration=a.duration;this.status.videoWidth=a.videoWidth;this.status.videoHeight=a.videoHeight;this.status.readyState= 63 4;this.status.networkState=0;this.status.playbackRate=1;this.status.ended=!1},_updateButtons:function(a){a===f?a=!this.status.paused:this.status.paused=!a;this.css.jq.play.length&&this.css.jq.pause.length&&(a?(this.css.jq.play.hide(),this.css.jq.pause.show()):(this.css.jq.play.show(),this.css.jq.pause.hide()));this.css.jq.restoreScreen.length&&this.css.jq.fullScreen.length&&(this.status.noFullWindow?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.hide()):this.options.fullWindow?(this.css.jq.fullScreen.hide(), 64 this.css.jq.restoreScreen.show()):(this.css.jq.fullScreen.show(),this.css.jq.restoreScreen.hide()));this.css.jq.repeat.length&&this.css.jq.repeatOff.length&&(this.options.loop?(this.css.jq.repeat.hide(),this.css.jq.repeatOff.show()):(this.css.jq.repeat.show(),this.css.jq.repeatOff.hide()))},_updateInterface:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.width(this.status.seekPercent+"%");this.css.jq.playBar.length&&(this.options.smoothPlayBar?this.css.jq.playBar.stop().animate({width:this.status.currentPercentAbsolute+ 65 "%"},250,"linear"):this.css.jq.playBar.width(this.status.currentPercentRelative+"%"));this.css.jq.currentTime.length&&this.css.jq.currentTime.text(this._convertTime(this.status.currentTime));this.css.jq.duration.length&&this.css.jq.duration.text(this._convertTime(this.status.duration))},_convertTime:m.prototype.time,_seeking:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.addClass("jp-seeking-bg")},_seeked:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.removeClass("jp-seeking-bg")}, 66 _resetGate:function(){this.html.audio.gate=!1;this.html.video.gate=!1;this.flash.gate=!1},_resetActive:function(){this.html.active=!1;this.flash.active=!1},_escapeHtml:function(a){return a.split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""")},_qualifyURL:function(a){var c=document.createElement("div");c.innerHTML='<a href="'+this._escapeHtml(a)+'">x</a>';return c.firstChild.href},_absoluteMediaUrls:function(a){var c=this;b.each(a,function(b,e){c.format[b]&& 67 (a[b]=c._qualifyURL(e))});return a},setMedia:function(a){var c=this,d=!1,e=this.status.media.poster!==a.poster;this._resetMedia();this._resetGate();this._resetActive();a=this._absoluteMediaUrls(a);b.each(this.formats,function(e,f){var k="video"===c.format[f].media;b.each(c.solutions,function(b,e){if(c[e].support[f]&&c._validString(a[f])){var g="html"===e;k?(g?(c.html.video.gate=!0,c._html_setVideo(a),c.html.active=!0):(c.flash.gate=!0,c._flash_setVideo(a),c.flash.active=!0),c.css.jq.videoPlay.length&& 68 c.css.jq.videoPlay.show(),c.status.video=!0):(g?(c.html.audio.gate=!0,c._html_setAudio(a),c.html.active=!0):(c.flash.gate=!0,c._flash_setAudio(a),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.hide(),c.status.video=!1);d=!0;return!1}});if(d)return!1});d?(this.status.nativeVideoControls&&this.html.video.gate||!this._validString(a.poster)||(e?this.htmlElement.poster.src=a.poster:this.internal.poster.jq.show()),this.status.srcSet=!0,this.status.media=b.extend({},a),this._updateButtons(!1), 69 this._updateInterface()):this._error({type:b.jPlayer.error.NO_SUPPORT,context:"{supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SUPPORT,hint:b.jPlayer.errorHint.NO_SUPPORT})},_resetMedia:function(){this._resetStatus();this._updateButtons(!1);this._updateInterface();this._seeked();this.internal.poster.jq.hide();clearTimeout(this.internal.htmlDlyCmdId);this.html.active?this._html_resetMedia():this.flash.active&&this._flash_resetMedia()},clearMedia:function(){this._resetMedia(); 70 this.html.active?this._html_clearMedia():this.flash.active&&this._flash_clearMedia();this._resetGate();this._resetActive()},load:function(){this.status.srcSet?this.html.active?this._html_load():this.flash.active&&this._flash_load():this._urlNotSetError("load")},focus:function(){this.options.keyEnabled&&(b.jPlayer.focus=this)},play:function(a){a="number"===typeof a?a:NaN;this.status.srcSet?(this.focus(),this.html.active?this._html_play(a):this.flash.active&&this._flash_play(a)):this._urlNotSetError("play")}, 71 videoPlay:function(){this.play()},pause:function(a){a="number"===typeof a?a:NaN;this.status.srcSet?this.html.active?this._html_pause(a):this.flash.active&&this._flash_pause(a):this._urlNotSetError("pause")},tellOthers:function(a,c){var d=this,e="function"===typeof c,g=Array.prototype.slice.call(arguments);"string"===typeof a&&(e&&g.splice(1,1),b.each(this.instances,function(){d.element!==this&&(e&&!c.call(this.data("jPlayer"),d)||this.jPlayer.apply(this,g))}))},pauseOthers:function(a){this.tellOthers("pause", 72 function(){return this.status.srcSet},a)},stop:function(){this.status.srcSet?this.html.active?this._html_pause(0):this.flash.active&&this._flash_pause(0):this._urlNotSetError("stop")},playHead:function(a){a=this._limitValue(a,0,100);this.status.srcSet?this.html.active?this._html_playHead(a):this.flash.active&&this._flash_playHead(a):this._urlNotSetError("playHead")},_muted:function(a){this.mutedWorker(a);this.options.globalVolume&&this.tellOthers("mutedWorker",function(){return this.options.globalVolume}, 73 a)},mutedWorker:function(a){this.options.muted=a;this.html.used&&this._html_setProperty("muted",a);this.flash.used&&this._flash_mute(a);this.html.video.gate||this.html.audio.gate||(this._updateMute(a),this._updateVolume(this.options.volume),this._trigger(b.jPlayer.event.volumechange))},mute:function(a){a=a===f?!0:!!a;this._muted(a)},unmute:function(a){a=a===f?!0:!!a;this._muted(!a)},_updateMute:function(a){a===f&&(a=this.options.muted);this.css.jq.mute.length&&this.css.jq.unmute.length&&(this.status.noVolume? 74 (this.css.jq.mute.hide(),this.css.jq.unmute.hide()):a?(this.css.jq.mute.hide(),this.css.jq.unmute.show()):(this.css.jq.mute.show(),this.css.jq.unmute.hide()))},volume:function(a){this.volumeWorker(a);this.options.globalVolume&&this.tellOthers("volumeWorker",function(){return this.options.globalVolume},a)},volumeWorker:function(a){a=this._limitValue(a,0,1);this.options.volume=a;this.html.used&&this._html_setProperty("volume",a);this.flash.used&&this._flash_volume(a);this.html.video.gate||this.html.audio.gate|| 75 (this._updateVolume(a),this._trigger(b.jPlayer.event.volumechange))},volumeBar:function(a){if(this.css.jq.volumeBar.length){var c=b(a.currentTarget),d=c.offset(),e=a.pageX-d.left,g=c.width();a=c.height()-a.pageY+d.top;c=c.height();this.options.verticalVolume?this.volume(a/c):this.volume(e/g)}this.options.muted&&this._muted(!1)},volumeBarValue:function(){},_updateVolume:function(a){a===f&&(a=this.options.volume);a=this.options.muted?0:a;this.status.noVolume?(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.hide(), 76 this.css.jq.volumeBarValue.length&&this.css.jq.volumeBarValue.hide(),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.hide()):(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.show(),this.css.jq.volumeBarValue.length&&(this.css.jq.volumeBarValue.show(),this.css.jq.volumeBarValue[this.options.verticalVolume?"height":"width"](100*a+"%")),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.show())},volumeMax:function(){this.volume(1);this.options.muted&&this._muted(!1)},_cssSelectorAncestor:function(a){var c= 77 this;this.options.cssSelectorAncestor=a;this._removeUiClass();this.ancestorJq=a?b(a):[];a&&1!==this.ancestorJq.length&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.ancestorJq.length+" found for cssSelectorAncestor.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT});this._addUiClass();b.each(this.options.cssSelector,function(a,b){c._cssSelector(a,b)});this._updateInterface();this._updateButtons();this._updateAutohide();this._updateVolume(); 78 this._updateMute()},_cssSelector:function(a,c){var d=this;"string"===typeof c?b.jPlayer.prototype.options.cssSelector[a]?(this.css.jq[a]&&this.css.jq[a].length&&this.css.jq[a].unbind(".jPlayer"),this.options.cssSelector[a]=c,this.css.cs[a]=this.options.cssSelectorAncestor+" "+c,this.css.jq[a]=c?b(this.css.cs[a]):[],this.css.jq[a].length&&this.css.jq[a].bind("click.jPlayer",function(c){c.preventDefault();d[a](c);b(this).blur()}),c&&1!==this.css.jq[a].length&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT, 79 context:this.css.cs[a],message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.css.jq[a].length+" found for "+a+" method.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT})):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_METHOD,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_METHOD,hint:b.jPlayer.warningHint.CSS_SELECTOR_METHOD}):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_STRING,context:c,message:b.jPlayer.warningMsg.CSS_SELECTOR_STRING,hint:b.jPlayer.warningHint.CSS_SELECTOR_STRING})}, 80 seekBar:function(a){if(this.css.jq.seekBar.length){var c=b(a.currentTarget),d=c.offset();a=a.pageX-d.left;c=c.width();this.playHead(100*a/c)}},playBar:function(){},playbackRate:function(a){this._setOption("playbackRate",a)},playbackRateBar:function(a){if(this.css.jq.playbackRateBar.length){var c=b(a.currentTarget),d=c.offset(),e=a.pageX-d.left,g=c.width();a=c.height()-a.pageY+d.top;c=c.height();this.playbackRate((this.options.verticalPlaybackRate?a/c:e/g)*(this.options.maxPlaybackRate-this.options.minPlaybackRate)+ 81 this.options.minPlaybackRate)}},playbackRateBarValue:function(){},_updatePlaybackRate:function(){var a=(this.options.playbackRate-this.options.minPlaybackRate)/(this.options.maxPlaybackRate-this.options.minPlaybackRate);this.status.playbackRateEnabled?(this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.show(),this.css.jq.playbackRateBarValue.length&&(this.css.jq.playbackRateBarValue.show(),this.css.jq.playbackRateBarValue[this.options.verticalPlaybackRate?"height":"width"](100*a+"%"))): 82 (this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.hide(),this.css.jq.playbackRateBarValue.length&&this.css.jq.playbackRateBarValue.hide())},repeat:function(){this._loop(!0)},repeatOff:function(){this._loop(!1)},_loop:function(a){this.options.loop!==a&&(this.options.loop=a,this._updateButtons(),this._trigger(b.jPlayer.event.repeat))},currentTime:function(){},duration:function(){},gui:function(){},noSolution:function(){},option:function(a,c){var d=a;if(0===arguments.length)return b.extend(!0, 83 {},this.options);if("string"===typeof a){var e=a.split(".");if(c===f){for(var d=b.extend(!0,{},this.options),g=0;g<e.length;g++)if(d[e[g]]!==f)d=d[e[g]];else return this._warning({type:b.jPlayer.warning.OPTION_KEY,context:a,message:b.jPlayer.warningMsg.OPTION_KEY,hint:b.jPlayer.warningHint.OPTION_KEY}),f;return d}for(var g=d={},h=0;h<e.length;h++)h<e.length-1?(g[e[h]]={},g=g[e[h]]):g[e[h]]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(a,b){c._setOption(a, 84 b)});return this},_setOption:function(a,c){var d=this;switch(a){case "volume":this.volume(c);break;case "muted":this._muted(c);break;case "globalVolume":this.options[a]=c;break;case "cssSelectorAncestor":this._cssSelectorAncestor(c);break;case "cssSelector":b.each(c,function(a,c){d._cssSelector(a,c)});break;case "playbackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate,this.options.maxPlaybackRate);this.html.used&&this._html_setProperty("playbackRate",c);this._updatePlaybackRate(); 85 break;case "defaultPlaybackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate,this.options.maxPlaybackRate);this.html.used&&this._html_setProperty("defaultPlaybackRate",c);this._updatePlaybackRate();break;case "minPlaybackRate":this.options[a]=c=this._limitValue(c,0.1,this.options.maxPlaybackRate-0.1);this._updatePlaybackRate();break;case "maxPlaybackRate":this.options[a]=c=this._limitValue(c,this.options.minPlaybackRate+0.1,16);this._updatePlaybackRate();break;case "fullScreen":if(this.options[a]!== 86 c){var e=b.jPlayer.nativeFeatures.fullscreen.used.webkitVideo;if(!e||e&&!this.status.waitForPlay)e||(this.options[a]=c),c?this._requestFullscreen():this._exitFullscreen(),e||this._setOption("fullWindow",c)}break;case "fullWindow":this.options[a]!==c&&(this._removeUiClass(),this.options[a]=c,this._refreshSize());break;case "size":this.options.fullWindow||this.options[a].cssClass===c.cssClass||this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "sizeFull":this.options.fullWindow&& 87 this.options[a].cssClass!==c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "autohide":this.options[a]=b.extend({},this.options[a],c);this._updateAutohide();break;case "loop":this._loop(c);break;case "nativeVideoControls":this.options[a]=b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this._restrictNativeVideoControls();this._updateNativeVideoControls();break;case "noFullWindow":this.options[a]= 88 b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullWindow=this._uaBlocklist(this.options.noFullWindow);this._restrictNativeVideoControls();this._updateButtons();break;case "noVolume":this.options[a]=b.extend({},this.options[a],c);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._updateVolume();this._updateMute();break;case "emulateHtml":this.options[a]!==c&&((this.options[a]=c)?this._emulateHtmlBridge(): 89 this._destroyHtmlBridge());break;case "timeFormat":this.options[a]=b.extend({},this.options[a],c);break;case "keyEnabled":this.options[a]=c;c||this!==b.jPlayer.focus||(b.jPlayer.focus=null);break;case "keyBindings":this.options[a]=b.extend(!0,{},this.options[a],c);break;case "audioFullScreen":this.options[a]=c}return this},_refreshSize:function(){this._setSize();this._addUiClass();this._updateSize();this._updateButtons();this._updateAutohide();this._trigger(b.jPlayer.event.resize)},_setSize:function(){this.options.fullWindow? 90 (this.status.width=this.options.sizeFull.width,this.status.height=this.options.sizeFull.height,this.status.cssClass=this.options.sizeFull.cssClass):(this.status.width=this.options.size.width,this.status.height=this.options.size.height,this.status.cssClass=this.options.size.cssClass);this.element.css({width:this.status.width,height:this.status.height})},_addUiClass:function(){this.ancestorJq.length&&this.ancestorJq.addClass(this.status.cssClass)},_removeUiClass:function(){this.ancestorJq.length&&this.ancestorJq.removeClass(this.status.cssClass)}, 91 _updateSize:function(){this.internal.poster.jq.css({width:this.status.width,height:this.status.height});!this.status.waitForPlay&&this.html.active&&this.status.video||this.html.video.available&&this.html.used&&this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):!this.status.waitForPlay&&this.flash.active&&this.status.video&&this.internal.flash.jq.css({width:this.status.width,height:this.status.height})},_updateAutohide:function(){var a=this, 92 c=function(){a.css.jq.gui.fadeIn(a.options.autohide.fadeIn,function(){clearTimeout(a.internal.autohideId);a.internal.autohideId=setTimeout(function(){a.css.jq.gui.fadeOut(a.options.autohide.fadeOut)},a.options.autohide.hold)})};this.css.jq.gui.length&&(this.css.jq.gui.stop(!0,!0),clearTimeout(this.internal.autohideId),this.element.unbind(".jPlayerAutohide"),this.css.jq.gui.unbind(".jPlayerAutohide"),this.status.nativeVideoControls?this.css.jq.gui.hide():this.options.fullWindow&&this.options.autohide.full|| 93 !this.options.fullWindow&&this.options.autohide.restored?(this.element.bind("mousemove.jPlayer.jPlayerAutohide",c),this.css.jq.gui.bind("mousemove.jPlayer.jPlayerAutohide",c),this.css.jq.gui.hide()):this.css.jq.gui.show())},fullScreen:function(){this._setOption("fullScreen",!0)},restoreScreen:function(){this._setOption("fullScreen",!1)},_fullscreenAddEventListeners:function(){var a=this,c=b.jPlayer.nativeFeatures.fullscreen;c.api.fullscreenEnabled&&c.event.fullscreenchange&&("function"!==typeof this.internal.fullscreenchangeHandler&& 94 (this.internal.fullscreenchangeHandler=function(){a._fullscreenchange()}),document.addEventListener(c.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1))},_fullscreenRemoveEventListeners:function(){var a=b.jPlayer.nativeFeatures.fullscreen;this.internal.fullscreenchangeHandler&&document.addEventListener(a.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1)},_fullscreenchange:function(){this.options.fullScreen&&!b.jPlayer.nativeFeatures.fullscreen.api.fullscreenElement()&& 95 this._setOption("fullScreen",!1)},_requestFullscreen:function(){var a=this.ancestorJq.length?this.ancestorJq[0]:this.element[0],c=b.jPlayer.nativeFeatures.fullscreen;c.used.webkitVideo&&(a=this.htmlElement.video);c.api.fullscreenEnabled&&c.api.requestFullscreen(a)},_exitFullscreen:function(){var a=b.jPlayer.nativeFeatures.fullscreen,c;a.used.webkitVideo&&(c=this.htmlElement.video);a.api.fullscreenEnabled&&a.api.exitFullscreen(c)},_html_initMedia:function(a){var c=b(this.htmlElement.media).empty(); 96 b.each(a.track||[],function(a,b){var g=document.createElement("track");g.setAttribute("kind",b.kind?b.kind:"");g.setAttribute("src",b.src?b.src:"");g.setAttribute("srclang",b.srclang?b.srclang:"");g.setAttribute("label",b.label?b.label:"");b.def&&g.setAttribute("default",b.def);c.append(g)});this.htmlElement.media.src=this.status.src;"none"!==this.options.preload&&this._html_load();this._trigger(b.jPlayer.event.timeupdate)},_html_setFormat:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&& 97 a[e])return c.status.src=a[e],c.status.format[e]=!0,c.status.formatType=e,!1})},_html_setAudio:function(a){this._html_setFormat(a);this.htmlElement.media=this.htmlElement.audio;this._html_initMedia(a)},_html_setVideo:function(a){this._html_setFormat(a);this.status.nativeVideoControls&&(this.htmlElement.video.poster=this._validString(a.poster)?a.poster:"");this.htmlElement.media=this.htmlElement.video;this._html_initMedia(a)},_html_resetMedia:function(){this.htmlElement.media&&(this.htmlElement.media.id!== 98 this.internal.video.id||this.status.nativeVideoControls||this.internal.video.jq.css({width:"0px",height:"0px"}),this.htmlElement.media.pause())},_html_clearMedia:function(){this.htmlElement.media&&(this.htmlElement.media.src="about:blank",this.htmlElement.media.load())},_html_load:function(){this.status.waitForLoad&&(this.status.waitForLoad=!1,this.htmlElement.media.load());clearTimeout(this.internal.htmlDlyCmdId)},_html_play:function(a){var b=this,d=this.htmlElement.media;this._html_load();if(isNaN(a))d.play(); 99 else{this.internal.cmdsIgnored&&d.play();try{if(!d.seekable||"object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a,d.play();else throw 1;}catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.play(a)},250);return}}this._html_checkWaitForPlay()},_html_pause:function(a){var b=this,d=this.htmlElement.media;0<a?this._html_load():clearTimeout(this.internal.htmlDlyCmdId);d.pause();if(!isNaN(a))try{if(!d.seekable||"object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a;else throw 1; 100 }catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.pause(a)},250);return}0<a&&this._html_checkWaitForPlay()},_html_playHead:function(a){var b=this,d=this.htmlElement.media;this._html_load();try{if("object"===typeof d.seekable&&0<d.seekable.length)d.currentTime=a*d.seekable.end(d.seekable.length-1)/100;else if(0<d.duration&&!isNaN(d.duration))d.currentTime=a*d.duration/100;else throw"e";}catch(e){this.internal.htmlDlyCmdId=setTimeout(function(){b.playHead(a)},250);return}this.status.waitForLoad|| 101 this._html_checkWaitForPlay()},_html_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})))},_html_setProperty:function(a,b){this.html.audio.available&&(this.htmlElement.audio[a]=b);this.html.video.available&&(this.htmlElement.video[a]=b)},_flash_setAudio:function(a){var c=this;try{b.each(this.formats, 102 function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4a":case "fla":c._getMovie().fl_setAudio_m4a(a[d]);break;case "mp3":c._getMovie().fl_setAudio_mp3(a[d]);break;case "rtmpa":c._getMovie().fl_setAudio_rtmp(a[d])}c.status.src=a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_setVideo:function(a){var c=this;try{b.each(this.formats,function(b,d){if(c.flash.support[d]&& 103 a[d]){switch(d){case "m4v":case "flv":c._getMovie().fl_setVideo_m4v(a[d]);break;case "rtmpv":c._getMovie().fl_setVideo_rtmp(a[d])}c.status.src=a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_resetMedia:function(){this.internal.flash.jq.css({width:"0px",height:"0px"});this._flash_pause(NaN)},_flash_clearMedia:function(){try{this._getMovie().fl_clearMedia()}catch(a){this._flashError(a)}}, 104 _flash_load:function(){try{this._getMovie().fl_load()}catch(a){this._flashError(a)}this.status.waitForLoad=!1},_flash_play:function(a){try{this._getMovie().fl_play(a)}catch(b){this._flashError(b)}this.status.waitForLoad=!1;this._flash_checkWaitForPlay()},_flash_pause:function(a){try{this._getMovie().fl_pause(a)}catch(b){this._flashError(b)}0<a&&(this.status.waitForLoad=!1,this._flash_checkWaitForPlay())},_flash_playHead:function(a){try{this._getMovie().fl_play_head(a)}catch(b){this._flashError(b)}this.status.waitForLoad|| 105 this._flash_checkWaitForPlay()},_flash_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.flash.jq.css({width:this.status.width,height:this.status.height})))},_flash_volume:function(a){try{this._getMovie().fl_volume(a)}catch(b){this._flashError(b)}},_flash_mute:function(a){try{this._getMovie().fl_mute(a)}catch(b){this._flashError(b)}},_getMovie:function(){return document[this.internal.flash.id]}, 106 _getFlashPluginVersion:function(){var a=0,b;if(window.ActiveXObject)try{if(b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")){var d=b.GetVariable("$version");d&&(d=d.split(" ")[1].split(","),a=parseInt(d[0],10)+"."+parseInt(d[1],10))}}catch(e){}else navigator.plugins&&0<navigator.mimeTypes.length&&(b=navigator.plugins["Shockwave Flash"])&&(a=navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/,"$1"));return 1*a},_checkForFlash:function(a){var b=!1;this._getFlashPluginVersion()>= 107 a&&(b=!0);return b},_validString:function(a){return a&&"string"===typeof a},_limitValue:function(a,b,d){return a<b?b:a>d?d:a},_urlNotSetError:function(a){this._error({type:b.jPlayer.error.URL_NOT_SET,context:a,message:b.jPlayer.errorMsg.URL_NOT_SET,hint:b.jPlayer.errorHint.URL_NOT_SET})},_flashError:function(a){var c;c=this.internal.ready?"FLASH_DISABLED":"FLASH";this._error({type:b.jPlayer.error[c],context:this.internal.flash.swf,message:b.jPlayer.errorMsg[c]+a.message,hint:b.jPlayer.errorHint[c]}); 108 this.internal.flash.jq.css({width:"1px",height:"1px"})},_error:function(a){this._trigger(b.jPlayer.event.error,a);this.options.errorAlerts&&this._alert("Error!"+(a.message?"\n"+a.message:"")+(a.hint?"\n"+a.hint:"")+"\nContext: "+a.context)},_warning:function(a){this._trigger(b.jPlayer.event.warning,f,a);this.options.warningAlerts&&this._alert("Warning!"+(a.message?"\n"+a.message:"")+(a.hint?"\n"+a.hint:"")+"\nContext: "+a.context)},_alert:function(a){a="jPlayer "+this.version.script+" : id='"+this.internal.self.id+ 109 "' : "+a;this.options.consoleAlerts?console&&console.log&&console.log(a):alert(a)},_emulateHtmlBridge:function(){var a=this;b.each(b.jPlayer.emulateMethods.split(/\s+/g),function(b,d){a.internal.domNode[d]=function(b){a[d](b)}});b.each(b.jPlayer.event,function(c,d){var e=!0;b.each(b.jPlayer.reservedEvent.split(/\s+/g),function(a,b){if(b===c)return e=!1});e&&a.element.bind(d+".jPlayer.jPlayerHtml",function(){a._emulateHtmlUpdate();var b=document.createEvent("Event");b.initEvent(c,!1,!0);a.internal.domNode.dispatchEvent(b)})})}, 110 _emulateHtmlUpdate:function(){var a=this;b.each(b.jPlayer.emulateStatus.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.status[d]});b.each(b.jPlayer.emulateOptions.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.options[d]})},_destroyHtmlBridge:function(){var a=this;this.element.unbind(".jPlayerHtml");b.each((b.jPlayer.emulateMethods+" "+b.jPlayer.emulateStatus+" "+b.jPlayer.emulateOptions).split(/\s+/g),function(b,d){delete a.internal.domNode[d]})}};b.jPlayer.error={FLASH:"e_flash",FLASH_DISABLED:"e_flash_disabled", 111 NO_SOLUTION:"e_no_solution",NO_SUPPORT:"e_no_support",URL:"e_url",URL_NOT_SET:"e_url_not_set",VERSION:"e_version"};b.jPlayer.errorMsg={FLASH:"jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ",FLASH_DISABLED:"jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ",NO_SOLUTION:"No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.",NO_SUPPORT:"It is not possible to play any media format provided in setMedia() on this browser using your current options.", 112 URL:"Media URL could not be loaded.",URL_NOT_SET:"Attempt to issue media playback commands, while no media url is set.",VERSION:"jPlayer "+b.jPlayer.prototype.version.script+" needs Jplayer.swf version "+b.jPlayer.prototype.version.needFlash+" but found "};b.jPlayer.errorHint={FLASH:"Check your swfPath option and that Jplayer.swf is there.",FLASH_DISABLED:"Check that you have not display:none; the jPlayer entity or any ancestor.",NO_SOLUTION:"Review the jPlayer options: support and supplied.",NO_SUPPORT:"Video or audio formats defined in the supplied option are missing.", 113 URL:"Check media URL is valid.",URL_NOT_SET:"Use setMedia() to set the media URL.",VERSION:"Update jPlayer files."};b.jPlayer.warning={CSS_SELECTOR_COUNT:"e_css_selector_count",CSS_SELECTOR_METHOD:"e_css_selector_method",CSS_SELECTOR_STRING:"e_css_selector_string",OPTION_KEY:"e_option_key"};b.jPlayer.warningMsg={CSS_SELECTOR_COUNT:"The number of css selectors found did not equal one: ",CSS_SELECTOR_METHOD:"The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",CSS_SELECTOR_STRING:"The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.", 114 OPTION_KEY:"The option requested in jPlayer('option') is undefined."};b.jPlayer.warningHint={CSS_SELECTOR_COUNT:"Check your css selector and the ancestor.",CSS_SELECTOR_METHOD:"Check your method name.",CSS_SELECTOR_STRING:"Check your css selector is a string.",OPTION_KEY:"Check your option name."}});
Note: See TracChangeset
for help on using the changeset viewer.