diff --git a/package-lock.json b/package-lock.json index d6c634c9e..0a5f06084 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1793,6 +1793,28 @@ "video.js": "^7 || ^8" }, "dependencies": { + "m3u8-parser": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-6.2.0.tgz", + "integrity": "sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==", + "requires": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "global": "^4.4.0" + }, + "dependencies": { + "@videojs/vhs-utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", + "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", + "requires": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0", + "url-toolkit": "^2.2.1" + } + } + } + }, "mux.js": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-6.2.0.tgz", @@ -6277,9 +6299,9 @@ } }, "m3u8-parser": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-6.2.0.tgz", - "integrity": "sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.0.0.tgz", + "integrity": "sha512-DiJ9XBgCzEWBZBccRaiMXHY6hJvaS+Znm+yacnyhTvNVnXeFl57QqLHJnXLi7QzKxOZzHzHf5sBvLrY2U2IFsg==", "requires": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "^3.0.5", @@ -9243,6 +9265,28 @@ "videojs-vtt.js": "0.15.4" }, "dependencies": { + "m3u8-parser": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-6.2.0.tgz", + "integrity": "sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==", + "requires": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "global": "^4.4.0" + }, + "dependencies": { + "@videojs/vhs-utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", + "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", + "requires": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0", + "url-toolkit": "^2.2.1" + } + } + } + }, "videojs-contrib-quality-levels": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-3.0.0.tgz", diff --git a/package.json b/package.json index d6e154db0..bef24342b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@videojs/vhs-utils": "4.0.0", "aes-decrypter": "4.0.1", "global": "^4.4.0", - "m3u8-parser": "^6.2.0", + "m3u8-parser": "^7.0.0", "mpd-parser": "^1.1.1", "mux.js": "6.3.0", "video.js": "^7 || ^8" diff --git a/src/segment-loader.js b/src/segment-loader.js index 564ee0dd8..151b6cd7e 100644 --- a/src/segment-loader.js +++ b/src/segment-loader.js @@ -3180,8 +3180,7 @@ export default class SegmentLoader extends videojs.EventTarget { const Cue = window.WebKitDataCue || window.VTTCue; const value = { custom: segment.custom, - dateTimeObject: segment.dateTimeObject, - dateTimeString: segment.dateTimeString, + programDateTime: segment.programDateTime, bandwidth: segmentInfo.playlist.attributes.BANDWIDTH, resolution: segmentInfo.playlist.attributes.RESOLUTION, codecs: segmentInfo.playlist.attributes.CODECS, diff --git a/src/sync-controller.js b/src/sync-controller.js index b280d75bd..3b623f2f6 100644 --- a/src/sync-controller.js +++ b/src/sync-controller.js @@ -53,11 +53,11 @@ export const syncPointStrategies = [ const datetimeMapping = syncController.timelineToDatetimeMappings[segment.timeline]; - if (!datetimeMapping || !segment.dateTimeObject) { + if (!datetimeMapping || !segment.programDateTime) { continue; } - const segmentTime = segment.dateTimeObject.getTime() / 1000; + const segmentTime = segment.programDateTime / 1000; let start = segmentTime + datetimeMapping; // take part duration into account. @@ -408,9 +408,9 @@ export default class SyncController extends videojs.EventTarget { if (playlist.segments && playlist.segments.length && - playlist.segments[0].dateTimeObject) { + playlist.segments[0].programDateTime) { const firstSegment = playlist.segments[0]; - const playlistTimestamp = firstSegment.dateTimeObject.getTime() / 1000; + const playlistTimestamp = firstSegment.programDateTime / 1000; this.timelineToDatetimeMappings[firstSegment.timeline] = -playlistTimestamp; } @@ -449,10 +449,10 @@ export default class SyncController extends videojs.EventTarget { } } - const dateTime = segment.dateTimeObject; + const dateTime = segment.programDateTime; if (segment.discontinuity && shouldSaveTimelineMapping && dateTime) { - this.timelineToDatetimeMappings[segment.timeline] = -(dateTime.getTime() / 1000); + this.timelineToDatetimeMappings[segment.timeline] = -(dateTime / 1000); } } diff --git a/src/util/time.js b/src/util/time.js index 3edf48f4f..1b16f88c0 100644 --- a/src/util/time.js +++ b/src/util/time.js @@ -26,7 +26,7 @@ const SEGMENT_END_FUDGE_PERCENT = 0.25; * @return {Date} program time */ export const playerTimeToProgramTime = (playerTime, segment) => { - if (!segment.dateTimeObject) { + if (!segment.programDateTime) { // Can't convert without an "anchor point" for the program time (i.e., a time that can // be used to map the start of a segment with a real world time). return null; @@ -39,7 +39,7 @@ export const playerTimeToProgramTime = (playerTime, segment) => { const startOfSegment = transmuxedStart + transmuxerPrependedSeconds; const offsetFromSegmentStart = playerTime - startOfSegment; - return new Date(segment.dateTimeObject.getTime() + offsetFromSegmentStart * 1000); + return new Date(segment.programDateTime + offsetFromSegmentStart * 1000); }; export const originalSegmentVideoDuration = (videoTimingInfo) => { @@ -74,7 +74,7 @@ export const findSegmentForProgramTime = (programTime, playlist) => { let segment = playlist.segments[0]; - if (dateTimeObject < segment.dateTimeObject) { + if (dateTimeObject < segment.programDateTime) { // Requested time is before stream start. return null; } @@ -82,7 +82,7 @@ export const findSegmentForProgramTime = (programTime, playlist) => { for (let i = 0; i < playlist.segments.length - 1; i++) { segment = playlist.segments[i]; - const nextSegmentStart = playlist.segments[i + 1].dateTimeObject; + const nextSegmentStart = playlist.segments[i + 1].programDateTime; if (dateTimeObject < nextSegmentStart) { break; @@ -90,12 +90,12 @@ export const findSegmentForProgramTime = (programTime, playlist) => { } const lastSegment = playlist.segments[playlist.segments.length - 1]; - const lastSegmentStart = lastSegment.dateTimeObject; + const lastSegmentStart = lastSegment.programDateTime; const lastSegmentDuration = lastSegment.videoTimingInfo ? originalSegmentVideoDuration(lastSegment.videoTimingInfo) : lastSegment.duration + lastSegment.duration * SEGMENT_END_FUDGE_PERCENT; const lastSegmentEnd = - new Date(lastSegmentStart.getTime() + lastSegmentDuration * 1000); + new Date(lastSegmentStart + lastSegmentDuration * 1000); if (dateTimeObject > lastSegmentEnd) { // Beyond the end of the stream, or our best guess of the end of the stream. @@ -230,7 +230,7 @@ export const verifyProgramDateTimeTags = (playlist) => { for (let i = 0; i < playlist.segments.length; i++) { const segment = playlist.segments[i]; - if (!segment.dateTimeObject) { + if (!segment.programDateTime) { return false; } } @@ -355,7 +355,7 @@ export const seekToProgramTime = ({ const segment = matchedSegment.segment; const mediaOffset = getOffsetFromTimestamp( - segment.dateTimeObject, + segment.programDateTime, programTime ); diff --git a/test/playlist-loader.test.js b/test/playlist-loader.test.js index c642db048..5c268ecef 100644 --- a/test/playlist-loader.test.js +++ b/test/playlist-loader.test.js @@ -1052,7 +1052,7 @@ QUnit.module('Playlist Loader', function(hooks) { const segment = loader.main.playlists[0].segments[0]; assert.strictEqual(segment.custom.test, '#PARSER:parsed', 'parsed custom tag'); - assert.ok(segment.dateTimeObject, 'converted and parsed custom time'); + assert.ok(segment.programDateTime, 'converted and parsed custom time'); delete this.fakeVhs.options_; }); diff --git a/test/segment-loader.test.js b/test/segment-loader.test.js index 5a75b407d..357a44b06 100644 --- a/test/segment-loader.test.js +++ b/test/segment-loader.test.js @@ -4560,26 +4560,26 @@ QUnit.module('SegmentLoader', function(hooks) { const segmentDurationMs = targetDuration * 1000; - const playlist1Start = new Date('2021-01-01T00:00:00.000-05:00'); + const playlist1Start = new Date('2021-01-01T00:00:00.000-05:00').getTime(); - playlist1.segments[0].dateTimeObject = playlist1Start; - playlist1.segments[1].dateTimeObject = new Date(playlist1Start.getTime() + segmentDurationMs); + playlist1.segments[0].programDateTime = playlist1Start; + playlist1.segments[1].programDateTime = new Date(playlist1Start + segmentDurationMs).getTime(); // jump of 0.5 seconds after disco (0.5 seconds of missing real world time, e.g., // an encoder went down briefly), should have a PDT mapping difference of -3.5 // seconds from first mapping - playlist1.segments[2].dateTimeObject = new Date(playlist1.segments[1].dateTimeObject.getTime() + segmentDurationMs + 500); - playlist1.segments[3].dateTimeObject = new Date(playlist1.segments[2].dateTimeObject.getTime() + segmentDurationMs); + playlist1.segments[2].programDateTime = new Date(playlist1.segments[1].programDateTime + segmentDurationMs + 500).getTime(); + playlist1.segments[3].programDateTime = new Date(playlist1.segments[2].programDateTime + segmentDurationMs).getTime(); // offset by 0.25 seconds from playlist1 const playlist2Start = new Date('2021-01-01T00:00:00.250-05:00'); - playlist2.segments[0].dateTimeObject = playlist2Start; - playlist2.segments[1].dateTimeObject = new Date(playlist2Start.getTime() + segmentDurationMs); + playlist2.segments[0].programDateTime = playlist2Start.getTime(); + playlist2.segments[1].programDateTime = new Date(playlist2Start + segmentDurationMs).getTime(); // jump of 0.5 seconds after disco (0.5 seconds of missing real world time, e.g., // an encoder went down briefly), should have a PDT mapping difference of -3.5 // seconds from first mapping - playlist2.segments[2].dateTimeObject = new Date(playlist2.segments[1].dateTimeObject.getTime() + segmentDurationMs + 500); - playlist2.segments[3].dateTimeObject = new Date(playlist2.segments[2].dateTimeObject.getTime() + segmentDurationMs); + playlist2.segments[2].programDateTime = new Date(playlist2.segments[1].programDateTime + segmentDurationMs + 500).getTime(); + playlist2.segments[3].programDateTime = new Date(playlist2.segments[2].programDateTime + segmentDurationMs).getTime(); const { mediaSource_: mediaSource, @@ -4680,11 +4680,11 @@ QUnit.module('SegmentLoader', function(hooks) { const segment3Start = new Date(segment2Start.getTime() + segmentDurationMs + 500); [playlist1, playlist2].forEach((playlist) => { - playlist.dateTimeObject = segment0Start; - playlist.segments[0].dateTimeObject = segment0Start; - playlist.segments[1].dateTimeObject = segment1Start; - playlist.segments[2].dateTimeObject = segment2Start; - playlist.segments[3].dateTimeObject = segment3Start; + playlist.programDateTime = segment0Start; + playlist.segments[0].programDateTime = segment0Start; + playlist.segments[1].programDateTime = segment1Start; + playlist.segments[2].programDateTime = segment2Start; + playlist.segments[3].programDateTime = segment3Start; }); const { diff --git a/test/sync-controller.test.js b/test/sync-controller.test.js index b7a99c183..a0b3b24ac 100644 --- a/test/sync-controller.test.js +++ b/test/sync-controller.test.js @@ -45,7 +45,7 @@ QUnit.test('returns correct sync point for ProgramDateTime strategy', function(a assert.equal(syncPoint, null, 'no syncpoint when no date time to display time mapping'); - playlist.segments[0].dateTimeObject = datetime; + playlist.segments[0].programDateTime = datetime.getTime(); this.syncController.setDateTimeMappingForStart(playlist); @@ -55,7 +55,7 @@ QUnit.test('returns correct sync point for ProgramDateTime strategy', function(a assert.equal(syncPoint, null, 'no syncpoint when datetimeObject not set on playlist'); - newPlaylist.segments[0].dateTimeObject = new Date(2012, 11, 12, 12, 12, 22); + newPlaylist.segments[0].programDateTime = new Date(2012, 11, 12, 12, 12, 22).getTime(); syncPoint = strategy.run(this.syncController, newPlaylist, duration, timeline); @@ -78,7 +78,7 @@ QUnit.test('ProgramDateTime strategy finds nearest segment for sync', function(a assert.equal(syncPoint, null, 'no syncpoint when no date time to display time mapping'); playlist.segments.forEach((segment, index) => { - segment.dateTimeObject = new Date(2012, 11, 12, 12, 12, 12 + (index * 10)); + segment.programDateTime = new Date(2012, 11, 12, 12, 12, 12 + (index * 10)).getTime(); }); this.syncController.setDateTimeMappingForStart(playlist); @@ -90,7 +90,7 @@ QUnit.test('ProgramDateTime strategy finds nearest segment for sync', function(a assert.equal(syncPoint, null, 'no syncpoint when datetimeObject not set on playlist'); newPlaylist.segments.forEach((segment, index) => { - segment.dateTimeObject = new Date(2012, 11, 12, 12, 12, 22 + (index * 10)); + segment.programDateTime = new Date(2012, 11, 12, 12, 12, 22 + (index * 10)).getTime(); }); syncPoint = strategy.run(this.syncController, newPlaylist, duration, timeline, 170); @@ -115,7 +115,7 @@ QUnit.test( function(assert) { const playlist = playlistWithDuration(40); - playlist.segments[1].dateTimeObject = new Date(2012, 11, 12, 12, 12, 12); + playlist.segments[1].programDateTime = new Date(2012, 11, 12, 12, 12, 12).getTime(); this.syncController.setDateTimeMappingForStart(playlist); @@ -125,7 +125,7 @@ QUnit.test( 'did not set datetime mapping' ); - playlist.segments[0].dateTimeObject = new Date(2012, 11, 12, 12, 12, 2); + playlist.segments[0].programDateTime = new Date(2012, 11, 12, 12, 12, 2).getTime(); this.syncController.setDateTimeMappingForStart(playlist); @@ -140,12 +140,12 @@ QUnit.test( QUnit.test('uses separate date time to display time mapping for each timeline', function(assert) { const playlist = playlistWithDuration(40, { discontinuityStarts: [1, 3] }); - playlist.segments[0].dateTimeObject = new Date(2020, 1, 1, 1, 1, 1); + playlist.segments[0].programDateTime = new Date(2020, 1, 1, 1, 1, 1).getTime(); // 20 seconds later (10 more than default) - playlist.segments[1].dateTimeObject = new Date(2020, 1, 1, 1, 1, 21); - playlist.segments[2].dateTimeObject = new Date(2020, 1, 1, 1, 1, 31); + playlist.segments[1].programDateTime = new Date(2020, 1, 1, 1, 1, 21).getTime(); + playlist.segments[2].programDateTime = new Date(2020, 1, 1, 1, 1, 31).getTime(); // 30 seconds later (20 more than default) - playlist.segments[3].dateTimeObject = new Date(2020, 1, 1, 1, 2, 1); + playlist.segments[3].programDateTime = new Date(2020, 1, 1, 1, 2, 1).getTime(); // after this call, the initial playlist mapping will be provided this.syncController.setDateTimeMappingForStart(playlist); @@ -165,7 +165,7 @@ QUnit.test('uses separate date time to display time mapping for each timeline', assert.deepEqual( this.syncController.timelineToDatetimeMappings, { - 0: -(playlist.segments[0].dateTimeObject.getTime() / 1000) + 0: -(playlist.segments[0].programDateTime / 1000) }, 'has correct mapping for timeline 0' ); @@ -183,8 +183,8 @@ QUnit.test('uses separate date time to display time mapping for each timeline', assert.deepEqual( this.syncController.timelineToDatetimeMappings, { - 0: -(playlist.segments[0].dateTimeObject.getTime() / 1000), - 1: -(playlist.segments[1].dateTimeObject.getTime() / 1000) + 0: -(playlist.segments[0].programDateTime / 1000), + 1: -(playlist.segments[1].programDateTime / 1000) }, 'has correct mapping for timelines 0 and 1' ); @@ -202,8 +202,8 @@ QUnit.test('uses separate date time to display time mapping for each timeline', assert.deepEqual( this.syncController.timelineToDatetimeMappings, { - 0: -(playlist.segments[0].dateTimeObject.getTime() / 1000), - 1: -(playlist.segments[1].dateTimeObject.getTime() / 1000) + 0: -(playlist.segments[0].programDateTime / 1000), + 1: -(playlist.segments[1].programDateTime / 1000) }, 'does not add a new timeline mapping when no disco' ); @@ -221,9 +221,9 @@ QUnit.test('uses separate date time to display time mapping for each timeline', assert.deepEqual( this.syncController.timelineToDatetimeMappings, { - 0: -(playlist.segments[0].dateTimeObject.getTime() / 1000), - 1: -(playlist.segments[1].dateTimeObject.getTime() / 1000), - 2: -(playlist.segments[3].dateTimeObject.getTime() / 1000) + 0: -(playlist.segments[0].programDateTime / 1000), + 1: -(playlist.segments[1].programDateTime / 1000), + 2: -(playlist.segments[3].programDateTime / 1000) }, 'has correct mappings for timelines 0, 1, and 2' ); @@ -241,7 +241,7 @@ QUnit.test('ProgramDateTime strategy finds nearest llhls sync point', function(a assert.equal(syncPoint, null, 'no syncpoint when no date time to display time mapping'); playlist.segments.forEach((segment, index) => { - segment.dateTimeObject = new Date(2012, 11, 12, 12, 12, 12 + (index * 10)); + segment.programDateTime = new Date(2012, 11, 12, 12, 12, 12 + (index * 10)).getTime(); }); this.syncController.setDateTimeMappingForStart(playlist); diff --git a/test/util/time.test.js b/test/util/time.test.js index 1ab5f5680..25759e65b 100644 --- a/test/util/time.test.js +++ b/test/util/time.test.js @@ -24,7 +24,7 @@ QUnit.test( segments: [{ start: 0, end: 1, - dateTimeObject: new Date() + programDateTime: new Date().getTime() }] }; const badPlaylist = { @@ -32,7 +32,7 @@ QUnit.test( { start: 0, end: 1, - dateTimeObject: new Date() + programDateTime: new Date().getTime() }, { start: 1, @@ -41,7 +41,7 @@ QUnit.test( { start: 2, end: 3, - dateTimeObject: new Date() + programDateTime: new Date().getTime() } ] }; @@ -280,7 +280,7 @@ QUnit.test( transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:39:57.158Z') + programDateTime: new Date('2018-11-10T19:39:57.158Z').getTime() }], targetDuration: 1 }), @@ -295,7 +295,7 @@ QUnit.test( function(assert) { const segment = { duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }; assert.deepEqual( @@ -317,11 +317,11 @@ QUnit.test( function(assert) { const segment1 = { duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }; const segment2 = { duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:58.158Z') + programDateTime: new Date('2018-11-10T19:38:58.158Z').getTime() }; assert.deepEqual( @@ -348,7 +348,7 @@ QUnit.test( transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }; assert.deepEqual( @@ -375,7 +375,7 @@ QUnit.test('findSegmentForProgramTime returns accurate last segment', function(a transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }, { videoTimingInfo: { transmuxerPrependedSeconds: 0, @@ -383,7 +383,7 @@ QUnit.test('findSegmentForProgramTime returns accurate last segment', function(a transmuxedPresentationEnd: 2 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:58.158Z') + programDateTime: new Date('2018-11-10T19:38:58.158Z').getTime() }] }; @@ -410,7 +410,7 @@ QUnit.test( transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }, { videoTimingInfo: { transmuxerPrependedSeconds: 0, @@ -418,7 +418,7 @@ QUnit.test( transmuxedPresentationEnd: 2 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:58.158Z') + programDateTime: new Date('2018-11-10T19:38:58.158Z').getTime() }] }; @@ -440,17 +440,17 @@ QUnit.test('findSegmentForProgramTime returns estimated last segment', function( transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }, { duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:58.158Z') + programDateTime: new Date('2018-11-10T19:38:58.158Z').getTime() }] }; // 25% of last segment duration + last segment duration on top of last segment start // to test allowed fudge const programTime = - new Date(playlist.segments[1].dateTimeObject.getTime() + 1.25 * 1000); + new Date(playlist.segments[1].programDateTime + 1.25 * 1000); assert.deepEqual( findSegmentForProgramTime(programTime.toISOString(), playlist), @@ -476,16 +476,16 @@ QUnit.test( transmuxedPresentationEnd: 1 }, duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:57.158Z') + programDateTime: new Date('2018-11-10T19:38:57.158Z').getTime() }, { duration: 1, - dateTimeObject: new Date('2018-11-10T19:38:58.158Z') + programDateTime: new Date('2018-11-10T19:38:58.158Z').getTime() }] }; // just over allowed fudge of 25% const programTime = - new Date(playlist.segments[1].dateTimeObject.getTime() + 1.26 * 1000); + new Date(playlist.segments[1].programDateTime + 1.26 * 1000); assert.equal( findSegmentForProgramTime(programTime.toISOString(), playlist), @@ -549,11 +549,11 @@ QUnit.test( ' program date time', function(assert) { // UTC: Sun, 11 Nov 2018 00:00:00 GMT - const dateTimeObject = new Date(1541894400000); + const programDateTime = new Date(1541894400000).getTime(); assert.deepEqual( playerTimeToProgramTime(7, { - dateTimeObject, + programDateTime, videoTimingInfo: { transmuxedPresentationEnd: 11, transmuxedPresentationStart: 4, @@ -561,7 +561,7 @@ QUnit.test( } }).toISOString(), // 7 seconds into the stream, segment starts at 4 seconds - (new Date(dateTimeObject.getTime() + 3 * 1000)).toISOString(), + (new Date(programDateTime + 3 * 1000)).toISOString(), 'returns stream time based on segment program date time' ); } @@ -569,11 +569,11 @@ QUnit.test( QUnit.test('playerTimeToProgramTime accounts for prepended content', function(assert) { // UTC: Sun, 11 Nov 2018 00:00:00 GMT - const dateTimeObject = new Date(1541894400000); + const programDateTime = new Date(1541894400000).getTime(); assert.deepEqual( playerTimeToProgramTime(7, { - dateTimeObject, + programDateTime, videoTimingInfo: { transmuxedPresentationEnd: 11, transmuxedPresentationStart: 4, @@ -582,7 +582,7 @@ QUnit.test('playerTimeToProgramTime accounts for prepended content', function(as }).toISOString(), // 7 seconds into the stream, segment starts at 4 seconds, but after accounting for // prepended content of 2 seconds, the original segment starts at 6 seconds - (new Date(dateTimeObject.getTime() + 1 * 1000)).toISOString(), + (new Date(programDateTime + 1 * 1000)).toISOString(), 'returns stream time based on segment program date time' ); }); @@ -609,8 +609,7 @@ QUnit.module('Time: getProgramTime', { segments: [{ duration: 4, // UTC: Sun, 11 Nov 2018 00:00:00 GMT - dateTimeObject: new Date(1541894400000), - dateTimeString: '2018-11-11T00:00:00.000Z', + programDateTime: new Date(1541894400000).getTime(), start: 5, videoTimingInfo: { transmuxerPrependedSeconds: 0, @@ -696,7 +695,7 @@ QUnit.test( // offset into start of stream by time passed in const expectedDateTime = - new Date(this.playlist.segments[0].dateTimeObject.getTime() + 6 * 1000); + new Date(this.playlist.segments[0].programDateTime + 6 * 1000); assert.equal( programTime.programDateTime, @@ -719,14 +718,12 @@ QUnit.test( { duration: 1, // UTC: Sun, 11 Nov 2018 00:00:00 GMT - dateTimeObject: new Date(1541894400000), - dateTimeString: '2018-11-11T00:00:00.000Z' + programDateTime: new Date(1541894400000).getTime() }, { duration: 2, // UTC: Sun, 11 Nov 2018 00:00:00 GMT - dateTimeObject: new Date(1541894400000), - dateTimeString: '2018-11-11T00:00:00.000Z' + programDateTime: new Date(1541894400000).getTime() } ] }; @@ -802,7 +799,7 @@ QUnit.test('returns programDateTime parsed from media segment tags', function(as assert.equal(err, null, 'no error'); assert.equal( programTime.programDateTime, - playlist.segments[0].dateTimeString, + new Date(playlist.segments[0].programDateTime).toISOString(), 'uses programDateTime found in media segments' ); done(); @@ -993,8 +990,7 @@ QUnit.test('returns error if time does not exist in live stream', function(asser programTime: '2018-10-12T22:33:52.037+00:00', playlist: { segments: [{ - dateTimeString: '2018-10-12T22:33:49.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:49.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:49.037+00:00').getTime(), duration: 1, start: 0 }], @@ -1041,8 +1037,7 @@ QUnit.test('vod: seeks and returns player time seeked to if buffered', function( playlist: { segments: [ { - dateTimeString: '2018-10-12T22:33:49.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:49.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:49.037+00:00').getTime(), duration: 1, start: 0, videoTimingInfo: { @@ -1051,8 +1046,7 @@ QUnit.test('vod: seeks and returns player time seeked to if buffered', function( transmuxedPresentationEnd: 1 } }, { - dateTimeString: '2018-10-12T22:33:50.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:50.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:50.037+00:00').getTime(), duration: 1, start: 1, videoTimingInfo: { @@ -1107,8 +1101,7 @@ QUnit.test('vod: does not account for prepended content duration', function(asse playlist: { segments: [ { - dateTimeString: '2018-10-12T22:33:48.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:48.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:48.037+00:00').getTime(), duration: 2, start: 0, videoTimingInfo: { @@ -1117,8 +1110,7 @@ QUnit.test('vod: does not account for prepended content duration', function(asse transmuxedPresentationEnd: 2 } }, { - dateTimeString: '2018-10-12T22:33:50.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:50.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:50.037+00:00').getTime(), duration: 2, start: 2, videoTimingInfo: { @@ -1173,8 +1165,7 @@ QUnit.test('live: seeks and returns player time seeked to if buffered', function playlist: { segments: [ { - dateTimeString: '2018-10-12T22:33:49.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:49.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:49.037+00:00').getTime(), duration: 1, start: 0, videoTimingInfo: { @@ -1183,8 +1174,7 @@ QUnit.test('live: seeks and returns player time seeked to if buffered', function transmuxedPresentationEnd: 1 } }, { - dateTimeString: '2018-10-12T22:33:50.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:50.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:50.037+00:00').getTime(), duration: 1, start: 1, videoTimingInfo: { @@ -1238,8 +1228,7 @@ QUnit.test('setting pauseAfterSeek to false seeks without pausing', function(ass playlist: { segments: [ { - dateTimeString: '2018-10-12T22:33:49.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:49.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:49.037+00:00').getTime(), duration: 1, start: 0, videoTimingInfo: { @@ -1248,8 +1237,7 @@ QUnit.test('setting pauseAfterSeek to false seeks without pausing', function(ass transmuxedPresentationEnd: 1 } }, { - dateTimeString: '2018-10-12T22:33:50.037+00:00', - dateTimeObject: new Date('2018-10-12T22:33:50.037+00:00'), + programDateTime: new Date('2018-10-12T22:33:50.037+00:00').getTime(), duration: 1, start: 1, videoTimingInfo: {