From 9220c1f87d3ab1b23d0008fc8b0164d2ad26f35f Mon Sep 17 00:00:00 2001 From: Theodore Abshire Date: Mon, 1 Nov 2021 20:34:49 -0700 Subject: [PATCH] fix(hls): Made HLS notify segments after fit Previously, the HLS parser would notify the presentation timeline of the segments in the manifest before fitting the segments. The HLS parser will also sometimes remove segments from the end of a VOD asset if they do not fit within the playlist duration. This could sometimes cause the presentation timeline and MediaSource to have different opinions on how long the VOD asset was, which could lead to the seek bar looking like the presentation stopped before the end. Closes #3733 Change-Id: I67fdc28a3f6eee158c9906359491fe6bb418e730 --- lib/hls/hls_parser.js | 33 ++++++++++++++++++++++++--------- test/hls/hls_parser_unit.js | 2 ++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index 54a26174cf..cf5009821c 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -534,6 +534,30 @@ shaka.hls.HlsParser = class { } } + // Now that the content has been fit, notify segments. + this.segmentsToNotifyByStream_ = []; + const streamsToNotify = []; + for (const variant of variants) { + for (const stream of [variant.video, variant.audio]) { + if (stream) { + streamsToNotify.push(stream); + } + } + } + await Promise.all(streamsToNotify.map(async (stream) => { + await stream.createSegmentIndex(); + })); + for (const stream of streamsToNotify) { + this.segmentsToNotifyByStream_.push(stream.segmentIndex.references); + } + this.notifySegments_(); + + // This asserts that the live edge is being calculated from segment times. + // For VOD and event streams, this check should still pass. + goog.asserts.assert( + !this.presentationTimeline_.usingPresentationStartTime(), + 'We should not be using the presentation start time in HLS!'); + this.manifest_ = { presentationTimeline: this.presentationTimeline_, variants, @@ -1618,12 +1642,6 @@ shaka.hls.HlsParser = class { } this.notifySegments_(); - - // This asserts that the live edge is being calculated from segment times. - // For VOD and event streams, this check should still pass. - goog.asserts.assert( - !this.presentationTimeline_.usingPresentationStartTime(), - 'We should not be using the presentation start time in HLS!'); } /** @@ -2014,9 +2032,6 @@ shaka.hls.HlsParser = class { } } - this.segmentsToNotifyByStream_.push(references); - this.notifySegments_(); - return references; } diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index 7ee5d21f12..67c000c123 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -1309,6 +1309,8 @@ describe('HlsParser', () => { // stream. const timeline = actual.presentationTimeline; expect(timeline.getDuration()).toBe(10); + expect(timeline.getSeekRangeStart()).toBe(0); + expect(timeline.getSeekRangeEnd()).toBe(10); expect(actual.textStreams.length).toBe(1); expect(actual.variants.length).toBe(1);