mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
fix(HLS): Fix subtitle timing (#7625)
Simplifies subtitle management for sequence mode and segments mode Runs subtitle tests in segments mode as well (Tizen 3.0) Fixes: https://github.com/shaka-project/shaka-player/issues/7447
This commit is contained in:
committed by
GitHub
parent
67cbe9915d
commit
9e2b15ead4
@@ -272,6 +272,8 @@ module.exports = (config) => {
|
||||
{pattern: 'test/test/assets/hls-raw-ec3/*', included: false},
|
||||
{pattern: 'test/test/assets/hls-raw-mp3/*', included: false},
|
||||
{pattern: 'test/test/assets/hls-sample-aes/*', included: false},
|
||||
// eslint-disable-next-line max-len
|
||||
{pattern: 'test/test/assets/hls-text-no-discontinuity/*', included: false},
|
||||
{pattern: 'test/test/assets/hls-text-offset/*', included: false},
|
||||
{pattern: 'test/test/assets/hls-ts-aac/*', included: false},
|
||||
{pattern: 'test/test/assets/hls-ts-ac3/*', included: false},
|
||||
|
||||
@@ -4126,7 +4126,7 @@ shaka.hls.HlsParser = class {
|
||||
let aesKey = undefined;
|
||||
|
||||
let discontinuitySequence = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
||||
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE', 0);
|
||||
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE', -1);
|
||||
const mediaSequenceNumber = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
||||
playlist.tags, 'EXT-X-MEDIA-SEQUENCE', 0);
|
||||
const skipTag = shaka.hls.Utils.getFirstTagWithName(
|
||||
|
||||
@@ -1139,7 +1139,8 @@ shaka.media.MediaSourceEngine = class {
|
||||
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
||||
|
||||
if (contentType == ContentType.TEXT) {
|
||||
if (this.sequenceMode_) {
|
||||
if (this.manifestType_ == shaka.media.ManifestParser.HLS &&
|
||||
reference.discontinuitySequence >= 0) {
|
||||
// This won't be known until the first video segment is appended.
|
||||
const offset = await this.textSequenceModeOffset_;
|
||||
this.textEngine_.setTimestampOffset(offset);
|
||||
@@ -1233,7 +1234,7 @@ shaka.media.MediaSourceEngine = class {
|
||||
const isBestSourceBufferForTimestamps =
|
||||
contentType == ContentType.VIDEO ||
|
||||
!(ContentType.VIDEO in this.sourceBuffers_);
|
||||
if (this.sequenceMode_ && isBestSourceBufferForTimestamps) {
|
||||
if (isBestSourceBufferForTimestamps) {
|
||||
this.textSequenceModeOffset_.resolve(timestampOffset);
|
||||
}
|
||||
}
|
||||
@@ -1562,6 +1563,10 @@ shaka.media.MediaSourceEngine = class {
|
||||
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
|
||||
}
|
||||
|
||||
if (!this.sequenceMode_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Queue an abort() to help MSE splice together overlapping segments.
|
||||
// We set appendWindowEnd when we change periods in DASH content, and the
|
||||
// period transition may result in overlap.
|
||||
|
||||
@@ -295,7 +295,7 @@ shaka.media.SegmentReference = class {
|
||||
this.thumbnailSprite = null;
|
||||
|
||||
/** @type {number} */
|
||||
this.discontinuitySequence = 0;
|
||||
this.discontinuitySequence = -1;
|
||||
|
||||
/** @type {boolean} */
|
||||
this.allPartialSegments = allPartialSegments;
|
||||
|
||||
@@ -2152,17 +2152,15 @@ shaka.media.StreamingEngine = class {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.manifest_.sequenceMode) {
|
||||
const lastDiscontinuitySequence =
|
||||
mediaState.lastSegmentReference ?
|
||||
mediaState.lastSegmentReference.discontinuitySequence : null;
|
||||
// Across discontinuity bounds, we should resync timestamps for
|
||||
// sequence mode playbacks. The next segment appended should
|
||||
// land at its theoretical timestamp from the segment index.
|
||||
if (reference.discontinuitySequence != lastDiscontinuitySequence) {
|
||||
operations.push(this.playerInterface_.mediaSourceEngine.resync(
|
||||
mediaState.type, reference.startTime));
|
||||
}
|
||||
const lastDiscontinuitySequence =
|
||||
mediaState.lastSegmentReference ?
|
||||
mediaState.lastSegmentReference.discontinuitySequence : null;
|
||||
// Across discontinuity bounds, we should resync timestamps. The next
|
||||
// segment appended should land at its theoretical timestamp from the
|
||||
// segment index.
|
||||
if (reference.discontinuitySequence != lastDiscontinuitySequence) {
|
||||
operations.push(this.playerInterface_.mediaSourceEngine.resync(
|
||||
mediaState.type, reference.startTime));
|
||||
}
|
||||
|
||||
await Promise.all(operations);
|
||||
|
||||
@@ -86,13 +86,7 @@ shaka.text.VttTextParser = class {
|
||||
// Only use 'X-TIMESTAMP-MAP' with HLS. This overrides offset above.
|
||||
if (blocks[0].includes('X-TIMESTAMP-MAP') &&
|
||||
this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
||||
if (this.sequenceMode_) {
|
||||
// Compute a different, rollover-based offset for sequence mode.
|
||||
offset = this.computeHlsSequenceModeOffset_(blocks[0], time);
|
||||
} else {
|
||||
// Calculate the offset from the segment startTime.
|
||||
offset = time.segmentStart;
|
||||
}
|
||||
offset = this.computeHlsOffset_(blocks[0], time);
|
||||
}
|
||||
|
||||
// Parse VTT regions.
|
||||
@@ -129,7 +123,7 @@ shaka.text.VttTextParser = class {
|
||||
* @return {number}
|
||||
* @private
|
||||
*/
|
||||
computeHlsSequenceModeOffset_(headerBlock, time) {
|
||||
computeHlsOffset_(headerBlock, time) {
|
||||
// https://bit.ly/2K92l7y
|
||||
// The 'X-TIMESTAMP-MAP' header is used in HLS to align text with
|
||||
// the rest of the media.
|
||||
|
||||
@@ -111,10 +111,6 @@ describe('HlsParser', () => {
|
||||
});
|
||||
|
||||
it('supports text discontinuity', async () => {
|
||||
if (!shaka.util.Platform.supportsSequenceMode()) {
|
||||
pending('Sequence mode is not supported by the platform.');
|
||||
}
|
||||
|
||||
player.setTextTrackVisibility(true);
|
||||
|
||||
await player.load('/base/test/test/assets/hls-text-offset/index.m3u8');
|
||||
@@ -134,4 +130,25 @@ describe('HlsParser', () => {
|
||||
|
||||
await player.unload();
|
||||
});
|
||||
|
||||
it('supports text without discontinuity', async () => {
|
||||
player.setTextTrackVisibility(true);
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
await player.load('/base/test/test/assets/hls-text-no-discontinuity/index.m3u8');
|
||||
await video.play();
|
||||
|
||||
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 1, 30);
|
||||
|
||||
const cues = video.textTracks[0].cues;
|
||||
expect(cues.length).toBe(3);
|
||||
expect(cues[0].startTime).toBeCloseTo(0.6, 0);
|
||||
expect(cues[0].endTime).toBeCloseTo(2.88, 0);
|
||||
expect(cues[1].startTime).toBeCloseTo(2.88, 0);
|
||||
expect(cues[1].endTime).toBeCloseTo(6.36, 0);
|
||||
expect(cues[2].startTime).toBeCloseTo(6.36, 0);
|
||||
expect(cues[2].endTime).toBeCloseTo(10.68, 0);
|
||||
|
||||
await player.unload();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1153,6 +1153,7 @@ describe('HlsParser', () => {
|
||||
'#EXT-X-VERSION:3\n',
|
||||
'#EXT-X-TARGETDURATION:5\n',
|
||||
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
||||
'#EXT-X-DISCONTINUITY-SEQUENCE:0\n',
|
||||
'#EXTINF:3,\n',
|
||||
'clip0-video-0.ts\n',
|
||||
'#EXTINF:1,\n',
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
#EXT-X-TARGETDURATION:7
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXT-X-INDEPENDENT-SEGMENTS
|
||||
#EXTINF:6.000000,
|
||||
0.ts
|
||||
#EXTINF:6.000000,
|
||||
1.ts
|
||||
#EXT-X-ENDLIST
|
||||
@@ -0,0 +1,6 @@
|
||||
#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="de",DEFAULT=NO,AUTOSELECT=NO,LANGUAGE="de",FORCED="NO",URI="text.m3u8"
|
||||
|
||||
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1240800,CODECS="avc1.640014,mp4a.40.2",RESOLUTION=256x144,SUBTITLES="subs"
|
||||
av.m3u8
|
||||
@@ -0,0 +1,15 @@
|
||||
WEBVTT
|
||||
|
||||
1
|
||||
00:00:00.600 --> 00:00:02.880
|
||||
Heute haben wir einen wesentlichen Meilenstein
|
||||
|
||||
2
|
||||
00:00:02.880 --> 00:00:06.360
|
||||
auf dem Weg zur Science
|
||||
City Hamburg Bahrenfeld erreicht.
|
||||
|
||||
3
|
||||
00:00:06.360 --> 00:00:10.680
|
||||
Die Science City ist ein 125 Hektar
|
||||
großes Areal in Bahrenfeld,
|
||||
@@ -0,0 +1,8 @@
|
||||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-TARGETDURATION:12
|
||||
#EXTINF:12.000,
|
||||
subtitle.vtt
|
||||
#EXT-X-ENDLIST
|
||||
Reference in New Issue
Block a user