diff --git a/src/segment/segmentList.js b/src/segment/segmentList.js index a3bb1f87..31556a38 100644 --- a/src/segment/segmentList.js +++ b/src/segment/segmentList.js @@ -50,7 +50,8 @@ const SegmentURLToSegmentObject = (attributes, segmentUrl) => { export const segmentsFromList = (attributes, segmentTimeline) => { const { duration, - segmentUrls = [] + segmentUrls = [], + periodStart } = attributes; // Per spec (5.3.9.2.1) no way to determine segment duration OR @@ -75,10 +76,18 @@ export const segmentsFromList = (attributes, segmentTimeline) => { const segments = segmentTimeInfo.map((segmentTime, index) => { if (segmentUrlMap[index]) { const segment = segmentUrlMap[index]; + // See DASH spec section 5.3.9.2.2 + // - if timescale isn't present on any level, default to 1. + const timescale = attributes.timescale || 1; + // - if presentationTimeOffset isn't present on any level, default to 0 + const presentationTimeOffset = attributes.presentationTimeOffset || 0; segment.timeline = segmentTime.timeline; segment.duration = segmentTime.duration; segment.number = segmentTime.number; + segment.presentationTime = + periodStart + ((segmentTime.time - presentationTimeOffset) / timescale); + return segment; } // Since we're mapping we should get rid of any blank segments (in case diff --git a/src/segment/segmentTemplate.js b/src/segment/segmentTemplate.js index 545b9ad7..274d37d2 100644 --- a/src/segment/segmentTemplate.js +++ b/src/segment/segmentTemplate.js @@ -162,11 +162,10 @@ export const segmentsFromTemplate = (attributes, segmentTimeline) => { const timescale = attributes.timescale || 1; // - if presentationTimeOffset isn't present on any level, default to 0 const presentationTimeOffset = attributes.presentationTimeOffset || 0; - // presentationTimeOffset has already been adjusted by the timescale const presentationTime = // Even if the @t attribute is not specified for the segment, segment.time is // calculated in mpd-parser prior to this, so it's assumed to be available. - attributes.periodStart + (segment.time / timescale) - presentationTimeOffset; + attributes.periodStart + ((segment.time - presentationTimeOffset) / timescale); const map = { uri, @@ -178,10 +177,6 @@ export const segmentsFromTemplate = (attributes, segmentTimeline) => { presentationTime }; - if (attributes.presentationTimeOffset) { - map.presentationTimeOffset = attributes.presentationTimeOffset; - } - return map; }); }; diff --git a/src/toPlaylists.js b/src/toPlaylists.js index c81f61c6..e12732b7 100644 --- a/src/toPlaylists.js +++ b/src/toPlaylists.js @@ -10,12 +10,6 @@ export const generateSegments = ({ attributes, segmentInfo }) => { if (segmentInfo.template) { segmentsFn = segmentsFromTemplate; segmentAttributes = merge(attributes, segmentInfo.template); - - if (segmentInfo.template.presentationTimeOffset) { - segmentAttributes.presentationTimeOffset = - segmentInfo.template.presentationTimeOffset / segmentInfo.template.timescale; - } - } else if (segmentInfo.base) { segmentsFn = segmentsFromBase; segmentAttributes = merge(attributes, segmentInfo.base); diff --git a/test/index.test.js b/test/index.test.js index 4ff2f8c7..f3dabd1a 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -15,6 +15,7 @@ import locationsTemplate from './manifests/locations.mpd'; import multiperiod from './manifests/multiperiod.mpd'; import webmsegments from './manifests/webmsegments.mpd'; import multiperiodSegmentTemplate from './manifests/multiperiod-segment-template.mpd'; +import multiperiodSegmentList from './manifests/multiperiod-segment-list.mpd'; import multiperiodDynamic from './manifests/multiperiod-dynamic.mpd'; import audioOnly from './manifests/audio-only.mpd'; import { @@ -41,6 +42,9 @@ import { import { parsedManifest as multiperiodSegmentTemplateManifest } from './manifests/multiperiod-segment-template.js'; +import { + parsedManifest as multiperiodSegmentListManifest +} from './manifests/multiperiod-segment-list.js'; import { parsedManifest as multiperiodDynamicManifest } from './manifests/multiperiod-dynamic.js'; @@ -101,6 +105,10 @@ QUnit.test('has parse', function(assert) { name: 'multiperiod_segment_template', input: multiperiodSegmentTemplate, expected: multiperiodSegmentTemplateManifest +}, { + name: 'multiperiod_segment_list', + input: multiperiodSegmentList, + expected: multiperiodSegmentListManifest }, { name: 'multiperiod_dynamic', input: multiperiodDynamic, diff --git a/test/manifests/multiperiod-dynamic.js b/test/manifests/multiperiod-dynamic.js index 675cfcf2..9cab1fda 100644 --- a/test/manifests/multiperiod-dynamic.js +++ b/test/manifests/multiperiod-dynamic.js @@ -205,7 +205,6 @@ export const parsedManifest = { }, presentationTime: 19.938462809458052, number: 14, - presentationTimeOffset: 4.85297052154195, discontinuity: true }, { @@ -218,8 +217,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_audio128_2/init3.m4f' }, presentationTime: 21.099460541884355, - number: 15, - presentationTimeOffset: 4.85297052154195 + number: 15 }, { uri: 'https://example.com/default_audio128_2/segment16.m4f', @@ -475,7 +473,6 @@ export const parsedManifest = { }, presentationTime: 19.938462809458052, number: 14, - presentationTimeOffset: 4.85297052154195, discontinuity: true }, { @@ -488,8 +485,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_audio96_2/init3.m4f' }, presentationTime: 21.099460541884355, - number: 15, - presentationTimeOffset: 4.85297052154195 + number: 15 }, { uri: 'https://example.com/default_audio96_2/segment16.m4f', @@ -751,7 +747,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -764,8 +759,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video2000_0_1280x720/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video2000_0_1280x720/segment15.m4f', @@ -777,8 +771,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video2000_0_1280x720/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video2000_0_1280x720/segment16.m4f', @@ -1028,7 +1021,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -1041,8 +1033,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video1200_1_960x540/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video1200_1_960x540/segment15.m4f', @@ -1054,8 +1045,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video1200_1_960x540/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video1200_1_960x540/segment16.m4f', @@ -1305,7 +1295,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -1318,8 +1307,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video900_1_640x360/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video900_1_640x360/segment15.m4f', @@ -1331,8 +1319,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video900_1_640x360/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video900_1_640x360/segment16.m4f', diff --git a/test/manifests/multiperiod-segment-list.js b/test/manifests/multiperiod-segment-list.js new file mode 100644 index 00000000..f60dddde --- /dev/null +++ b/test/manifests/multiperiod-segment-list.js @@ -0,0 +1,87 @@ +export const parsedManifest = { + allowCache: true, + discontinuityStarts: [], + duration: 12, + endList: true, + mediaGroups: { + 'AUDIO': {}, + 'CLOSED-CAPTIONS': {}, + 'SUBTITLES': {}, + 'VIDEO': {} + }, + playlists: [ + { + attributes: { + 'AUDIO': 'audio', + 'BANDWIDTH': 449000, + 'CODECS': 'avc1.420015', + 'NAME': '482', + 'PROGRAM-ID': 1, + 'RESOLUTION': { + height: 270, + width: 482 + }, + 'SUBTITLES': 'subs' + }, + endList: true, + mediaSequence: 1, + targetDuration: 3, + resolvedUri: '', + segments: [ + { + duration: 3, + map: { + uri: '', + resolvedUri: 'https://www.example.com/base' + }, + resolvedUri: 'https://www.example.com/low/segment-1.ts', + timeline: 0, + presentationTime: 0, + uri: 'low/segment-1.ts', + number: 1 + }, + { + duration: 3, + map: { + uri: '', + resolvedUri: 'https://www.example.com/base' + }, + resolvedUri: 'https://www.example.com/low/segment-2.ts', + timeline: 0, + presentationTime: 3, + uri: 'low/segment-2.ts', + number: 2 + }, + { + discontinuity: true, + duration: 3, + map: { + uri: '', + resolvedUri: 'https://www.example.com/base' + }, + resolvedUri: 'https://www.example.com/low/segment-1.ts', + timeline: 1, + presentationTime: 6, + uri: 'low/segment-1.ts', + number: 1 + }, + { + duration: 3, + map: { + uri: '', + resolvedUri: 'https://www.example.com/base' + }, + resolvedUri: 'https://www.example.com/low/segment-2.ts', + timeline: 1, + presentationTime: 9, + uri: 'low/segment-2.ts', + number: 2 + } + ], + timeline: 0, + uri: '' + } + ], + segments: [], + uri: '' +}; diff --git a/test/manifests/multiperiod-segment-list.mpd b/test/manifests/multiperiod-segment-list.mpd new file mode 100644 index 00000000..2994c2ff --- /dev/null +++ b/test/manifests/multiperiod-segment-list.mpd @@ -0,0 +1,33 @@ + + + https://www.example.com/base + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/manifests/multiperiod.js b/test/manifests/multiperiod.js index 162f0ec2..f61feac7 100644 --- a/test/manifests/multiperiod.js +++ b/test/manifests/multiperiod.js @@ -205,7 +205,6 @@ export const parsedManifest = { }, presentationTime: 19.938462809458052, number: 14, - presentationTimeOffset: 4.85297052154195, discontinuity: true }, { @@ -218,8 +217,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_audio128_2/init3.m4f' }, presentationTime: 21.099460541884355, - number: 15, - presentationTimeOffset: 4.85297052154195 + number: 15 }, { uri: 'https://example.com/default_audio128_2/segment16.m4f', @@ -475,7 +473,6 @@ export const parsedManifest = { }, presentationTime: 19.938462809458052, number: 14, - presentationTimeOffset: 4.85297052154195, discontinuity: true }, { @@ -488,8 +485,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_audio96_2/init3.m4f' }, presentationTime: 21.099460541884355, - number: 15, - presentationTimeOffset: 4.85297052154195 + number: 15 }, { uri: 'https://example.com/default_audio96_2/segment16.m4f', @@ -751,7 +747,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -764,8 +759,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video2000_0_1280x720/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video2000_0_1280x720/segment15.m4f', @@ -777,8 +771,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video2000_0_1280x720/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video2000_0_1280x720/segment16.m4f', @@ -1028,7 +1021,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -1041,8 +1033,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video1200_1_960x540/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video1200_1_960x540/segment15.m4f', @@ -1054,8 +1045,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video1200_1_960x540/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video1200_1_960x540/segment16.m4f', @@ -1305,7 +1295,6 @@ export const parsedManifest = { }, presentationTime: 19.953266664333334, number: 13, - presentationTimeOffset: 4.838166666666667, discontinuity: true }, { @@ -1318,8 +1307,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video900_1_640x360/init3.m4f' }, presentationTime: 20.920899997666666, - number: 14, - presentationTimeOffset: 4.838166666666667 + number: 14 }, { uri: 'https://example.com/default_video900_1_640x360/segment15.m4f', @@ -1331,8 +1319,7 @@ export const parsedManifest = { resolvedUri: 'https://example.com/default_video900_1_640x360/init3.m4f' }, presentationTime: 22.856166664333333, - number: 15, - presentationTimeOffset: 4.838166666666667 + number: 15 }, { uri: 'https://example.com/default_video900_1_640x360/segment16.m4f', diff --git a/test/manifests/segmentList.js b/test/manifests/segmentList.js index 8ab1d2ab..85f67552 100644 --- a/test/manifests/segmentList.js +++ b/test/manifests/segmentList.js @@ -36,6 +36,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-1.ts', timeline: 0, + presentationTime: 0, uri: 'low/segment-1.ts', number: 1 }, @@ -47,6 +48,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-2.ts', timeline: 0, + presentationTime: 1, uri: 'low/segment-2.ts', number: 2 }, @@ -58,6 +60,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-3.ts', timeline: 0, + presentationTime: 2, uri: 'low/segment-3.ts', number: 3 }, @@ -69,6 +72,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-4.ts', timeline: 0, + presentationTime: 3, uri: 'low/segment-4.ts', number: 4 }, @@ -80,6 +84,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-5.ts', timeline: 0, + presentationTime: 4, uri: 'low/segment-5.ts', number: 5 }, @@ -91,6 +96,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/low/segment-6.ts', timeline: 0, + presentationTime: 5, uri: 'low/segment-6.ts', number: 6 } @@ -124,6 +130,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-1.ts', timeline: 0, + presentationTime: 0, uri: 'high/segment-1.ts', number: 1 }, @@ -135,6 +142,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-2.ts', timeline: 0, + presentationTime: 60, uri: 'high/segment-2.ts', number: 2 }, @@ -146,6 +154,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-3.ts', timeline: 0, + presentationTime: 120, uri: 'high/segment-3.ts', number: 3 }, @@ -157,6 +166,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-4.ts', timeline: 0, + presentationTime: 180, uri: 'high/segment-4.ts', number: 4 }, @@ -168,6 +178,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-5.ts', timeline: 0, + presentationTime: 240, uri: 'high/segment-5.ts', number: 5 }, @@ -179,6 +190,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-6.ts', timeline: 0, + presentationTime: 300, uri: 'high/segment-6.ts', number: 6 }, @@ -190,6 +202,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-7.ts', timeline: 0, + presentationTime: 360, uri: 'high/segment-7.ts', number: 7 }, @@ -201,6 +214,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-8.ts', timeline: 0, + presentationTime: 420, uri: 'high/segment-8.ts', number: 8 }, @@ -212,6 +226,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-9.ts', timeline: 0, + presentationTime: 480, uri: 'high/segment-9.ts', number: 9 }, @@ -223,6 +238,7 @@ export const parsedManifest = { }, resolvedUri: 'https://www.example.com/high/segment-10.ts', timeline: 0, + presentationTime: 540, uri: 'high/segment-10.ts', number: 10 } diff --git a/test/segment/segmentList.test.js b/test/segment/segmentList.test.js index fdc20791..27345672 100644 --- a/test/segment/segmentList.test.js +++ b/test/segment/segmentList.test.js @@ -21,6 +21,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }], initialization: { sourceURL: 'init.fmp4' }, periodIndex: 0, + periodStart: 0, startNumber: 1, baseUrl: 'http://example.com/', type: 'static' @@ -40,6 +41,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 1000, uri: '1.fmp4', number: 1 }, { @@ -50,6 +52,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 2000, uri: '2.fmp4', number: 2 }, { @@ -60,6 +63,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }, resolvedUri: 'http://example.com/3.fmp4', timeline: 0, + presentationTime: 3000, uri: '3.fmp4', number: 3 }, { @@ -70,6 +74,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }, resolvedUri: 'http://example.com/4.fmp4', timeline: 0, + presentationTime: 4000, uri: '4.fmp4', number: 4 }, { @@ -80,6 +85,7 @@ QUnit.test('uses segmentTimeline to set segments', function(assert) { }, resolvedUri: 'http://example.com/5.fmp4', timeline: 0, + presentationTime: 5000, uri: '5.fmp4', number: 5 }]); @@ -102,6 +108,7 @@ QUnit.test( }], initialization: { sourceURL: 'init.fmp4' }, periodIndex: 0, + periodStart: 0, startNumber: 1, baseUrl: 'http://example.com/', type: 'static' @@ -121,6 +128,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 1000, uri: '1.fmp4', number: 1 }, { @@ -131,6 +139,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 2000, uri: '2.fmp4', number: 2 }]); @@ -154,6 +163,7 @@ QUnit.test( }], initialization: { sourceURL: 'init.fmp4' }, periodIndex: 0, + periodStart: 0, startNumber: 1, baseUrl: 'http://example.com/', type: 'static' @@ -173,6 +183,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 1000, uri: '1.fmp4', number: 1 }, { @@ -183,6 +194,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 2000, uri: '2.fmp4', number: 2 }, { @@ -193,6 +205,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/3.fmp4', timeline: 0, + presentationTime: 3000, uri: '3.fmp4', number: 3 }, { @@ -203,6 +216,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/4.fmp4', timeline: 0, + presentationTime: 4000, uri: '4.fmp4', number: 4 }, { @@ -213,6 +227,7 @@ QUnit.test( }, resolvedUri: 'http://example.com/5.fmp4', timeline: 0, + presentationTime: 5000, uri: '5.fmp4', number: 5 }]); @@ -235,6 +250,7 @@ QUnit.test('uses duration to set segments', function(assert) { initialization: { sourceURL: 'init.fmp4' }, duration: 10, periodIndex: 0, + periodStart: 0, startNumber: 1, sourceDuration: 50, baseUrl: 'http://example.com/', @@ -249,6 +265,7 @@ QUnit.test('uses duration to set segments', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -259,6 +276,7 @@ QUnit.test('uses duration to set segments', function(assert) { }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 10, uri: '2.fmp4', number: 2 }, { @@ -269,6 +287,7 @@ QUnit.test('uses duration to set segments', function(assert) { }, resolvedUri: 'http://example.com/3.fmp4', timeline: 0, + presentationTime: 20, uri: '3.fmp4', number: 3 }, { @@ -279,6 +298,7 @@ QUnit.test('uses duration to set segments', function(assert) { }, resolvedUri: 'http://example.com/4.fmp4', timeline: 0, + presentationTime: 30, uri: '4.fmp4', number: 4 }, { @@ -289,6 +309,7 @@ QUnit.test('uses duration to set segments', function(assert) { }, resolvedUri: 'http://example.com/5.fmp4', timeline: 0, + presentationTime: 40, uri: '5.fmp4', number: 5 }]); @@ -311,6 +332,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { duration: 10, timescale: 2, periodIndex: 0, + periodStart: 0, startNumber: 1, sourceDuration: 25, baseUrl: 'http://example.com/', @@ -325,6 +347,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -335,6 +358,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 5, uri: '2.fmp4', number: 2 }, { @@ -345,6 +369,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { }, resolvedUri: 'http://example.com/3.fmp4', timeline: 0, + presentationTime: 10, uri: '3.fmp4', number: 3 }, { @@ -355,6 +380,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { }, resolvedUri: 'http://example.com/4.fmp4', timeline: 0, + presentationTime: 15, uri: '4.fmp4', number: 4 }, { @@ -365,6 +391,7 @@ QUnit.test('uses timescale to set segment duration', function(assert) { }, resolvedUri: 'http://example.com/5.fmp4', timeline: 0, + presentationTime: 20, uri: '5.fmp4', number: 5 }]); @@ -381,6 +408,7 @@ QUnit.test('timescale sets duration of last segment correctly', function(assert) duration: 10, timescale: 1, periodIndex: 0, + periodStart: 0, startNumber: 1, sourceDuration: 15, baseUrl: 'http://example.com/', @@ -395,6 +423,7 @@ QUnit.test('timescale sets duration of last segment correctly', function(assert) }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -405,6 +434,7 @@ QUnit.test('timescale sets duration of last segment correctly', function(assert) }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 10, uri: '2.fmp4', number: 2 }]); @@ -423,6 +453,7 @@ QUnit.test('segmentUrl translates ranges correctly', function(assert) { duration: 10, timescale: 1, periodIndex: 0, + periodStart: 0, startNumber: 1, sourceDuration: 20, baseUrl: 'http://example.com/', @@ -441,6 +472,7 @@ QUnit.test('segmentUrl translates ranges correctly', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -455,6 +487,7 @@ QUnit.test('segmentUrl translates ranges correctly', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 10, uri: '1.fmp4', number: 2 }]); @@ -525,6 +558,7 @@ QUnit.test('translates ranges in node', function(assert) { duration: 10, timescale: 1, periodIndex: 0, + periodStart: 0, startNumber: 1, sourceDuration: 20, baseUrl: 'http://example.com/', @@ -543,6 +577,7 @@ QUnit.test('translates ranges in node', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -557,6 +592,7 @@ QUnit.test('translates ranges in node', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 10, uri: '1.fmp4', number: 2 }]); diff --git a/test/toPlaylists.test.js b/test/toPlaylists.test.js index b407e392..535f1905 100644 --- a/test/toPlaylists.test.js +++ b/test/toPlaylists.test.js @@ -137,6 +137,7 @@ QUnit.test('segment list', function(assert) { duration: 10, sourceDuration: 11, periodIndex: 0, + periodStart: 0, type: 'static' }, segmentInfo: { @@ -161,6 +162,7 @@ QUnit.test('segment list', function(assert) { media: '2.fmp4' }], periodIndex: 0, + periodStart: 0, type: 'static' }, segments: [{ @@ -171,6 +173,7 @@ QUnit.test('segment list', function(assert) { }, resolvedUri: 'http://example.com/1.fmp4', timeline: 0, + presentationTime: 0, uri: '1.fmp4', number: 1 }, { @@ -181,6 +184,7 @@ QUnit.test('segment list', function(assert) { }, resolvedUri: 'http://example.com/2.fmp4', timeline: 0, + presentationTime: 10, uri: '2.fmp4', number: 2 }] @@ -189,7 +193,7 @@ QUnit.test('segment list', function(assert) { assert.deepEqual(toPlaylists(representations), playlists); }); -QUnit.test('presentationTimeOffset', function(assert) { +QUnit.test('presentationTime accounts for presentationTimeOffset', function(assert) { const representations = [{ attributes: { baseUrl: 'http://example.com/', @@ -206,17 +210,14 @@ QUnit.test('presentationTimeOffset', function(assert) { } }]; - // the presentationTimeOffset output should be the value in the template - // divided by the timescale in the template. - // It should be available on segments const playlists = [{ attributes: { baseUrl: 'http://example.com/', periodIndex: 0, periodStart: 25, + presentationTimeOffset: 100, sourceDuration: 2, duration: 2, - presentationTimeOffset: 25, timescale: 4, type: 'static' }, @@ -224,8 +225,9 @@ QUnit.test('presentationTimeOffset', function(assert) { uri: '', timeline: 0, duration: 2, + // The presentationTime value should be adjusted based on the presentationTimeOffset + // and its timescale. presentationTime: 0, - presentationTimeOffset: 25, resolvedUri: 'http://example.com/', map: { uri: '',