diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index ccb235b08c..435176d13f 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -1677,8 +1677,6 @@ shaka.hls.HlsParser = class { stream.encrypted = realStream.encrypted; stream.drmInfos = realStream.drmInfos; stream.keyIds = realStream.keyIds; - stream.kind = realStream.kind; - stream.roles = realStream.roles; stream.mimeType = realStream.mimeType; if (shaka.media.MediaSourceEngine.RAW_FORMATS.includes(stream.mimeType)) { stream.codecs = ''; @@ -1944,16 +1942,6 @@ shaka.hls.HlsParser = class { /** @type {!shaka.media.SegmentIndex} */ const segmentIndex = new shaka.media.SegmentIndex(segments); - const kind = (type == shaka.util.ManifestParserUtils.ContentType.TEXT) ? - shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE : undefined; - - const roles = []; - if (characteristics) { - for (const characteristic of characteristics.split(',')) { - roles.push(characteristic); - } - } - const serverControlTag = shaka.hls.Utils.getFirstTagWithName( playlist.tags, 'EXT-X-SERVER-CONTROL'); const canSkipSegments = serverControlTag ? @@ -1965,8 +1953,6 @@ shaka.hls.HlsParser = class { stream.encrypted = encrypted; stream.drmInfos = drmInfos; stream.keyIds = keyIds; - stream.kind = kind; - stream.roles = roles; stream.mimeType = mimeType; return { @@ -2016,7 +2002,8 @@ shaka.hls.HlsParser = class { segmentIndex: null, mimeType, codecs, - kind: undefined, + kind: (type == shaka.util.ManifestParserUtils.ContentType.TEXT) ? + shaka.util.ManifestParserUtils.TextStreamKind.SUBTITLE : undefined, encrypted: false, drmInfos: [], keyIds: new Set(), @@ -2032,7 +2019,7 @@ shaka.hls.HlsParser = class { width: undefined, height: undefined, bandwidth: undefined, - roles: [], + roles: characteristics ? characteristics.split(',') : [], forced, channelsCount, audioSamplingRate: null, diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index 541475bbc6..6aba12084d 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -1090,6 +1090,77 @@ describe('HlsParser', () => { await testHlsParser(master, media, manifest); }); + // https://github.com/shaka-project/shaka-player/issues/4759 + it('makes roles available without loading tracks', 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 (caption)",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-spoken-dialog,', + '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'; + }); + }); + 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; + }); + manifest.addPartialTextStream((stream) => { + stream.language = 'en'; + stream.kind = TextStreamKind.SUBTITLE; + stream.roles = [ + 'public.accessibility.describes-spoken-dialog', + 'public.accessibility.describes-music-and-sound', + ]; + }); + manifest.sequenceMode = true; + }); + + fakeNetEngine.setResponseText('test:/master', master); + + // NOTE: Not using testHlsParser here because that unconditionally loads all + // streams. We need to test the behavior specifically when streams are + // _not_ loaded. + const actual = await parser.start('test:/master', playerInterface); + expect(actual).toEqual(manifest); + }); + it('gets mime type from header request', async () => { const master = [ '#EXTM3U\n',