From 246f7c5684c79b62ef61e956b6231c8b8b664e87 Mon Sep 17 00:00:00 2001 From: Bidisha Das Date: Thu, 20 Jul 2023 03:00:20 +0530 Subject: [PATCH] fix(HLS): Add subtitle role when there are no roles (#5357) Fixes #5355 Co-authored-by: Joey Parrish --- lib/hls/hls_parser.js | 18 +++++++++- test/hls/hls_parser_unit.js | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index e50c459271..85bf68fadf 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -2436,6 +2436,22 @@ shaka.hls.HlsParser = class { // stream is lazy-loaded. const mimeType = this.guessMimeTypeBeforeLoading_(type, codecs) || this.guessMimeTypeFallback_(type); + const roles = []; + if (characteristics) { + for (const characteristic of characteristics.split(',')) { + roles.push(characteristic); + } + } + + const kind = (type == shaka.util.ManifestParserUtils.ContentType.TEXT) ? + shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE : undefined; + + // If there are no roles, and we have defaulted to the subtitle "kind" for + // this track, add the implied subtitle role. + if (!roles.length && + kind === shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE) { + roles.push(shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE); + } return { id: this.globalId_++, @@ -2462,7 +2478,7 @@ shaka.hls.HlsParser = class { width: undefined, height: undefined, bandwidth: undefined, - roles: characteristics ? characteristics.split(',') : [], + roles, forced, channelsCount, audioSamplingRate: sampleRate, diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index 2e95381ca6..c987e99347 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -1173,6 +1173,75 @@ describe('HlsParser', () => { await testHlsParser(master, media, manifest); }); + it('adds subtitle role when characteristics are empty', async () => { + const master = [ + '#EXTM3U\n', + '#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1",', + 'RESOLUTION=960x540,FRAME-RATE=60,AUDIO="aud1",SUBTITLES="sub1"\n', + 'video\n', + + '#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud1",LANGUAGE="en",', + 'NAME="English",URI="audio"\n', + + '#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud1",LANGUAGE="en",', + 'CHARACTERISTICS="public.accessibility.describes-video,', + 'public.accessibility.describes-music-and-sound",', + 'NAME="English (describes-video)",URI="audio2"\n', + + '#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="sub1",LANGUAGE="en",', + 'NAME="English (subtitle)",DEFAULT=YES,AUTOSELECT=YES,', + 'URI="text"\n', + + '#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="sub1",LANGUAGE="en",', + 'NAME="English (caption)",DEFAULT=YES,AUTOSELECT=YES,', + 'CHARACTERISTICS="public.accessibility.describes-music-and-sound",', + 'URI="text2"\n', + ].join(''); + const manifest = shaka.test.ManifestGenerator.generate((manifest) => { + manifest.anyTimeline(); + manifest.addPartialVariant((variant) => { + variant.language = 'en'; + variant.addPartialStream(ContentType.VIDEO); + variant.addPartialStream(ContentType.AUDIO, (stream) => { + stream.language = 'en'; + stream.roles = []; + }); + }); + manifest.addPartialVariant((variant) => { + variant.language = 'en'; + variant.addPartialStream(ContentType.VIDEO); + variant.addPartialStream(ContentType.AUDIO, (stream) => { + stream.language = 'en'; + stream.roles = [ + 'public.accessibility.describes-video', + 'public.accessibility.describes-music-and-sound', + ]; + }); + }); + manifest.addPartialTextStream((stream) => { + stream.language = 'en'; + stream.kind = TextStreamKind.SUBTITLE; + stream.roles = [ + 'subtitle', + ]; + }); + manifest.addPartialTextStream((stream) => { + stream.language = 'en'; + stream.kind = TextStreamKind.SUBTITLE; + stream.roles = [ + 'public.accessibility.describes-music-and-sound', + ]; + }); + manifest.sequenceMode = sequenceMode; + manifest.type = shaka.media.ManifestParser.HLS; + }); + + fakeNetEngine.setResponseText('test:/master', master); + + const actual = await parser.start('test:/master', playerInterface); + expect(actual).toEqual(manifest); + }); + it('parses characteristics from text tags', async () => { const master = [ '#EXTM3U\n',