From 38c50818890f9c0fb21af6edf2ac9c5cce187e48 Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Thu, 25 Mar 2021 14:17:07 -0700 Subject: [PATCH] fix(player): Fix resolution changes with lang change. Now, when changing audio languages, we'll try to stick with the same resolution we were at before. This only happens with ABR disabled since ABR will switch resolutions anyway. Fixes #3262 Closes #3288 Change-Id: Ie4e529ad4ab942d74ae46318c605b45b8a07123b --- lib/player.js | 32 ++++++++++++++++++++++++++++++++ test/player_unit.js | 16 ++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/player.js b/lib/player.js index 2d33c122a3..4b761e9fe1 100644 --- a/lib/player.js +++ b/lib/player.js @@ -3541,6 +3541,38 @@ shaka.Player = class extends shaka.util.FakeEventTarget { new shaka.media.PreferenceBasedCriteria(language, role || '', /* channelCount= */ 0, /* label= */ ''); + if (!this.config_.abr.enabled) { + const diff = (a, b) => { + if (!a.video && !b.video) { + return 0; + } else if (!a.video || !b.video) { + return Infinity; + } else { + return Math.abs((a.video.height || 0) - (b.video.height || 0)) + + Math.abs((a.video.width || 0) - (b.video.width || 0)); + } + }; + // Find the variant whose size is closest to the active variant. This + // ensures we stay at about the same resolution when just changing the + // language/role. + const active = this.streamingEngine_.getCurrentVariant(); + const set = + this.currentAdaptationSetCriteria_.create(this.manifest_.variants); + let bestVariant = null; + for (const curVariant of set.values()) { + if (!bestVariant || + diff(bestVariant, active) > diff(curVariant, active)) { + bestVariant = curVariant; + } + } + if (bestVariant) { + const track = shaka.util.StreamUtils.variantToTrack(bestVariant); + this.selectVariantTrack(track, /* clearBuffer= */ true); + return; + } + } + + // If we haven't switched yet, just use ABR to find a new track. this.chooseVariantAndSwitch_(); } else if (this.video_ && this.video_.audioTracks) { const audioTracks = Array.from(this.video_.audioTracks); diff --git a/test/player_unit.js b/test/player_unit.js index d33b003774..1662a088d1 100644 --- a/test/player_unit.js +++ b/test/player_unit.js @@ -1727,6 +1727,22 @@ describe('Player', () => { expect(getActiveVariantTrack().audioRoles).toEqual([]); }); + // https://github.com/google/shaka-player/issues/3262 + it('selectAudioLanguage() doesn\'t change resolution', () => { + player.configure('abr.enabled', false); + abrManager.chooseIndex = 1; + const lowResEn = + variantTracks.filter((t) => t.language == 'en' && t.height == 200)[0]; + player.selectVariantTrack(lowResEn); + + // Switching to 'es' should keep the low-res stream and not choose the + // high-res version. + player.selectAudioLanguage('es'); + const lowResEs = + variantTracks.filter((t) => t.language == 'es' && t.height == 200)[0]; + expect(getActiveVariantTrack().id).toBe(lowResEs.id); + }); + it('selectTextLanguage() does not change selected variant track', () => { // This came up in a custom application that allows to select // from all tracks regardless of selected language.