diff --git a/AUTHORS b/AUTHORS index d2a77ceb39..207912e783 100644 --- a/AUTHORS +++ b/AUTHORS @@ -78,6 +78,7 @@ Seongryun Jo Swank Motion Pictures Inc. <*@swankmp.com> TalkTalk Plc <*@talktalkplc.com> Tatsiana Gelahova +Tian Shao Tomas Tichy Tomohiro Matsuzawa Toshihiro Suzuki diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ad4022bc07..1b272e8878 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -114,6 +114,7 @@ Seth Madison Tatsiana Gelahova Theodore Abshire Thomas Stephens +Tian Shao Tim Plummer Timothy Drews Tomas Bucher diff --git a/demo/common/message_ids.js b/demo/common/message_ids.js index 2052e4216a..6ee5e5fe7f 100644 --- a/demo/common/message_ids.js +++ b/demo/common/message_ids.js @@ -153,6 +153,7 @@ shakaDemo.MessageIds = { ALWAYS_STREAM_TEXT_WARNING: 'DEMO_ALWAYS_STREAM_TEXT_WARNING', AUDIO_CHANNEL_COUNT: 'DEMO_AUDIO_CHANNEL_COUNT', AUDIO_LANGUAGE: 'DEMO_AUDIO_LANGUAGE', + AUDIO_LABEL: 'DEMO_AUDIO_LABEL', AUDIO_ROBUSTNESS: 'DEMO_AUDIO_ROBUSTNESS', AUTO_CORRECT_DASH_DRIFT: 'DEMO_AUTO_CORRECT_DASH_DRIFT', AUTO_LOW_LATENCY: 'DEMO_AUTO_LOW_LATENCY', diff --git a/demo/config.js b/demo/config.js index 8db3062a49..a23048b720 100644 --- a/demo/config.js +++ b/demo/config.js @@ -477,6 +477,7 @@ shakaDemo.Config = class { this.addSection_(MessageIds.LANGUAGE_SECTION_HEADER, docLink) .addTextInput_(MessageIds.AUDIO_LANGUAGE, 'preferredAudioLanguage') + .addTextInput_(MessageIds.AUDIO_LABEL, 'preferredAudioLabel') .addTextInput_(MessageIds.TEXT_LANGUAGE, 'preferredTextLanguage') .addTextInput_(MessageIds.TEXT_ROLE, 'preferredTextRole') .addSelectInput_( diff --git a/demo/locales/en.json b/demo/locales/en.json index a861a17cf0..fe028bd096 100644 --- a/demo/locales/en.json +++ b/demo/locales/en.json @@ -11,6 +11,7 @@ "DEMO_APPLE": "Apple", "DEMO_AUDIO_CHANNEL_COUNT": "Preferred Audio Channel Count", "DEMO_AUDIO_LANGUAGE": "Preferred Audio Language", + "DEMO_AUDIO_LABEL": "Preferred Audio Label", "DEMO_AUDIO_ONLY": "Audio only", "DEMO_AUDIO_ONLY_SEARCH": "Filters for assets that do not have video streams.", "DEMO_AUDIO_ROBUSTNESS": "Audio Robustness", diff --git a/demo/locales/source.json b/demo/locales/source.json index 5d3b425f02..2a228c4220 100644 --- a/demo/locales/source.json +++ b/demo/locales/source.json @@ -47,6 +47,10 @@ "description": "The name of a configuration value.", "message": "Preferred Audio Language" }, + "DEMO_AUDIO_LABEL": { + "description": "The name of a configuration value.", + "message": "Preferred Audio Label" + }, "DEMO_AUDIO_ONLY": { "description": "A tag that marks an asset as having multiple languages.", "message": "Audio only" diff --git a/docs/tutorials/config.md b/docs/tutorials/config.md index 2a23ccbf65..039c3f40e1 100644 --- a/docs/tutorials/config.md +++ b/docs/tutorials/config.md @@ -64,6 +64,7 @@ player.getConfiguration(); playRangeEnd: Infinity playRangeStart: 0 preferredAudioLanguage: "" + preferredAudioLabel: "" preferredTextLanguage: "" restrictions: Object streaming: Object diff --git a/externs/shaka/player.js b/externs/shaka/player.js index a7a511f4a8..7ee17f3f33 100644 --- a/externs/shaka/player.js +++ b/externs/shaka/player.js @@ -1317,6 +1317,7 @@ shaka.extern.OfflineConfiguration; * lcevc: shaka.extern.LcevcConfiguration, * offline: shaka.extern.OfflineConfiguration, * preferredAudioLanguage: string, + * preferredAudioLabel: string, * preferredTextLanguage: string, * preferredVariantRole: string, * preferredTextRole: string, @@ -1356,6 +1357,8 @@ shaka.extern.OfflineConfiguration; * The preferred language to use for audio tracks. If not given it will use * the 'main' track. * Changing this during playback will not affect the current playback. + * @property {string} preferredAudioLabel + * The preferred label to use for audio tracks * @property {string} preferredTextLanguage * The preferred language to use for text tracks. If a matching text track * is found, and the selected audio and text tracks have different languages, diff --git a/lib/media/adaptation_set_criteria.js b/lib/media/adaptation_set_criteria.js index d4111535fe..b1fe6a3cfa 100644 --- a/lib/media/adaptation_set_criteria.js +++ b/lib/media/adaptation_set_criteria.js @@ -218,7 +218,7 @@ shaka.media.PreferenceBasedCriteria = class { */ static filterVariantsByLabel_(variants, preferredLabel) { return variants.filter((variant) => { - if (!variant.audio) { + if (!variant.audio || !variant.audio.label) { return false; } diff --git a/lib/player.js b/lib/player.js index 1c463a8267..a6626abb9a 100644 --- a/lib/player.js +++ b/lib/player.js @@ -2099,7 +2099,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { new shaka.media.PreferenceBasedCriteria( this.config_.preferredAudioLanguage, this.config_.preferredVariantRole, - this.config_.preferredAudioChannelCount); + this.config_.preferredAudioChannelCount, + this.config_.preferredAudioLabel); this.currentTextLanguage_ = this.config_.preferredTextLanguage; this.currentTextRole_ = this.config_.preferredTextRole; diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index 2cfc433b17..46f388ca18 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -289,6 +289,7 @@ shaka.util.PlayerConfiguration = class { abr: abr, autoShowText: AutoShowText.IF_SUBTITLES_MAY_BE_NEEDED, preferredAudioLanguage: '', + preferredAudioLabel: '', preferredTextLanguage: '', preferredVariantRole: '', preferredTextRole: '', diff --git a/test/player_unit.js b/test/player_unit.js index 7308d9b7ea..1e8171a710 100644 --- a/test/player_unit.js +++ b/test/player_unit.js @@ -1252,6 +1252,7 @@ describe('Player', () => { manifest.addVariant(106, (variant) => { // spanish stereo, low res variant.language = 'es'; variant.bandwidth = 1100; + variant.label = 'es-label'; variant.addExistingStream(1); // video variant.addAudio(6, (stream) => { stream.originalId = 'audio-es'; @@ -1263,6 +1264,7 @@ describe('Player', () => { manifest.addVariant(107, (variant) => { // spanish stereo, high res variant.language = 'es'; variant.bandwidth = 2100; + variant.label = 'es-label'; variant.addExistingStream(2); // video variant.addExistingStream(6); // audio }); @@ -1529,7 +1531,7 @@ describe('Player', () => { type: 'variant', bandwidth: 1100, language: 'es', - label: null, + label: 'es-label', kind: null, width: 100, height: 200, @@ -1565,7 +1567,7 @@ describe('Player', () => { type: 'variant', bandwidth: 2100, language: 'es', - label: null, + label: 'es-label', kind: null, width: 200, height: 400, @@ -2236,6 +2238,18 @@ describe('Player', () => { roles: ['commentary'], })); }); + + it('chooses a variant with preferred audio label', async () => { + expect(getActiveVariantTrack().label).toBe(null); + + player.configure({ + preferredAudioLanguage: '', + preferredAudioLabel: 'es-label', + }); + + await player.load(fakeManifestUri, 0, fakeMimeType); + expect(getActiveVariantTrack().label).toBe('es-label'); + }); }); // describe('tracks') describe('languages', () => { diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 07ac9be353..52d05001da 100644 --- a/test/test/util/manifest_generator.js +++ b/test/test/util/manifest_generator.js @@ -263,6 +263,8 @@ shaka.test.ManifestGenerator.Variant = class { if (!isPartial) { /** @type {string} */ this.language = 'und'; + /** @type {string} */ + this.label = ''; /** @type {number} */ this.bandwidth = 0; /** @type {number} */ @@ -316,7 +318,7 @@ shaka.test.ManifestGenerator.Variant = class { const ContentType = shaka.util.ManifestParserUtils.ContentType; const stream = new shaka.test.ManifestGenerator.Stream( this.manifest_, /* isPartial= */ false, id, ContentType.AUDIO, - this.language); + this.language, this.label); if (func) { func(stream); } @@ -447,8 +449,9 @@ shaka.test.ManifestGenerator.Stream = class { * @param {?number} id * @param {shaka.util.ManifestParserUtils.ContentType} type * @param {string=} lang + * @param {string=} label */ - constructor(manifest, isPartial, id, type, lang) { + constructor(manifest, isPartial, id, type, lang, label) { goog.asserts.assert( !manifest || !manifest.isIdUsed_(id), 'Streams should have unique ids!'); @@ -518,7 +521,7 @@ shaka.test.ManifestGenerator.Stream = class { /** @type {string} */ this.language = lang || 'und'; /** @type {?string} */ - this.label = null; + this.label = label || null; /** @type {boolean} */ this.primary = false; /** @type {?shaka.extern.Stream} */