Skip to content

Commit

Permalink
fix: Fix exceptions when quickly shutting down src= on Safari (#4088)
Browse files Browse the repository at this point in the history
Some events and timers were used to process track changes with src=
playback on Safari, but they did not properly clean up when the player
was unloaded or destroyed.  In the case that this happened quickly
after starting playback, exceptions would be thrown or tracks could
manipulated after new content began.

This fixes the cleanup of these timers and events to be aware of
Player unloads or destruction.

Closes #4087
  • Loading branch information
joeyparrish committed Apr 21, 2022
1 parent ab3a24c commit da14ae4
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {

this.playhead_ = new shaka.media.SrcEqualsPlayhead(has.mediaElement);

// This flag is used below in the language preference setup and
// track-management to check if this load was canceled before the necessary
// events fired.
let unloaded = false;
this.cleanupOnUnload_.push(() => {
unloaded = true;
});

if (has.startTime != null) {
this.playhead_.setStartTime(has.startTime);
}
Expand Down Expand Up @@ -2171,6 +2179,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
}
if (this.video_.textTracks) {
this.eventManager_.listen(this.video_.textTracks, 'addtrack', (e) => {
// If we have moved on to another piece of content while waiting for
// the above event, we should not process tracks here.
if (unloaded) {
return;
}

this.onTracksChanged_();
this.processTimedMetadataSrcEqls_(/** @type {!TrackEvent} */(e));
});
Expand Down Expand Up @@ -2212,13 +2226,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
fullyLoaded.resolve();
});

// This flag is used below in the language preference setup to check if this
// load was canceled before the necessary events fire.
let unloaded = false;
this.cleanupOnUnload_.push(() => {
unloaded = true;
});

// We can't switch to preferred languages, though, until the data is loaded.
shaka.util.MediaReadyState.waitForReadyState(this.video_,
HTMLMediaElement.HAVE_CURRENT_DATA,
Expand Down Expand Up @@ -2376,12 +2383,16 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
// In Safari the initial assignment does not always work, so we schedule
// this process to be repeated several times to ensure that it has been put
// in the correct mode.
new shaka.util.Timer(() => {
const timer = new shaka.util.Timer(() => {
const textTracks = this.getMetadataTracks_();
for (const textTrack of textTracks) {
textTrack.mode = 'hidden';
}
}).tickNow().tickAfter(/* seconds= */ 0.5);
}).tickNow().tickAfter(0.5);

this.cleanupOnUnload_.push(() => {
timer.stop();
});
}


Expand Down

0 comments on commit da14ae4

Please sign in to comment.