From ae6e9c2c5d51a70147ffad75552ea7cd935571ef Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Mon, 22 Jun 2020 17:00:02 -0400 Subject: [PATCH] remove currentMedia, abort/pause audio loaders on exclude --- src/master-playlist-controller.js | 24 +++++------ src/segment-loader.js | 27 +++---------- test/master-playlist-controller.test.js | 54 +++---------------------- 3 files changed, 20 insertions(+), 85 deletions(-) diff --git a/src/master-playlist-controller.js b/src/master-playlist-controller.js index 4d18d9657..abb1c5a24 100644 --- a/src/master-playlist-controller.js +++ b/src/master-playlist-controller.js @@ -553,7 +553,7 @@ export class MasterPlaylistController extends videojs.EventTarget { const codecs = this.getCodecsOrExclude_(); // no codecs means that the playlist was excluded - if (!codecs || !this.sourceUpdater_.canChangeType()) { + if (!codecs) { return; } @@ -1290,13 +1290,9 @@ export class MasterPlaylistController extends videojs.EventTarget { } getCodecsOrExclude_() { - if (!this.areMediaTypesKnown_()) { - return; - } - const media = { - main: this.mainSegmentLoader_.currentMedia_ || this.mainSegmentLoader_.startingMedia_ || {}, - audio: this.audioSegmentLoader_.currentMedia_ || this.audioSegmentLoader_.startingMedia_ || {} + main: this.mainSegmentLoader_.startingMedia_ || {}, + audio: this.audioSegmentLoader_.startingMedia_ || {} }; // set "main" media equal to video @@ -1350,6 +1346,9 @@ export class MasterPlaylistController extends videojs.EventTarget { if (usingAudioLoader && unsupportedAudio && this.media().attributes.AUDIO) { const audioGroup = this.media().attributes.AUDIO; + this.mediaTypes_.AUDIO.activePlaylistLoader.pause(); + this.audioSegmentLoader_.pause(); + this.audioSegmentLoader_.abort(); this.master().playlists.forEach(variant => { const variantAudioGroup = variant.attributes && variant.attributes.AUDIO; @@ -1422,17 +1421,14 @@ export class MasterPlaylistController extends videojs.EventTarget { return; } + if (!this.areMediaTypesKnown_()) { + return; + } + const codecs = this.getCodecsOrExclude_(); // no codecs means that the playlist was excluded - // or areMediaTypesKnown_ is false. if (!codecs) { - // reset starting media if media types were - // known aka the starting playlist was excluded. - if (this.areMediaTypesKnown_()) { - this.mainSegmentLoader_.startingMedia_ = void 0; - this.audioSegmentLoader_.startingMedia_ = void 0; - } return; } diff --git a/src/segment-loader.js b/src/segment-loader.js index 7a24a0d5f..1d19465c6 100644 --- a/src/segment-loader.js +++ b/src/segment-loader.js @@ -346,7 +346,6 @@ export default class SegmentLoader extends videojs.EventTarget { this.vhs_ = settings.vhs; this.loaderType_ = settings.loaderType; this.startingMedia_ = void 0; - this.currentMedia_ = void 0; this.segmentMetadataTrack_ = settings.segmentMetadataTrack; this.goalBufferLength_ = settings.goalBufferLength; this.sourceType_ = settings.sourceType; @@ -840,7 +839,7 @@ export default class SegmentLoader extends videojs.EventTarget { // out before we start adding more data this.resyncLoader(); } - this.currentMedia_ = void 0; + this.startingMedia_ = void 0; this.trigger('playlistupdate'); // the rest of this function depends on `oldPlaylist` being defined @@ -1453,26 +1452,10 @@ export default class SegmentLoader extends videojs.EventTarget { // When we have track info, determine what media types this loader is dealing with. // Guard against cases where we're not getting track info at all until we are // certain that all streams will provide it. - if ((trackInfo.hasVideo || trackInfo.hasAudio)) { - let changed = false; - - if (!this.startingMedia_) { - changed = true; - this.startingMedia_ = trackInfo; - } - if (!shallowEqual(this.currentMedia_, trackInfo)) { - this.currentMedia_ = trackInfo; - changed = true; - } - - // Note: if mux.js reports only audio or - // only video for a segment, when they are muxed - // we may trigger a trackinfo update that is only - // audio/video - if (changed) { - this.logger_('trackinfo update', trackInfo); - this.trigger('trackinfo'); - } + if ((trackInfo.hasVideo || trackInfo.hasAudio) && !shallowEqual(this.startingMedia_, trackInfo)) { + this.startingMedia_ = trackInfo; + this.logger_('trackinfo update', trackInfo); + this.trigger('trackinfo'); } } diff --git a/test/master-playlist-controller.test.js b/test/master-playlist-controller.test.js index 628d15582..e686f487a 100644 --- a/test/master-playlist-controller.test.js +++ b/test/master-playlist-controller.test.js @@ -1031,20 +1031,19 @@ QUnit.test('waits for both main and audio loaders to finish before calling endOf // audio media this.standardXHRResponse(this.requests.shift(), audioMedia); - return requestAndAppendSegment({ + return Promise.all([requestAndAppendSegment({ request: this.requests.shift(), segment: videoSegment(), isOnlyVideo: true, segmentLoader: MPC.mainSegmentLoader_, clock: this.clock - }).then(() => requestAndAppendSegment({ + }), requestAndAppendSegment({ request: this.requests.shift(), segment: audioSegment(), isOnlyAudio: true, segmentLoader: MPC.audioSegmentLoader_, clock: this.clock - })).then(() => { - + })]).then(() => { assert.equal(videoEnded, 1, 'main segment loader did not trigger ended again'); assert.equal(audioEnded, 1, 'audio segment loader triggered ended'); assert.equal(MPC.mediaSource.readyState, 'ended', 'Media Source ended'); @@ -1348,7 +1347,6 @@ QUnit.test('blacklists switching from video-only playlists to video+audio', func }); }); -// TODO: MOAR TEST QUnit.test('blacklists switching between playlists with different codecs', function(assert) { openMediaSource(this.player, this.clock); @@ -4551,8 +4549,6 @@ QUnit.module('MasterPlaylistController codecs', { const { audioStartingMedia, mainStartingMedia, - audioCurrentMedia, - mainCurrentMedia, audioPlaylist, mainPlaylist } = options; @@ -4561,18 +4557,10 @@ QUnit.module('MasterPlaylistController codecs', { this.mpc.mainSegmentLoader_.startingMedia_ = mainStartingMedia; } - if (mainCurrentMedia) { - this.mpc.mainSegmentLoader_.currentMedia_ = mainCurrentMedia; - } - if (audioStartingMedia) { this.mpc.audioSegmentLoader_.startingMedia_ = audioStartingMedia; } - if (audioCurrentMedia) { - this.mpc.audioSegmentLoader_.currentMedia_ = audioCurrentMedia; - } - this.master = {mediaGroups: {AUDIO: {}}, playlists: []}; this.mpc.master = () => this.master; @@ -4594,7 +4582,7 @@ QUnit.module('MasterPlaylistController codecs', { }; } this.master.playlists.push(audioPlaylist); - this.mpc.mediaTypes_.AUDIO.activePlaylistLoader = {}; + this.mpc.mediaTypes_.AUDIO.activePlaylistLoader = {pause() {}}; } }; }, @@ -4751,22 +4739,6 @@ QUnit.test('can get codecs from startingMedia', function(assert) { assert.deepEqual(codecs, {video: 'avc1.4c400d', audio: 'mp4a.40.5'}, 'codecs returned'); }); -QUnit.test('can get codecs from currentMedia', function(assert) { - this.contentSetup({ - mainStartingMedia: {videoCodec: 'avc1.4c400c', hasVideo: true, hasAudio: false}, - audioStartingMedia: {audioCodec: 'mp4a.40.2', hasVideo: false, hasAudio: true}, - mainCurrentMedia: {videoCodec: 'avc1.4c400d', hasVideo: true, hasAudio: false}, - audioCurrentMedia: {audioCodec: 'mp4a.40.5', hasVideo: false, hasAudio: true}, - mainPlaylist: {attributes: {}}, - audioPlaylist: {attributes: {}} - }); - - const codecs = this.mpc.getCodecsOrExclude_(); - - assert.deepEqual(this.blacklists, [], 'did not blacklist anything'); - assert.deepEqual(codecs, {video: 'avc1.4c400d', audio: 'mp4a.40.5'}, 'codecs returned'); -}); - QUnit.test('playlist codecs take priority over others', function(assert) { this.contentSetup({ mainStartingMedia: {videoCodec: 'avc1.4c400d', hasVideo: true, hasAudio: false}, @@ -4781,22 +4753,6 @@ QUnit.test('playlist codecs take priority over others', function(assert) { assert.deepEqual(codecs, {video: 'avc1.4b400d', audio: 'mp4a.40.20'}, 'codecs returned'); }); -QUnit.test('currentMedia codecs take priority over startingMedia codecs', function(assert) { - this.contentSetup({ - mainStartingMedia: {videoCodec: 'avc1.4c400d', hasVideo: true, hasAudio: false}, - audioStartingMedia: {audioCodec: 'mp4a.40.5', hasVideo: false, hasAudio: true}, - mainCurrentMedia: {videoCodec: 'avc1.4b400d', hasVideo: true, hasAudio: false}, - audioCurrentMedia: {audioCodec: 'mp4a.40.20', hasVideo: false, hasAudio: true}, - mainPlaylist: {attributes: {}}, - audioPlaylist: {attributes: {}} - }); - - const codecs = this.mpc.getCodecsOrExclude_(); - - assert.deepEqual(this.blacklists, [], 'did not blacklist anything'); - assert.deepEqual(codecs, {video: 'avc1.4b400d', audio: 'mp4a.40.20'}, 'codecs returned'); -}); - QUnit.test('uses default codecs if no codecs are found', function(assert) { this.contentSetup({ mainStartingMedia: {hasVideo: true, hasAudio: false}, @@ -5200,7 +5156,7 @@ QUnit.test('main & audio loader only trackinfo works as expected', function(asse this.mpc.sourceUpdater_.ready = () => true; this.mpc.sourceUpdater_.canChangeType = () => true; - this.mpc.mainSegmentLoader_.currentMedia_ = { + this.mpc.mainSegmentLoader_.startingMedia_ = { videoCodec: 'avc1.4c400e', hasVideo: true, hasAudio: false