From d8aa24f41d79c9efb58014c3069c5183738f26d4 Mon Sep 17 00:00:00 2001 From: Dave Nicholas Date: Thu, 16 Nov 2023 08:48:12 +0000 Subject: [PATCH] fix(DASH): Segments being fetched out of the range of the timeline (#5889) Fixes: https://github.com/shaka-project/shaka-player/issues/3952 --- .gitignore | 1 + lib/dash/mpd_utils.js | 6 ++++-- lib/dash/segment_template.js | 2 +- lib/media/presentation_timeline.js | 5 ++++- test/dash/mpd_utils_unit.js | 3 ++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e67fa224bc..cf5683caa1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ coverage/ .DS_Store .vscode .babel-cache +.idea/ diff --git a/lib/dash/mpd_utils.js b/lib/dash/mpd_utils.js index 252786a272..4a31dc8c46 100644 --- a/lib/dash/mpd_utils.js +++ b/lib/dash/mpd_utils.js @@ -128,11 +128,12 @@ shaka.dash.MpdUtils = class { * @param {number} unscaledPresentationTimeOffset * @param {number} periodDuration The Period's duration in seconds. * Infinity indicates that the Period continues indefinitely. + * @param {number} startNumber * @return {!Array.} */ static createTimeline( segmentTimeline, timescale, unscaledPresentationTimeOffset, - periodDuration) { + periodDuration, startNumber) { goog.asserts.assert( timescale > 0 && timescale < Infinity, 'timescale must be a positive, finite integer'); @@ -243,6 +244,7 @@ shaka.dash.MpdUtils = class { end: endTime / timescale, unscaledStart: startTime, partialSegments: partialSegments, + segmentPosition: timeline.length + startNumber, }; timeline.push(item); @@ -306,7 +308,7 @@ shaka.dash.MpdUtils = class { if (timelineNode) { timeline = MpdUtils.createTimeline( timelineNode, timescale, unscaledPresentationTimeOffset, - context.periodInfo.duration || Infinity); + context.periodInfo.duration || Infinity, startNumber); } const scaledPresentationTimeOffset = diff --git a/lib/dash/segment_template.js b/lib/dash/segment_template.js index b43f6a7e17..b50ae26225 100644 --- a/lib/dash/segment_template.js +++ b/lib/dash/segment_template.js @@ -820,7 +820,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex { if (!ref) { const mediaTemplate = this.templateInfo_.mediaTemplate; const range = this.templateInfo_.timeline[correctedPosition]; - const segmentReplacement = position + this.templateInfo_.startNumber; + const segmentReplacement = range.segmentPosition; const timeReplacement = this.templateInfo_ .unscaledPresentationTimeOffset + range.unscaledStart; const timestampOffset = this.periodStart_ - diff --git a/lib/media/presentation_timeline.js b/lib/media/presentation_timeline.js index df1695a36d..8b8d0221c4 100644 --- a/lib/media/presentation_timeline.js +++ b/lib/media/presentation_timeline.js @@ -620,7 +620,8 @@ shaka.media.PresentationTimeline = class { * start: number, * unscaledStart: number, * end: number, - * partialSegments: number + * partialSegments: number, + * segmentPosition: number * }} * * @description @@ -634,6 +635,8 @@ shaka.media.PresentationTimeline = class { * The end time (exclusive) of the range. * @property {number} partialSegments * The number of partial segments + * @property {number} segmentPosition + * The segment position of the timeline entry as it appears in the manifest * * @export */ diff --git a/test/dash/mpd_utils_unit.js b/test/dash/mpd_utils_unit.js index dfedb3bb4e..9ce1ec892d 100644 --- a/test/dash/mpd_utils_unit.js +++ b/test/dash/mpd_utils_unit.js @@ -459,7 +459,8 @@ describe('MpdUtils', () => { console.assert(segmentTimeline); const timeline = MpdUtils.createTimeline( - segmentTimeline, timescale, presentationTimeOffset, periodDuration); + segmentTimeline, timescale, presentationTimeOffset, + periodDuration, 0); expect(timeline).toEqual( expected.map((c) => jasmine.objectContaining(c))); }