Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(HLS): Fix HLS seekRange for live streams #5263

Merged
merged 1 commit into from
Jun 7, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ shaka.hls.HlsParser = class {
mediaSequenceNumber);
stream.segmentIndex.evict(playlistStartTime);
}
const oldSegment = segments[0];
goog.asserts.assert(oldSegment, 'Should have segments!');

streamInfo.minTimestamp = oldSegment.startTime;

const newestSegment = segments[segments.length - 1];
goog.asserts.assert(newestSegment, 'Should have segments!');

Expand Down Expand Up @@ -578,6 +583,9 @@ shaka.hls.HlsParser = class {
* @private
*/
offsetStreamInfo_(streamInfo, offset) {
// Adjust our accounting of the minimum timestamp.
streamInfo.minTimestamp += offset;

// Adjust our accounting of the maximum timestamp.
streamInfo.maxTimestamp += offset;
goog.asserts.assert(streamInfo.maxTimestamp >= 0,
Expand Down Expand Up @@ -1068,7 +1076,7 @@ shaka.hls.HlsParser = class {
const PresentationType = shaka.hls.HlsParser.PresentationType_;

if (this.presentationType_ == PresentationType.LIVE) {
let segmentAvailabilityDuration = this.getMinDuration_();
let segmentAvailabilityDuration = this.getLiveDuration_();

// This defaults to the presentation delay, which has the effect of
// making the live stream unseekable. This is consistent with Apple's
Expand Down Expand Up @@ -1927,6 +1935,7 @@ shaka.hls.HlsParser = class {
verbatimMediaPlaylistUri,
// These values are filled out or updated after lazy-loading:
absoluteMediaPlaylistUri: initialMediaPlaylistUri,
minTimestamp: 0,
maxTimestamp: 0,
mediaSequenceToStartTime: new Map(),
canSkipSegments: false,
Expand Down Expand Up @@ -1972,6 +1981,7 @@ shaka.hls.HlsParser = class {

// Copy values from the real stream info to our initial one.
streamInfo.absoluteMediaPlaylistUri = absoluteMediaPlaylistUri;
streamInfo.minTimestamp = realStreamInfo.minTimestamp;
streamInfo.maxTimestamp = realStreamInfo.maxTimestamp;
streamInfo.canSkipSegments = realStreamInfo.canSkipSegments;
streamInfo.hasEndList = realStreamInfo.hasEndList;
Expand Down Expand Up @@ -2098,6 +2108,22 @@ shaka.hls.HlsParser = class {
return minDuration;
}

/**
* @return {number}
* @private
*/
getLiveDuration_() {
let maxTimestamp = Infinity;
let minTimestamp = Infinity;
for (const streamInfo of this.uriToStreamInfosMap_.values()) {
if (streamInfo.stream.segmentIndex && streamInfo.stream.type != 'text') {
maxTimestamp = Math.min(maxTimestamp, streamInfo.maxTimestamp);
minTimestamp = Math.min(minTimestamp, streamInfo.minTimestamp);
}
}
return maxTimestamp - minTimestamp;
}

/**
* @param {!Array.<!shaka.extern.Stream>} streams
* @private
Expand Down Expand Up @@ -2236,6 +2262,7 @@ shaka.hls.HlsParser = class {
this.determinePresentationType_(playlist);
}

const firstStartTime = segments[0].startTime;
const lastEndTime = segments[segments.length - 1].endTime;
/** @type {!shaka.media.SegmentIndex} */
const segmentIndex = new shaka.media.SegmentIndex(segments);
Expand All @@ -2258,6 +2285,7 @@ shaka.hls.HlsParser = class {
type,
verbatimMediaPlaylistUri,
absoluteMediaPlaylistUri,
minTimestamp: firstStartTime,
maxTimestamp: lastEndTime,
canSkipSegments,
hasEndList: false,
Expand Down Expand Up @@ -3554,6 +3582,7 @@ shaka.hls.HlsParser = class {
* type: string,
* verbatimMediaPlaylistUri: string,
* absoluteMediaPlaylistUri: string,
* minTimestamp: number,
* maxTimestamp: number,
* mediaSequenceToStartTime: !Map.<number, number>,
* canSkipSegments: boolean,
Expand All @@ -3577,6 +3606,8 @@ shaka.hls.HlsParser = class {
* @property {string} absoluteMediaPlaylistUri
* The absolute media playlist URI, resolved relative to the master playlist
* and updated to reflect any redirects.
* @property {number} minTimestamp
* The minimum timestamp found in the stream.
* @property {number} maxTimestamp
* The maximum timestamp found in the stream.
* @property {!Map.<number, number>} mediaSequenceToStartTime
Expand Down