diff --git a/demo/common/message_ids.js b/demo/common/message_ids.js index 2b58d068c0..6ddc23d326 100644 --- a/demo/common/message_ids.js +++ b/demo/common/message_ids.js @@ -232,6 +232,7 @@ shakaDemo.MessageIds = { RESTRICTIONS_SECTION_HEADER: 'DEMO_RESTRICTIONS_SECTION_HEADER', SAFE_SEEK_OFFSET: 'DEMO_SAFE_SEEK_OFFSET', SAFE_SKIP_DISTANCE: 'DEMO_SAFE_SKIP_DISTANCE', + SEGMENT_RELATIVE_VTT_TIMING: 'DEMO_SEGMENT_RELATIVE_VTT_TIMING', SESSION_ID: 'DEMO_SESSION_ID', SHAKA_CONTROLS: 'DEMO_SHAKA_CONTROLS', SLOW_HALF_LIFE: 'DEMO_SLOW_HALF_LIFE', diff --git a/demo/config.js b/demo/config.js index 738e01719b..a220857b3d 100644 --- a/demo/config.js +++ b/demo/config.js @@ -237,7 +237,9 @@ shakaDemo.Config = class { .addBoolInput_(MessageIds.DISABLE_TEXT, 'manifest.disableText') .addBoolInput_(MessageIds.DISABLE_THUMBNAILS, - 'manifest.disableThumbnails'); + 'manifest.disableThumbnails') + .addBoolInput_(MessageIds.SEGMENT_RELATIVE_VTT_TIMING, + 'manifest.segmentRelativeVttTiming'); this.addRetrySection_('manifest', MessageIds.MANIFEST_RETRY_SECTION_HEADER); } diff --git a/demo/locales/en.json b/demo/locales/en.json index 670d8717a0..d51d7a676e 100644 --- a/demo/locales/en.json +++ b/demo/locales/en.json @@ -180,6 +180,7 @@ "DEMO_RESTRICTIONS_SECTION_HEADER": "Restrictions", "DEMO_SAFE_SEEK_OFFSET": "Safe Seek Offset", "DEMO_SAFE_SKIP_DISTANCE": "Safe Skip Distance", + "DEMO_SEGMENT_RELATIVE_VTT_TIMING": "Enable segment-relative VTT Timing", "DEMO_SESSION_ID": "Session ID", "DEMO_SAVE_BUTTON": "Save", "DEMO_SHAKA": "Shaka", diff --git a/demo/locales/source.json b/demo/locales/source.json index 2e75a0f548..d005b400bb 100644 --- a/demo/locales/source.json +++ b/demo/locales/source.json @@ -727,6 +727,10 @@ "description": "A button to save a custom asset.", "message": "Save" }, + "DEMO_SEGMENT_RELATIVE_VTT_TIMING": { + "description": "The name of a configuration value.", + "message": "Enable segment-relative VTT Timing" + }, "DEMO_SESSION_ID": { "description": "The name of a configuration value.", "message": "Session ID" diff --git a/externs/shaka/player.js b/externs/shaka/player.js index b56db3f62e..da49d258be 100644 --- a/externs/shaka/player.js +++ b/externs/shaka/player.js @@ -792,6 +792,7 @@ shaka.extern.HlsManifestConfiguration; * disableText: boolean, * disableThumbnails: boolean, * defaultPresentationDelay: number, + * segmentRelativeVttTiming: boolean, * dash: shaka.extern.DashManifestConfiguration, * hls: shaka.extern.HlsManifestConfiguration * }} @@ -823,6 +824,10 @@ shaka.extern.HlsManifestConfiguration; * configured or set as 0. * For HLS, the default value is 3 segments duration if not configured or * set as 0. + * @property {boolean} segmentRelativeVttTiming + * Option to calculate VTT text timings relative to the segment start + * instead of relative to the period start (which is the default). + * Defaults to false. * @property {shaka.extern.DashManifestConfiguration} dash * Advanced parameters used by the DASH manifest parser. * @property {shaka.extern.HlsManifestConfiguration} hls diff --git a/externs/shaka/text.js b/externs/shaka/text.js index 6403664c6e..d50d2c2b33 100644 --- a/externs/shaka/text.js +++ b/externs/shaka/text.js @@ -442,7 +442,8 @@ shaka.extern.TextParser = class { * @typedef {{ * periodStart: number, * segmentStart: number, - * segmentEnd: number + * segmentEnd: number, + * vttOffset: number * }} * * @property {number} periodStart @@ -451,6 +452,9 @@ shaka.extern.TextParser = class { * The absolute start time of the segment in seconds. * @property {number} segmentEnd * The absolute end time of the segment in seconds. + * @property {number} vttOffset + * The start time relative to either segment or period start depending + * on segmentRelativeVttTiming configuration. * * @exportDoc */ diff --git a/lib/media/media_source_engine.js b/lib/media/media_source_engine.js index 3f5fe6be23..8fd1931161 100644 --- a/lib/media/media_source_engine.js +++ b/lib/media/media_source_engine.js @@ -66,6 +66,9 @@ shaka.media.MediaSourceEngine = class { /** @private {shaka.text.TextEngine} */ this.textEngine_ = null; + /** @private {boolean} */ + this.segmentRelativeVttTiming_ = false; + const onMetadataNoOp = (metadata, timestampOffset, segmentEnd) => {}; /** @private {!function(!Array., @@ -367,7 +370,8 @@ shaka.media.MediaSourceEngine = class { if (!this.textEngine_) { this.textEngine_ = new shaka.text.TextEngine(this.textDisplayer_); } - this.textEngine_.initParser(mimeType, sequenceMode); + this.textEngine_.initParser(mimeType, sequenceMode, + this.segmentRelativeVttTiming_); } /** @@ -1113,6 +1117,13 @@ shaka.media.MediaSourceEngine = class { } } + /** + * @param {boolean} segmentRelativeVttTiming + */ + setSegmentRelativeVttTiming(segmentRelativeVttTiming) { + this.segmentRelativeVttTiming_ = segmentRelativeVttTiming; + } + /** * Apply platform-specific transformations to this segment to work around * issues in the platform. diff --git a/lib/player.js b/lib/player.js index 7e4892caa1..d9952af152 100644 --- a/lib/player.js +++ b/lib/player.js @@ -1571,6 +1571,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { (metadata, offset, endTime) => { this.processTimedMetadataMediaSrc_(metadata, offset, endTime); }); + const {segmentRelativeVttTiming} = this.config_.manifest; + mediaSourceEngine.setSegmentRelativeVttTiming(segmentRelativeVttTiming); // Wait for media source engine to finish opening. This promise should // NEVER be rejected as per the media source engine implementation. @@ -3020,6 +3022,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget { } if (this.mediaSourceEngine_) { + const {segmentRelativeVttTiming} = this.config_.manifest; + this.mediaSourceEngine_.setSegmentRelativeVttTiming( + segmentRelativeVttTiming); + const textDisplayerFactory = this.config_.textDisplayFactory; if (this.lastTextFactory_ != textDisplayerFactory) { const displayer = @@ -4864,6 +4870,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { periodStart: 0, segmentStart: 0, segmentEnd: this.video_.duration, + vttOffset: 0, }; const data = shaka.util.BufferUtils.toUint8(buffer); const cues = obj.parseMedia(data, time); diff --git a/lib/text/text_engine.js b/lib/text/text_engine.js index 151ff0898d..c968542572 100644 --- a/lib/text/text_engine.js +++ b/lib/text/text_engine.js @@ -31,6 +31,9 @@ shaka.text.TextEngine = class { /** @private {shaka.extern.TextDisplayer} */ this.displayer_ = displayer; + /** @private {boolean} */ + this.segmentRelativeVttTiming_ = false; + /** @private {number} */ this.timestampOffset_ = 0; @@ -130,8 +133,9 @@ shaka.text.TextEngine = class { * * @param {string} mimeType * @param {boolean} sequenceMode + * @param {boolean} segmentRelativeVttTiming */ - initParser(mimeType, sequenceMode) { + initParser(mimeType, sequenceMode, segmentRelativeVttTiming) { // No parser for CEA, which is extracted from video and side-loaded // into TextEngine and TextDisplayer. if (mimeType == shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE || @@ -149,6 +153,7 @@ shaka.text.TextEngine = class { shaka.log.alwaysWarn( 'Text parsers should have a "setSequenceMode" method!'); } + this.segmentRelativeVttTiming_ = segmentRelativeVttTiming; } /** @@ -174,11 +179,15 @@ shaka.text.TextEngine = class { return; } + const vttOffset = this.segmentRelativeVttTiming_ ? + startTime : this.timestampOffset_; + /** @type {shaka.extern.TextParser.TimeContext} **/ const time = { periodStart: this.timestampOffset_, segmentStart: startTime, segmentEnd: endTime, + vttOffset: vttOffset, }; // Parse the buffer and add the new cues. diff --git a/lib/text/vtt_text_parser.js b/lib/text/vtt_text_parser.js index 73334e545f..51bd1ad02a 100644 --- a/lib/text/vtt_text_parser.js +++ b/lib/text/vtt_text_parser.js @@ -62,9 +62,13 @@ shaka.text.VttTextParser = class { shaka.util.Error.Code.INVALID_TEXT_HEADER); } + // Depending on "segmentRelativeVttTiming" configuration, + // "vttOffset" will correspond to either "periodStart" (default) + // or "segmentStart", for segmented VTT where timings are relative + // to the beginning of each segment. // NOTE: "periodStart" is the timestamp offset applied via TextEngine. // It is no longer closely tied to periods, but the name stuck around. - let offset = time.periodStart; + let offset = time.vttOffset; // Do not honor the 'X-TIMESTAMP-MAP' value when in sequence mode. // That is because it is used mainly (solely?) to account for the timestamp diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js index 4ca307f179..f0444d32ee 100644 --- a/lib/util/player_configuration.js +++ b/lib/util/player_configuration.js @@ -89,6 +89,7 @@ shaka.util.PlayerConfiguration = class { disableText: false, disableThumbnails: false, defaultPresentationDelay: 0, + segmentRelativeVttTiming: false, dash: { clockSyncUri: '', ignoreDrmInfo: false, diff --git a/test/player_unit.js b/test/player_unit.js index 968205a897..2375e010db 100644 --- a/test/player_unit.js +++ b/test/player_unit.js @@ -140,6 +140,8 @@ describe('Player', () => { jasmine.createSpy('destroy').and.returnValue(Promise.resolve()), setUseEmbeddedText: jasmine.createSpy('setUseEmbeddedText'), getUseEmbeddedText: jasmine.createSpy('getUseEmbeddedText'), + setSegmentRelativeVttTiming: + jasmine.createSpy('setSegmentRelativeVttTiming'), getTextDisplayer: () => textDisplayer, ended: jasmine.createSpy('ended').and.returnValue(false), }; diff --git a/test/test/util/fake_media_source_engine.js b/test/test/util/fake_media_source_engine.js index 5e142e214e..9fc9966398 100644 --- a/test/test/util/fake_media_source_engine.js +++ b/test/test/util/fake_media_source_engine.js @@ -132,6 +132,10 @@ shaka.test.FakeMediaSourceEngine = class { this.getTextDisplayer = jasmine.createSpy('getTextDisplayer') .and.returnValue(new shaka.test.FakeTextDisplayer()); + + /** @type {!jasmine.Spy} */ + this.setSegmentRelativeVttTiming = + jasmine.createSpy('setSegmentRelativeVttTiming').and.stub(); } /** @override */ diff --git a/test/text/cue_integration.js b/test/text/cue_integration.js index 09d7b1fac6..89b850b3ba 100644 --- a/test/text/cue_integration.js +++ b/test/text/cue_integration.js @@ -23,7 +23,7 @@ describe('Cue', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000\n' + 'Test', - {periodStart: 7, segmentStart: 10, segmentEnd: 60}); + {periodStart: 7, segmentStart: 10, segmentEnd: 60, vttOffset: 7}); expect(cues.length).toBe(1); expect(cues[0].startTime).toBe(27); expect(cues[0].endTime).toBe(47); @@ -38,7 +38,7 @@ describe('Cue', () => { 'ID1\n' + '00:00:20.000 --> 00:00:40.000 align:middle size:56% vertical:lr\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); expect(cues.length).toBe(1); }); diff --git a/test/text/lrc_text_parser_unit.js b/test/text/lrc_text_parser_unit.js index 396e816948..8896a71937 100644 --- a/test/text/lrc_text_parser_unit.js +++ b/test/text/lrc_text_parser_unit.js @@ -12,7 +12,7 @@ describe('LrcTextParser', () => { it('supports no cues', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the start of the file', () => { @@ -22,7 +22,7 @@ describe('LrcTextParser', () => { ], '\n\n' + '[00:00.00]Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the end of the file', () => { @@ -32,7 +32,7 @@ describe('LrcTextParser', () => { ], '[00:00.00]Test' + '\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no blank line at the end of the file', () => { @@ -41,8 +41,7 @@ describe('LrcTextParser', () => { {startTime: 0, endTime: 2, payload: 'Test'}, ], '[00:00.00]Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports multiple cues', () => { @@ -55,7 +54,7 @@ describe('LrcTextParser', () => { '[00:00.00]Test\n' + '[00:10.00]Test2\n' + '[00:20.00]Test3', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports different time formats', () => { @@ -74,7 +73,7 @@ describe('LrcTextParser', () => { '[00:30,1]Test4\n' + '[00:40,001]Test5\n' + '[00:50,02]Test6', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); /** diff --git a/test/text/mp4_ttml_parser_unit.js b/test/text/mp4_ttml_parser_unit.js index d1410062bd..565ae179e7 100644 --- a/test/text/mp4_ttml_parser_unit.js +++ b/test/text/mp4_ttml_parser_unit.js @@ -47,7 +47,7 @@ describe('Mp4TtmlParser', () => { it('handles media segments with multiple mdats', () => { const parser = new shaka.text.Mp4TtmlParser(); parser.parseInit(ttmlInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const ret = parser.parseMedia(ttmlSegmentMultipleMDAT, time); // Bodies. expect(ret.length).toBe(2); @@ -60,8 +60,10 @@ describe('Mp4TtmlParser', () => { }); it('accounts for offset', () => { - const time1 = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; - const time2 = {periodStart: 7, segmentStart: 0, segmentEnd: 0}; + const time1 = + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; + const time2 = + {periodStart: 7, segmentStart: 0, segmentEnd: 0, vttOffset: 7}; const parser = new shaka.text.Mp4TtmlParser(); parser.parseInit(ttmlInitSegment); @@ -165,7 +167,7 @@ describe('Mp4TtmlParser', () => { ]; const parser = new shaka.text.Mp4TtmlParser(); parser.parseInit(ttmlInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const result = parser.parseMedia(ttmlSegment, time); shaka.test.TtmlUtils.verifyHelper( cues, result, {startTime: 23, endTime: 53.5}); diff --git a/test/text/mp4_vtt_parser_unit.js b/test/text/mp4_vtt_parser_unit.js index 92ef55710a..5b527b83e6 100644 --- a/test/text/mp4_vtt_parser_unit.js +++ b/test/text/mp4_vtt_parser_unit.js @@ -71,7 +71,7 @@ describe('Mp4VttParser', () => { const parser = new shaka.text.Mp4VttParser(); parser.parseInit(vttInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const result = parser.parseMedia(vttSegment, time); verifyHelper(cues, result); }); @@ -99,7 +99,7 @@ describe('Mp4VttParser', () => { const parser = new shaka.text.Mp4VttParser(); parser.parseInit(vttInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const result = parser.parseMedia(vttSegmentMultiPayload, time); verifyHelper(cues, result); }); @@ -127,7 +127,7 @@ describe('Mp4VttParser', () => { const parser = new shaka.text.Mp4VttParser(); parser.parseInit(vttInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const result = parser.parseMedia(vttSegSettings, time); verifyHelper(cues, result); }); @@ -149,7 +149,7 @@ describe('Mp4VttParser', () => { const parser = new shaka.text.Mp4VttParser(); parser.parseInit(vttInitSegment); - const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0}; + const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}; const result = parser.parseMedia(vttSegNoDuration, time); verifyHelper(cues, result); }); @@ -171,7 +171,8 @@ describe('Mp4VttParser', () => { const parser = new shaka.text.Mp4VttParser(); parser.parseInit(vttInitSegment); - const time = {periodStart: 10, segmentStart: 0, segmentEnd: 0}; + const time = + {periodStart: 10, segmentStart: 0, segmentEnd: 0, vttOffset: 10}; const result = parser.parseMedia(vttSegment, time); verifyHelper(cues, result); }); diff --git a/test/text/sbv_text_parser_unit.js b/test/text/sbv_text_parser_unit.js index b06fc2c77f..31896f5bb5 100644 --- a/test/text/sbv_text_parser_unit.js +++ b/test/text/sbv_text_parser_unit.js @@ -12,7 +12,7 @@ describe('SbvTextParser', () => { it('supports no cues', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the end of the file', () => { @@ -22,7 +22,7 @@ describe('SbvTextParser', () => { ], '0:00:20.000,0:00:40.000\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no blank line at the end of the file', () => { @@ -32,8 +32,7 @@ describe('SbvTextParser', () => { ], '0:00:20.000,0:00:40.000\n' + 'Test\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no newline after the final text payload', () => { @@ -43,7 +42,7 @@ describe('SbvTextParser', () => { ], '0:00:20.000,0:00:40.000\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports multiple cues', () => { @@ -56,7 +55,7 @@ describe('SbvTextParser', () => { 'Test\n\n' + '0:00:40.000,0:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); /** diff --git a/test/text/srt_text_parser_unit.js b/test/text/srt_text_parser_unit.js index 5284d73671..39223cf211 100644 --- a/test/text/srt_text_parser_unit.js +++ b/test/text/srt_text_parser_unit.js @@ -12,7 +12,7 @@ describe('SrtTextParser', () => { it('supports no cues', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the end of the file', () => { @@ -23,7 +23,7 @@ describe('SrtTextParser', () => { '1\n' + '00:00:20,000 --> 00:00:40,000\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no blank line at the end of the file', () => { @@ -34,8 +34,7 @@ describe('SrtTextParser', () => { '1\n' + '00:00:20,000 --> 00:00:40,000\n' + 'Test\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no newline after the final text payload', () => { @@ -46,7 +45,7 @@ describe('SrtTextParser', () => { '1\n' + '00:00:20,000 --> 00:00:40,000\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports multiple cues', () => { @@ -61,7 +60,7 @@ describe('SrtTextParser', () => { '2\n' + '00:00:40,000 --> 00:00:50,000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); /** diff --git a/test/text/ssa_text_parser_unit.js b/test/text/ssa_text_parser_unit.js index ff3354ae5f..2711014339 100644 --- a/test/text/ssa_text_parser_unit.js +++ b/test/text/ssa_text_parser_unit.js @@ -15,7 +15,7 @@ describe('SsaTextParser', () => { it('supports no cues', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the start of the file', () => { @@ -38,7 +38,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the end of the file', () => { @@ -61,7 +61,7 @@ describe('SsaTextParser', () => { 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test' + '\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no blank line at the end of the file', () => { @@ -83,8 +83,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports no styles', () => { @@ -99,8 +98,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('support no script info', () => { @@ -120,8 +118,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports only events', () => { @@ -134,8 +131,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports text with commas', () => { @@ -148,8 +144,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test,1,Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports different time formats', () => { @@ -168,7 +163,7 @@ describe('SsaTextParser', () => { ',,{\\pos(400,570)}Test2\n' + 'Dialogue: 0,0:00:08.01,0:00:10.001,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test3', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports multiple cues', () => { @@ -187,7 +182,7 @@ describe('SsaTextParser', () => { ',,{\\pos(400,570)}Test2\n' + 'Dialogue: 0,0:00:08.01,0:00:10.10,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test3', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports fontFamily style', () => { @@ -212,8 +207,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports color & backgroundColor style', () => { @@ -239,8 +233,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports bold style', () => { @@ -265,8 +258,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports italic style', () => { @@ -291,8 +283,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports underline style', () => { @@ -317,8 +308,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports letterSpacing style', () => { @@ -343,8 +333,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports V4 style', () => { @@ -369,8 +358,7 @@ describe('SsaTextParser', () => { 'Effect, Text\n' + 'Dialogue: 0,0:00:00.00,0:00:02.00,DefaultVCD, NTP,0000,0000,0000' + ',,{\\pos(400,570)}Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); /** diff --git a/test/text/text_engine_unit.js b/test/text/text_engine_unit.js index 46c6606de1..87059c5b8c 100644 --- a/test/text/text_engine_unit.js +++ b/test/text/text_engine_unit.js @@ -51,7 +51,10 @@ describe('TextEngine', () => { TextEngine.registerParser(dummyMimeType, mockParserPlugIn); textEngine = new TextEngine(mockDisplayer); - textEngine.initParser(dummyMimeType, false); + textEngine.initParser( + dummyMimeType, + /* sequenceMode= */ false, + /* segmentRelativeVttTiming= */ false); }); afterEach(() => { @@ -96,7 +99,7 @@ describe('TextEngine', () => { await textEngine.appendBuffer(dummyData, 0, 3); expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ dummyData, - {periodStart: 0, segmentStart: 0, segmentEnd: 3}, + {periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0}, ]); expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([ @@ -111,7 +114,7 @@ describe('TextEngine', () => { expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ dummyData, - {periodStart: 0, segmentStart: 3, segmentEnd: 5}, + {periodStart: 0, segmentStart: 3, segmentEnd: 5, vttOffset: 0}, ]); expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([ @@ -263,7 +266,7 @@ describe('TextEngine', () => { expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ dummyData, - {periodStart: 0, segmentStart: 0, segmentEnd: 3}, + {periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0}, ]); expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([ [ @@ -277,7 +280,7 @@ describe('TextEngine', () => { expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ dummyData, - {periodStart: 4, segmentStart: 4, segmentEnd: 7}, + {periodStart: 4, segmentStart: 4, segmentEnd: 7, vttOffset: 4}, ]); expect(mockDisplayer.appendSpy).toHaveBeenCalledOnceMoreWith([ [ @@ -286,6 +289,38 @@ describe('TextEngine', () => { ], ]); }); + + it('vttOffset when segmentRelativeVttTiming is set', async () => { + textEngine.initParser( + dummyMimeType, + /* sequenceMode= */ false, + /* segmentRelativeVttTiming= */ true); + + mockParseMedia.and.callFake((data, time) => { + return [ + createFakeCue(time.periodStart + 0, + time.periodStart + 1), + createFakeCue(time.periodStart + 2, + time.periodStart + 3), + ]; + }); + + await textEngine.appendBuffer(dummyData, 0, 3); + + expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ + dummyData, + {periodStart: 0, segmentStart: 0, segmentEnd: 3, vttOffset: 0}, + ]); + + textEngine.setTimestampOffset(8); + await textEngine.appendBuffer(dummyData, 4, 7); + + // vttOffset should equal segmentStart instead of periodStart + expect(mockParseMedia).toHaveBeenCalledOnceMoreWith([ + dummyData, + {periodStart: 8, segmentStart: 4, segmentEnd: 7, vttOffset: 4}, + ]); + }); }); describe('bufferStart/bufferEnd', () => { diff --git a/test/text/ttml_text_parser_unit.js b/test/text/ttml_text_parser_unit.js index 2c36ba75df..d1fda62b2b 100644 --- a/test/text/ttml_text_parser_unit.js +++ b/test/text/ttml_text_parser_unit.js @@ -22,14 +22,14 @@ describe('TtmlTextParser', () => { it('supports no cues', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {}); }); it('supports empty text string', () => { verifyHelper([], '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {}); }); @@ -37,7 +37,7 @@ describe('TtmlTextParser', () => { verifyHelper( [], '
\r\n
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {}); }); @@ -64,7 +64,7 @@ describe('TtmlTextParser', () => { }, ], '' + ttBody + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // When xml:space="preserve", take them into account. verifyHelper( @@ -90,7 +90,7 @@ describe('TtmlTextParser', () => { }, ], '' + ttBody + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // The default value for xml:space is "default". verifyHelper( @@ -106,7 +106,7 @@ describe('TtmlTextParser', () => { }, ], '' + ttBody + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); // Any other value is rejected as an error. @@ -137,7 +137,7 @@ describe('TtmlTextParser', () => { }, ], '' + ttBody + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.03, endTime: 62.05}); }); @@ -207,7 +207,7 @@ describe('TtmlTextParser', () => { 'First cue
Second cue' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -243,7 +243,7 @@ describe('TtmlTextParser', () => { 'First cue
Second cue' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -302,7 +302,7 @@ describe('TtmlTextParser', () => { '' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -321,7 +321,7 @@ describe('TtmlTextParser', () => { '

' + 'Test

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -351,7 +351,7 @@ describe('TtmlTextParser', () => { '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -363,7 +363,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -375,7 +375,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 7, segmentStart: 0, segmentEnd: 0}, + {periodStart: 7, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 69.05, endTime: 3730.2}); }); @@ -398,7 +398,7 @@ describe('TtmlTextParser', () => { '
' + '

Nested cue

' + '
', - {periodStart: 7, segmentStart: 0, segmentEnd: 0}, + {periodStart: 7, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 69.05, endTime: 3730.2}); }); @@ -410,7 +410,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 3567.03, endTime: 5402.3}); }); @@ -424,7 +424,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 615.5, endTime: 663}); }); @@ -438,7 +438,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 615.5, endTime: 663}); }); @@ -456,7 +456,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: Util.closeTo(615.5 + 1 / 60), endTime: 663}); }); @@ -470,7 +470,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 2.5, endTime: Util.closeTo(10.01)}); }); @@ -484,7 +484,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 5, endTime: Util.closeTo(6.02)}); }); @@ -496,7 +496,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 67.05}); }); @@ -506,7 +506,7 @@ describe('TtmlTextParser', () => { '
' + '' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {}); }); @@ -526,7 +526,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -548,7 +548,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -570,7 +570,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -595,7 +595,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -620,7 +620,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -641,7 +641,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -670,7 +670,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { viewportAnchorX: 50, @@ -698,7 +698,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { viewportAnchorX: 50, @@ -727,7 +727,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -763,7 +763,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -799,7 +799,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -836,7 +836,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -873,7 +873,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -911,7 +911,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -948,7 +948,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -977,7 +977,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { viewportAnchorX: 50, @@ -1005,7 +1005,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { viewportAnchorX: 50, @@ -1035,7 +1035,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, { region: { id: 'subtitleArea', @@ -1067,7 +1067,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); @@ -1088,7 +1088,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); @@ -1109,7 +1109,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); @@ -1130,7 +1130,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); @@ -1151,7 +1151,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1169,7 +1169,7 @@ describe('TtmlTextParser', () => { '
' + '' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); verifyHelper( @@ -1184,7 +1184,7 @@ describe('TtmlTextParser', () => { '' + '' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); verifyHelper( @@ -1197,7 +1197,7 @@ describe('TtmlTextParser', () => { '
' + '' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {}); }); @@ -1214,7 +1214,7 @@ describe('TtmlTextParser', () => { '' + '' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1237,7 +1237,7 @@ describe('TtmlTextParser', () => { '
' + '

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}, { startTime: 62.05, @@ -1260,7 +1260,7 @@ describe('TtmlTextParser', () => { '
' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 0, endTime: 62.05}, { startTime: 0, @@ -1291,7 +1291,7 @@ describe('TtmlTextParser', () => { '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1320,7 +1320,7 @@ describe('TtmlTextParser', () => { '

' + '

Line1
Line2

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); verifyHelper( @@ -1354,7 +1354,7 @@ describe('TtmlTextParser', () => { 'Line1
Line2
' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1382,7 +1382,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1408,7 +1408,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1456,7 +1456,7 @@ describe('TtmlTextParser', () => { '

Test

' + '

Test 2

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 4, region: {id: 'subtitleArea'}}, {startTime: 1, endTime: 4}); }); @@ -1481,7 +1481,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1503,7 +1503,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1540,7 +1540,7 @@ describe('TtmlTextParser', () => { 'Test' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1564,7 +1564,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1592,7 +1592,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1617,7 +1617,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1645,7 +1645,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1674,7 +1674,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 2}); }); @@ -1699,7 +1699,7 @@ describe('TtmlTextParser', () => { '
' + '

Test

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2, region: {id: 'subtitleArea'}}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1714,7 +1714,7 @@ describe('TtmlTextParser', () => { '

First cue

' + '

Second cue

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 4}); }); @@ -1738,7 +1738,7 @@ describe('TtmlTextParser', () => { '
' + '

äöü

' + '
', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 62.05, endTime: 3723.2}); }); @@ -1755,7 +1755,7 @@ describe('TtmlTextParser', () => { '

First cue

' + '

Second cue

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: Infinity}, {startTime: 3, endTime: Infinity}); @@ -1780,7 +1780,7 @@ describe('TtmlTextParser', () => { 'Second cue' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: Infinity}, {startTime: 3, endTime: Infinity}); }); @@ -1796,7 +1796,7 @@ describe('TtmlTextParser', () => { '

First cue

' + '

Second cue

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: 30}, {startTime: 3, endTime: 30}); }); @@ -1811,7 +1811,7 @@ describe('TtmlTextParser', () => { '

First cue

' + '

Second cue

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 1, endTime: Infinity}); }); @@ -1883,7 +1883,7 @@ describe('TtmlTextParser', () => { ' Test with spanStyle' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 0, endTime: 60}); }); @@ -1915,7 +1915,7 @@ describe('TtmlTextParser', () => { '

' + 'Hello!' + '

', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 0, endTime: 60}, ); }); @@ -1977,7 +1977,7 @@ describe('TtmlTextParser', () => { ' A
B' + '

' + '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, {startTime: 0, endTime: 60}); }); @@ -2018,7 +2018,7 @@ describe('TtmlTextParser', () => { expect(() => { new shaka.text.TtmlTextParser().parseMedia( shaka.util.BufferUtils.toUint8(data), - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }).toThrow(error); } }); diff --git a/test/text/vtt_text_parser_unit.js b/test/text/vtt_text_parser_unit.js index f2b1b51bf8..3aac2854a0 100644 --- a/test/text/vtt_text_parser_unit.js +++ b/test/text/vtt_text_parser_unit.js @@ -34,13 +34,13 @@ describe('VttTextParser', () => { it('supports no cues', () => { verifyHelper([], 'WEBVTT', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports initial comments', () => { verifyHelper([], 'WEBVTT - Comments', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports comment blocks', () => { @@ -48,7 +48,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + 'NOTE\n' + 'This is a comment block', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports comment blocks with inital comment', () => { @@ -56,7 +56,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + 'NOTE - A header comment\n' + 'This is a comment block', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles a blank line at the end of the file', () => { @@ -67,7 +67,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no blank line at the end of the file', () => { @@ -78,8 +78,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000\n' + 'Test\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0, - }); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('handles no newline after the final text payload', () => { @@ -90,7 +89,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports cues with no settings', () => { @@ -106,7 +105,7 @@ describe('VttTextParser', () => { '2\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports cues with no ID', () => { @@ -120,7 +119,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports comments within cues', () => { @@ -136,7 +135,7 @@ describe('VttTextParser', () => { 'This is a note\n\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports non-integer timecodes', () => { @@ -147,7 +146,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.100 --> 00:00:40.505\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports large timecodes', () => { @@ -158,50 +157,50 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 30:00:00.000\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('requires header', () => { errorHelper(shaka.util.Error.Code.INVALID_TEXT_HEADER, '', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); errorHelper(shaka.util.Error.Code.INVALID_TEXT_HEADER, '00:00:00.000 --> 00:00:00.020\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('rejects invalid time values', () => { errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n0:00.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00:00.20 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00:100.20 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00:00.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00:00:00:00.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n00:61.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); errorHelper(shaka.util.Error.Code.INVALID_TEXT_CUE, 'WEBVTT\n\n61:00.020 --> 0:00.040\nTest', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}, + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}, anyString); }); @@ -226,7 +225,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000 vertical:lr\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports line setting', () => { @@ -258,7 +257,7 @@ describe('VttTextParser', () => { 'Test3\n\n' + '00:00:55.000 --> 00:01:05.000 line:12.3%\n' + 'Test4\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports line setting with optional part', () => { @@ -280,7 +279,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000 line:-1,center\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports position setting', () => { @@ -294,7 +293,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:25.000 --> 00:00:45.000 position:12.3%\n' + 'Test2\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports position setting with optional part', () => { @@ -314,7 +313,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:20.000 --> 00:00:40.000 position:45%,start\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports size setting', () => { @@ -328,7 +327,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:25.000 --> 00:00:45.000 size:12.3%\n' + 'Test2\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports align setting', () => { @@ -339,7 +338,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 align:center\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports multiple settings', () => { @@ -357,7 +356,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 align:center size:56% vertical:lr\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports timestamps with one-digit hour at start time', () => { @@ -375,7 +374,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '0:00:20.000 --> 00:00:40.000 align:center size:56% vertical:lr\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports timestamps with one-digit hour at end time', () => { @@ -393,7 +392,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 0:00:40.000 align:center size:56% vertical:lr\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports stamps with one-digit hours at start & end time', () => { @@ -411,15 +410,15 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '0:00:20.000 --> 0:00:40.000 align:center size:56% vertical:lr\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); - it('uses time offset from periodStart, not segmentStart', () => { + it('uses time offset from vttOffset, not periodStart or segmentStart', () => { verifyHelper( [ { - startTime: 70, - endTime: 80, + startTime: 50, + endTime: 60, payload: 'Test', textAlign: 'center', size: 56, @@ -429,10 +428,9 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '0:00:10.000 --> 0:00:20.000 align:center size:56% vertical:lr\n' + 'Test', - {periodStart: 60, segmentStart: 80, segmentEnd: 100}); + {periodStart: 60, segmentStart: 80, segmentEnd: 100, vttOffset: 40}); }); - it('parses VTTRegions', () => { verifyHelper( [ @@ -460,7 +458,7 @@ describe('VttTextParser', () => { 'viewportanchor=10%,90% scroll=up\n\n' + '0:00:20.000 --> 0:00:40.000 region:reg1\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('ignores and logs invalid settings', () => { @@ -473,7 +471,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 vertical:es\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -482,7 +480,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 vertical:\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -491,7 +489,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 vertical\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -500,7 +498,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 line:-3%\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -509,7 +507,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 line:45%%\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -518,7 +516,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 align:10\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); verifyHelper( [ @@ -527,7 +525,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.000 --> 00:00:40.000 align:foo\n' + 'Test\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); expect(logWarningSpy).toHaveBeenCalledTimes(7); }); @@ -546,7 +544,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000 line:-1\n' + 'Test2', - {periodStart: 0, segmentStart: 25, segmentEnd: 65}); + {periodStart: 0, segmentStart: 25, segmentEnd: 65, vttOffset: 0}); }); it('handles timestamp rollover with X-TIMESTAMP-MAP header', () => { @@ -562,7 +560,7 @@ describe('VttTextParser', () => { 'Test', // Non-null segmentStart takes precedence over X-TIMESTAMP-MAP. // This protects us from rollover in the MPEGTS field. - {periodStart: 0, segmentStart: 95440, segmentEnd: 95550}); + {periodStart: 0, segmentStart: 95440, segmentEnd: 95550, vttOffset: 0}); verifyHelper( [ @@ -575,7 +573,7 @@ describe('VttTextParser', () => { 'X-TIMESTAMP-MAP=MPEGTS:9745408,LOCAL:00:00:00.000\n\n' + '00:00:00.000 --> 00:00:02.000 line:0\n' + 'Test2', - {periodStart: 0, segmentStart: 95550, segmentEnd: 95560}); + {periodStart: 0, segmentStart: 95550, segmentEnd: 95560, vttOffset: 0}); }); it('supports global style blocks', () => { @@ -606,7 +604,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports global style blocks without blank lines', () => { @@ -634,7 +632,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports payload stylized', () => { @@ -775,7 +773,7 @@ describe('VttTextParser', () => { 'Test 7\n\n' + '00:01:30.000 --> 00:01:40.000\n' + 'Test8', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports specific style blocks', () => { @@ -803,7 +801,7 @@ describe('VttTextParser', () => { 'Test\n\n' + '00:00:40.000 --> 00:00:50.000\n' + 'Test2', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports only two digits in the timestamp', () => { @@ -814,7 +812,7 @@ describe('VttTextParser', () => { 'WEBVTT\n\n' + '00:00:20.00 --> 00:00:40.00\n' + 'Test', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports class with default color', () => { @@ -956,7 +954,7 @@ describe('VttTextParser', () => { 'forward slash 1/2 in text\n\n' + '00:01:50.000 --> 00:02:00.000\n' + 'less or more < > in text', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); it('supports default color overriding', () => { @@ -982,7 +980,7 @@ describe('VttTextParser', () => { '::cue(bg_blue) { font-size: 10px; background-color: #FF0 }\n\n' + '00:00:10.000 --> 00:00:20.000\n' + 'Example 1\n\n', - {periodStart: 0, segmentStart: 0, segmentEnd: 0}); + {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0}); }); /**