Skip to content

Commit

Permalink
fix(HLS): Fix support of fragmented WebVTT (shaka-project#5156)
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad committed Apr 18, 2023
1 parent fdc5cb1 commit 9c4a61f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
13 changes: 10 additions & 3 deletions lib/hls/hls_parser.js
Expand Up @@ -1729,9 +1729,9 @@ shaka.hls.HlsParser = class {
let codecs = '';
/** @type {string} */
const type = this.getType_(tag);
// Text does not require a codec.
if (type != shaka.util.ManifestParserUtils.ContentType.TEXT && groupId &&
this.groupIdToCodecsMap_.has(groupId)) {
if (type == shaka.util.ManifestParserUtils.ContentType.TEXT) {
codecs = tag.getAttributeValue('CODECS') || '';
} else if (groupId && this.groupIdToCodecsMap_.has(groupId)) {
codecs = this.groupIdToCodecsMap_.get(groupId);
}

Expand Down Expand Up @@ -2007,6 +2007,13 @@ shaka.hls.HlsParser = class {
}
}

if (type == ContentType.TEXT) {
const firstSegment = realStream.segmentIndex.get(0);
if (firstSegment && firstSegment.initSegmentReference) {
stream.mimeType = 'application/mp4';
}
}

// Add finishing touches to the stream that can only be done once we have
// more full context on the media as a whole.
if (this.hasEnoughInfoToFinalizeStreams_()) {
Expand Down
9 changes: 8 additions & 1 deletion lib/media/streaming_engine.js
Expand Up @@ -378,7 +378,7 @@ shaka.media.StreamingEngine = class {
/**
* @param {shaka.extern.Stream} textStream
*/
switchTextStream(textStream) {
async switchTextStream(textStream) {
this.currentTextStream_ = textStream;

if (!this.startupComplete_) {
Expand All @@ -390,6 +390,13 @@ shaka.media.StreamingEngine = class {
goog.asserts.assert(textStream && textStream.type == ContentType.TEXT,
'Wrong stream type passed to switchTextStream!');

// In HLS it is possible that the mimetype changes when the media
// playlist is downloaded, so it is necessary to have the updated data
// here.
if (!textStream.segmentIndex) {
await textStream.createSegmentIndex();
}

this.switchInternal_(
textStream, /* clearBuffer= */ true,
/* safeMargin= */ 0, /* force= */ false);
Expand Down
45 changes: 45 additions & 0 deletions test/hls/hls_parser_unit.js
Expand Up @@ -2263,6 +2263,51 @@ describe('HlsParser', () => {
expect(actual).toEqual(manifest);
});

it('parses manifest with MP4+WEBVTT streams', async () => {
const master = [
'#EXTM3U\n',
'#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="sub1",LANGUAGE="eng",',
'CODECS="wvtt",URI="text"\n',
'#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1",',
'RESOLUTION=960x540,FRAME-RATE=60,SUBTITLES="sub1"\n',
'video\n',
].join('');

const media = [
'#EXTM3U\n',
'#EXT-X-PLAYLIST-TYPE:VOD\n',
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
'#EXTINF:5,\n',
'#EXT-X-BYTERANGE:121090@616\n',
'main.mp4',
].join('');

const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
manifest.anyTimeline();
manifest.addPartialVariant((variant) => {
variant.addPartialStream(ContentType.VIDEO);
});
manifest.addPartialTextStream((stream) => {
stream.language = 'en';
stream.mime('application/mp4', 'wvtt');
});
manifest.sequenceMode = sequenceMode;
manifest.type = shaka.media.ManifestParser.HLS;
});

fakeNetEngine
.setResponseText('test:/master', master)
.setResponseText('test:/audio', media)
.setResponseText('test:/video', media)
.setResponseText('test:/text', media)
.setResponseValue('test:/init.mp4', initSegmentData)
.setResponseValue('test:/main.mp4', segmentData);

const actual = await parser.start('test:/master', playerInterface);
await loadAllStreamsFor(actual);
expect(actual).toEqual(manifest);
});

it('detects VTT streams by codec', async () => {
const master = [
'#EXTM3U\n',
Expand Down

0 comments on commit 9c4a61f

Please sign in to comment.