Skip to content

Commit 58405fd

Browse files
brandonocaseygkatsev
authored andcommitted
fix: always return a promise from play, if supported (videojs#5227)
If Promise is available or if Promise is polyfilled, then we'll return a new Promise from `play()` that will get fulfilled with the value returned from the `play()` method. This means that on IE11, this promise will get resolved when we call `play()` even if play doesn't succeed. We will have a follow-on PR to polyfill this behavior and resolve or reject the promise for browsers like IE11 that don't return a promise from `play()`.
1 parent 6893091 commit 58405fd

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

src/js/player.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,12 +1972,34 @@ class Player extends Component {
19721972
* Attempt to begin playback at the first opportunity.
19731973
*
19741974
* @return {Promise|undefined}
1975-
* Returns a `Promise` only if the browser returns one and the player
1976-
* is ready to begin playback. For some browsers and all non-ready
1977-
* situations, this will return `undefined`.
1975+
* Returns a promise if the browser supports Promises (or one
1976+
* was passed in as an option). This promise will be resolved on
1977+
* the return value of play. If this is undefined it will fulfill the
1978+
* promise chain otherwise the promise chain will be fulfilled when
1979+
* the promise from play is fulfilled.
19781980
*/
19791981
play() {
1982+
const PromiseClass = this.options_.Promise || window.Promise;
19801983

1984+
if (PromiseClass) {
1985+
return new PromiseClass((resolve) => {
1986+
this.play_(resolve);
1987+
});
1988+
}
1989+
1990+
return this.play_();
1991+
}
1992+
1993+
/**
1994+
* The actual logic for play, takes a callback that will be resolved on the
1995+
* return value of play. This allows us to resolve to the play promise if there
1996+
* is one on modern browsers.
1997+
*
1998+
* @private
1999+
* @param {Function} [callback]
2000+
* The callback that should be called when the techs play is actually called
2001+
*/
2002+
play_(callback = silencePromise) {
19812003
// If this is called while we have a play queued up on a loadstart, remove
19822004
// that listener to avoid getting in a potentially bad state.
19832005
if (this.playOnLoadstart_) {
@@ -1997,12 +2019,13 @@ class Player extends Component {
19972019
this.playWaitingForReady_ = true;
19982020
this.ready(() => {
19992021
this.playWaitingForReady_ = false;
2000-
silencePromise(this.play());
2022+
callback(this.play());
20012023
});
20022024

20032025
// If the player/tech is ready and we have a source, we can attempt playback.
20042026
} else if (!this.changingSrc_ && (this.src() || this.currentSrc())) {
2005-
return this.techGet_('play');
2027+
callback(this.techGet_('play'));
2028+
return;
20062029

20072030
// If the tech is ready, but we do not have a source, we'll need to wait
20082031
// for both the `ready` and a `loadstart` when the source is finally
@@ -2014,11 +2037,12 @@ class Player extends Component {
20142037

20152038
this.playOnLoadstart_ = () => {
20162039
this.playOnLoadstart_ = null;
2017-
silencePromise(this.play());
2040+
callback(this.play());
20182041
};
20192042

20202043
this.one('loadstart', this.playOnLoadstart_);
20212044
}
2045+
20222046
}
20232047

20242048
/**

test/unit/player.test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,7 @@ if (window.Promise) {
11361136
}
11371137

11381138
QUnit.test('play promise should resolve to native value if returned', function(assert) {
1139+
const done = assert.async();
11391140
const player = TestHelpers.makePlayer({});
11401141

11411142
player.src({
@@ -1148,7 +1149,18 @@ QUnit.test('play promise should resolve to native value if returned', function(a
11481149
player.tech_.play = () => 'foo';
11491150
const p = player.play();
11501151

1151-
assert.equal(p, 'foo', 'play returns foo');
1152+
const finish = (v) => {
1153+
assert.equal(v, 'foo', 'play returns foo');
1154+
done();
1155+
};
1156+
1157+
if (typeof p === 'string') {
1158+
finish(p);
1159+
} else {
1160+
p.then((v) => {
1161+
finish(v);
1162+
});
1163+
}
11521164
});
11531165

11541166
QUnit.test('should throw on startup no techs are specified', function(assert) {

0 commit comments

Comments
 (0)