Skip to content

Commit

Permalink
fix(iOS): pause player on suspend or stalled if extra buffer is avail…
Browse files Browse the repository at this point in the history
…able (#6199)

On iOS, when disconnecting the headphones, we may receive a stalled or suspend event. In those case, we may actually still have buffer available for us to play through rather than actually having stalled or suspended. In those cases, we should pause the player to prevent playback issues.
  • Loading branch information
marcodeltorob authored and gkatsev committed Oct 4, 2019
1 parent f34d441 commit c791cd8
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/js/tech/html5.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ class Html5 extends Tech {
// into a `fullscreenchange` event
this.proxyWebkitFullscreen_();

if (browser.IS_IOS) {
this.handleIOSHeadphonesDisconnection_();
}

this.triggerReady();
}

Expand Down Expand Up @@ -204,6 +208,50 @@ class Html5 extends Tech {
});
}

/**
* Handle IOS Headphone disconnection during playback
*
* @private
*/
handleIOSHeadphonesDisconnection_() {
// Fudge factor to account for TimeRanges rounding
const TIME_FUDGE_FACTOR = 1 / 30;

// Comparisons between time values such as current time and the end of the buffered range
// can be misleading because of precision differences or when the current media has poorly
// aligned audio and video, which can cause values to be slightly off from what you would
// expect. This value is what we consider to be safe to use in such comparisons to account
// for these scenarios.
const SAFE_TIME_DELTA = TIME_FUDGE_FACTOR * 3;

// If iOS check if we have a real stalled or supend event or
// we got stalled/suspend due headphones where disconnected during playback
this.on(['stalled', 'suspend'], (e) => {
const buffered = this.buffered();

if (!buffered.length) {
return;
}

let extraBuffer = false;
const currentTime = this.currentTime();

// Establish if we have an extra buffer in the current time range playing.
for (let i = 0; i < buffered.length; i++) {
if (buffered.start(i) <= currentTime &&
currentTime < buffered.end(i) + SAFE_TIME_DELTA) {
extraBuffer = true;
break;
}
}

// if tech is not paused, browser has internet connection & player has extraBuffer inside the timeRange
if (extraBuffer && !this.paused() && window.navigator.onLine) {
this.pause();
}
});
}

/**
* Attempt to force override of tracks for the given type
*
Expand Down

0 comments on commit c791cd8

Please sign in to comment.