mirror of
https://github.com/videojs/video.js.git
synced 2025-03-29 22:07:10 +02:00
fix: throw error on muted resolution rejection during autoplay (#7293)
Previously, when autoplay was set to any or muted, we would accidentally swallow the autoplay rejection when we reset the muted state back to what it was. Instead, we want to re-throw the error. To get it working, we also had to update our tests to try/catch in our fake promise.
This commit is contained in:
parent
0f707876ef
commit
f9fb1d3f51
@ -1430,7 +1430,9 @@ class Player extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const muted = () => {
|
||||
// Save original muted() value, set muted to true, and attempt to play().
|
||||
// On promise rejection, restore muted from saved value
|
||||
const resolveMuted = () => {
|
||||
const previouslyMuted = this.muted();
|
||||
|
||||
this.muted(true);
|
||||
@ -1448,21 +1450,24 @@ class Player extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
return mutedPromise.catch(restoreMuted);
|
||||
return mutedPromise.catch(err => {
|
||||
restoreMuted();
|
||||
throw new Error(`Rejection at manualAutoplay. Restoring muted value. ${err ? err : ''}`);
|
||||
});
|
||||
};
|
||||
|
||||
let promise;
|
||||
|
||||
// if muted defaults to true
|
||||
// the only thing we can do is call play
|
||||
if (type === 'any' && this.muted() !== true) {
|
||||
if (type === 'any' && !this.muted()) {
|
||||
promise = this.play();
|
||||
|
||||
if (isPromise(promise)) {
|
||||
promise = promise.catch(muted);
|
||||
promise = promise.catch(resolveMuted);
|
||||
}
|
||||
} else if (type === 'muted' && this.muted() !== true) {
|
||||
promise = muted();
|
||||
} else if (type === 'muted' && !this.muted()) {
|
||||
promise = resolveMuted();
|
||||
} else {
|
||||
promise = this.play();
|
||||
}
|
||||
@ -1473,7 +1478,7 @@ class Player extends Component {
|
||||
|
||||
return promise.then(() => {
|
||||
this.trigger({type: 'autoplay-success', autoplay: type});
|
||||
}).catch((e) => {
|
||||
}).catch(() => {
|
||||
this.trigger({type: 'autoplay-failure', autoplay: type});
|
||||
});
|
||||
}
|
||||
|
@ -29,18 +29,25 @@ QUnit.module('autoplay', {
|
||||
|
||||
fixture.appendChild(videoTag);
|
||||
|
||||
// this promise fake will act right away
|
||||
// it will also only act on catch calls
|
||||
// These mock promises immediately execute,
|
||||
// effectively synchronising promise chains for testing
|
||||
|
||||
// This will only act on catch calls
|
||||
this.rejectPromise = {
|
||||
then(fn) {
|
||||
return this;
|
||||
},
|
||||
catch(fn) {
|
||||
fn();
|
||||
try {
|
||||
fn();
|
||||
} catch (err) {
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// This will only act on then calls
|
||||
this.resolvePromise = {
|
||||
then(fn) {
|
||||
fn();
|
||||
@ -274,7 +281,10 @@ QUnit.test('option = "any" play, no muted, rejection leads to muted then play',
|
||||
assert.equal(this.player.autoplay(), 'any', 'player.autoplay getter');
|
||||
assert.equal(this.player.tech_.autoplay(), false, 'tech.autoplay getter');
|
||||
|
||||
// muted called twice here, as muted is value is restored on failure.
|
||||
// The workflow described here:
|
||||
// Call play() -> on rejection, attempt to set mute to true ->
|
||||
// call play() again -> on rejection, set original mute value ->
|
||||
// catch failure at the end of promise chain
|
||||
this.player.tech_.trigger('loadstart');
|
||||
assert.equal(this.counts.play, 2, 'play count');
|
||||
assert.equal(this.counts.muted, 2, 'muted count');
|
||||
|
Loading…
x
Reference in New Issue
Block a user