|
7 | 7 | * http://opensource.org/licenses/MIT
|
8 | 8 | *
|
9 | 9 | * Author: Mark J Panaghiston
|
10 |
| - * Version: 2.5.4 |
11 |
| - * Date: 9th January 2014 |
| 10 | + * Version: 2.5.5 |
| 11 | + * Date: 8th March 2014 |
12 | 12 | */
|
13 | 13 |
|
14 | 14 | /* Code verified using http://www.jshint.com/ */
|
|
470 | 470 | $.jPlayer.prototype = {
|
471 | 471 | count: 0, // Static Variable: Change it via prototype.
|
472 | 472 | version: { // Static Object
|
473 |
| - script: "2.5.4", |
| 473 | + script: "2.5.5", |
474 | 474 | needFlash: "2.5.2",
|
475 | 475 | flash: "unknown"
|
476 | 476 | },
|
|
794 | 794 | $.jPlayer.focus = this;
|
795 | 795 | }
|
796 | 796 |
|
| 797 | + // A fix for Android where older (2.3) and even some 4.x devices fail to work when changing the *audio* SRC and then playing immediately. |
| 798 | + this.androidFix = { |
| 799 | + setMedia: false, // True when media set |
| 800 | + play: false, // True when a progress event will instruct the media to play |
| 801 | + pause: false, // True when a progress event will instruct the media to pause at a time. |
| 802 | + time: NaN // The play(time) parameter |
| 803 | + }; |
| 804 | + if($.jPlayer.platform.android) { |
| 805 | + this.options.preload = this.options.preload !== 'auto' ? 'metadata' : 'auto'; // Default to metadata, but allow auto. |
| 806 | + } |
| 807 | + |
797 | 808 | this.formats = []; // Array based on supplied string option. Order defines priority.
|
798 | 809 | this.solutions = []; // Array based on solution string option. Order defines priority.
|
799 | 810 | this.require = {}; // Which media types are required: video, audio.
|
|
1261 | 1272 | if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command
|
1262 | 1273 | self.internal.cmdsIgnored = false;
|
1263 | 1274 | }
|
| 1275 | + self.androidFix.setMedia = false; // Disable the fix after the first progress event. |
| 1276 | + if(self.androidFix.play) { // Play Android audio - performing the fix. |
| 1277 | + self.androidFix.play = false; |
| 1278 | + self.play(self.androidFix.time); |
| 1279 | + } |
| 1280 | + if(self.androidFix.pause) { // Pause Android audio at time - performing the fix. |
| 1281 | + self.androidFix.pause = false; |
| 1282 | + self.pause(self.androidFix.time); |
| 1283 | + } |
1264 | 1284 | self._getHtmlStatus(mediaElement);
|
1265 | 1285 | self._updateInterface();
|
1266 | 1286 | self._trigger($.jPlayer.event.progress);
|
|
1691 | 1711 | this._resetGate();
|
1692 | 1712 | this._resetActive();
|
1693 | 1713 |
|
| 1714 | + // Clear the Android Fix. |
| 1715 | + this.androidFix.setMedia = false; |
| 1716 | + this.androidFix.play = false; |
| 1717 | + this.androidFix.pause = false; |
| 1718 | + |
1694 | 1719 | // Convert all media URLs to absolute URLs.
|
1695 | 1720 | media = this._absoluteMediaUrls(media);
|
1696 | 1721 |
|
|
1719 | 1744 | self.html.audio.gate = true;
|
1720 | 1745 | self._html_setAudio(media);
|
1721 | 1746 | self.html.active = true;
|
| 1747 | + |
| 1748 | + // Setup the Android Fix - Only for HTML audio. |
| 1749 | + if($.jPlayer.platform.android) { |
| 1750 | + self.androidFix.setMedia = true; |
| 1751 | + } |
1722 | 1752 | } else {
|
1723 | 1753 | self.flash.gate = true;
|
1724 | 1754 | self._flash_setAudio(media);
|
|
2590 | 2620 | var self = this,
|
2591 | 2621 | media = this.htmlElement.media;
|
2592 | 2622 |
|
| 2623 | + this.androidFix.pause = false; // Cancel the pause fix. |
| 2624 | + |
2593 | 2625 | this._html_load(); // Loads if required and clears any delayed commands.
|
2594 | 2626 |
|
2595 |
| - if(!isNaN(time)) { |
| 2627 | + // Setup the Android Fix. |
| 2628 | + if(this.androidFix.setMedia) { |
| 2629 | + this.androidFix.play = true; |
| 2630 | + this.androidFix.time = time; |
| 2631 | + |
| 2632 | + } else if(!isNaN(time)) { |
2596 | 2633 |
|
2597 | 2634 | // Attempt to play it, since iOS has been ignoring commands
|
2598 | 2635 | if(this.internal.cmdsIgnored) {
|
|
2622 | 2659 | _html_pause: function(time) {
|
2623 | 2660 | var self = this,
|
2624 | 2661 | media = this.htmlElement.media;
|
2625 |
| - |
| 2662 | + |
| 2663 | + this.androidFix.play = false; // Cancel the play fix. |
| 2664 | + |
2626 | 2665 | if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
|
2627 | 2666 | this._html_load(); // Loads if required and clears any delayed commands.
|
2628 | 2667 | } else {
|
|
2632 | 2671 | // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime.
|
2633 | 2672 | media.pause();
|
2634 | 2673 |
|
2635 |
| - if(!isNaN(time)) { |
| 2674 | + // Setup the Android Fix. |
| 2675 | + if(this.androidFix.setMedia) { |
| 2676 | + this.androidFix.pause = true; |
| 2677 | + this.androidFix.time = time; |
| 2678 | + |
| 2679 | + } else if(!isNaN(time)) { |
2636 | 2680 | try {
|
2637 | 2681 | if(!media.seekable || typeof media.seekable === "object" && media.seekable.length > 0) {
|
2638 | 2682 | media.currentTime = time;
|
|
2656 | 2700 |
|
2657 | 2701 | this._html_load(); // Loads if required and clears any delayed commands.
|
2658 | 2702 |
|
| 2703 | + // This playHead() method needs a refactor to apply the android fix. |
| 2704 | + |
2659 | 2705 | try {
|
2660 | 2706 | if(typeof media.seekable === "object" && media.seekable.length > 0) {
|
2661 | 2707 | media.currentTime = percent * media.seekable.end(media.seekable.length-1) / 100;
|
|
0 commit comments