From f15d36525088d10f585ae986793c0eab4c9b6f5e Mon Sep 17 00:00:00 2001 From: Yair Ansbacher Date: Mon, 21 Feb 2022 13:16:46 +0200 Subject: [PATCH] feat(FEC-11894): persist user selection during playlist playback (#634) store the video track selection and select it on load Solves: FEC-11894 --- src/player.js | 24 ++++++++++++++++++++ test/src/player.spec.js | 49 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/player.js b/src/player.js index 10b78b9de..c8c3a164f 100644 --- a/src/player.js +++ b/src/player.js @@ -324,6 +324,7 @@ export default class Player extends FakeEventTarget { muted: undefined, volume: undefined, rate: undefined, + videoTrack: undefined, audioLanguage: '', textLanguage: '' }; @@ -1304,6 +1305,7 @@ export default class Player extends FakeEventTarget { selectTrack(track: ?Track): void { if (this._engine) { if (track instanceof VideoTrack) { + this._playbackAttributesState.videoTrack = track; if (this._stateManager.currentState.type === StateType.IDLE) { this._pendingSelectedVideoTrack = track; } else { @@ -1388,6 +1390,7 @@ export default class Player extends FakeEventTarget { if (this._engine) { this._engine.enableAdaptiveBitrate(); } + this._playbackAttributesState.videoTrack = undefined; } /** @@ -2549,6 +2552,7 @@ export default class Player extends FakeEventTarget { let currentOrConfiguredAudioLang = this._playbackAttributesState.audioLanguage || playbackConfig.audioLanguage; this._setDefaultTrack(this._getTextTracks(), currentOrConfiguredTextLang, offTextTrack); this._setDefaultTrack(this._getAudioTracks(), currentOrConfiguredAudioLang, activeTracks.audio); + this._setDefaultVideoTrack(); } /** @@ -2601,6 +2605,26 @@ export default class Player extends FakeEventTarget { } } + /** + * Sets the video track selected by the user. + * @returns {void} + * @private + */ + _setDefaultVideoTrack(): void { + const sortedVideoTracks = this._getVideoTracks().sort((track1: VideoTrack, track2: VideoTrack) => track2.bandwidth - track1.bandwidth); + let selectedVideoTrack = sortedVideoTracks.find( + (track: VideoTrack) => track.label && track.label === this._playbackAttributesState.videoTrack?.label + ); + if (!selectedVideoTrack) { + selectedVideoTrack = sortedVideoTracks.find( + (track: VideoTrack) => track.height && track.height === this._playbackAttributesState.videoTrack?.height + ); + } + if (selectedVideoTrack) { + this.selectTrack(selectedVideoTrack); + } + } + /** * Checks for callbacks that should change the tracks, and call them on the * respective track group (audio/text/video) diff --git a/test/src/player.spec.js b/test/src/player.spec.js index 398de73cf..6c4fd533e 100644 --- a/test/src/player.spec.js +++ b/test/src/player.spec.js @@ -935,7 +935,7 @@ describe('Player', function () { removeElement(targetId); }); - it.skip('should select a new video track', done => { + it('should select a new video track', done => { let tracks; player.addEventListener(CustomEventType.VIDEO_TRACK_CHANGED, event => { (event.payload.selectedVideoTrack instanceof VideoTrack).should.be.true; @@ -961,6 +961,53 @@ describe('Player', function () { video = player._engine.getVideoElement(); }); + it('should select the previous selected track', done => { + let tracks; + player.ready().then(() => { + tracks = player._tracks.filter(track => { + return track instanceof VideoTrack; + }); + player.selectTrack(tracks[1]); + player.setSources(sourcesConfig.MultipleSources); + player.load(); + player.ready().then(() => { + try { + (video.src.indexOf(sourcesConfig.MultipleSources.progressive[0].url) > -1).should.be.false; + (video.src.indexOf(sourcesConfig.MultipleSources.progressive[1].url) > -1).should.be.true; + done(); + } catch (e) { + done(e); + } + }); + }); + player.load(); + video = player._engine.getVideoElement(); + }); + + it('should remove user selection once adaptive bitrate enabled', done => { + let tracks; + player.ready().then(() => { + tracks = player._tracks.filter(track => { + return track instanceof VideoTrack; + }); + player.selectTrack(tracks[1]); + player.enableAdaptiveBitrate(); + player.setSources(sourcesConfig.MultipleSources); + player.load(); + player.ready().then(() => { + try { + (video.src.indexOf(sourcesConfig.MultipleSources.progressive[0].url) > -1).should.be.true; + (video.src.indexOf(sourcesConfig.MultipleSources.progressive[1].url) > -1).should.be.false; + done(); + } catch (e) { + done(e); + } + }); + }); + player.load(); + video = player._engine.getVideoElement(); + }); + it('should not change the selected for non exist video track', done => { player.ready().then(() => { let tracks = player._tracks.filter(track => {