Skip to content

Commit

Permalink
feat: media-sequence sync strategy, remove calculateTimestampOffsetFo…
Browse files Browse the repository at this point in the history
…rEachSegment and remove replaceSegmentsUntil (#1457)

* Revert "fix: check for transmuxer for vtt-segment-loader (#1452)"

This reverts commit b4dd748.

* Revert "fix: fix several issues with calculate timestamp offset for each segment (#1451)"

This reverts commit 3bbc6ef.

* Revert "fix: replaceSegmentsUntil flag resetting too early (#1444)"

This reverts commit af39ba5.

* Revert "fix: prevent wrapping in resetMainLoaderReplaceSegments (#1439)"

This reverts commit 719b7f4.

* Revert "feat: Add feature flag to calculate timestampOffset for each segment to handle streams with corrupted pts or dts timestamps (#1426)"

This reverts commit 2355ddc.

* Revert "fix: fastQualityChange refactor (#1414)"

This reverts commit 4590bdd.

* cherry-pick: use transmuxer time info instead of probeTs

* feat: sync controller media sequence strategy (#1458)

* feat: add media sequence sync strategy

* fix: fix current media sequence increment

* chore: update logs

* feat: use exact segment match in sync-controller

* fix: fix race condition for a fast quality switch

* chore: add additional logs for choose next request

* feat: force timestamp after resync

* chore: fix or skip tests

* Update src/segment-loader.js

Co-authored-by: Walter Seymour <[email protected]>

---------

Co-authored-by: Dzianis Dashkevich <[email protected]>
Co-authored-by: Walter Seymour <[email protected]>

---------

Co-authored-by: Dzianis Dashkevich <[email protected]>
Co-authored-by: Walter Seymour <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2023
1 parent a891580 commit e304c20
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 224 deletions.
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,6 @@ This option defaults to `false`.
* Default: `false`
* Use [Decode Timestamp](https://www.w3.org/TR/media-source/#decode-timestamp) instead of [Presentation Timestamp](https://www.w3.org/TR/media-source/#presentation-timestamp) for [timestampOffset](https://www.w3.org/TR/media-source/#dom-sourcebuffer-timestampoffset) calculation. This option was introduced to align with DTS-based browsers. This option affects only transmuxed data (eg: transport stream). For more info please check the following [issue](https://github.com/videojs/http-streaming/issues/1247).

##### calculateTimestampOffsetForEachSegment
* Type: `boolean`,
* Default: `false`
* Calculate timestampOffset for each segment, regardless of its timeline. Sometimes it is helpful when you have corrupted DTS/PTS timestamps during discontinuities.


##### useForcedSubtitles
* Type: `boolean`
* Default: `false`
Expand Down
5 changes: 0 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,6 @@
<label class="form-check-label" for="dts-offset">Use DTS instead of PTS for Timestamp Offset calculation (reloads player)</label>
</div>

<div class="form-check">
<input id=offset-each-segment type="checkbox" class="form-check-input">
<label class="form-check-label" for="offset-each-segment">Calculate timestampOffset for each segment, regardless of its timeline (reloads player)</label>
</div>

<div class="form-check">
<input id=llhls type="checkbox" class="form-check-input">
<label class="form-check-label" for="llhls">[EXPERIMENTAL] Enables support for ll-hls (reloads player)</label>
Expand Down
3 changes: 0 additions & 3 deletions scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,6 @@
'pixel-diff-selector',
'network-info',
'dts-offset',
'offset-each-segment',
'override-native',
'preload',
'mirror-source',
Expand Down Expand Up @@ -526,7 +525,6 @@
'pixel-diff-selector',
'network-info',
'dts-offset',
'offset-each-segment',
'exact-manifest-timings',
'forced-subtitles'
].forEach(function(name) {
Expand Down Expand Up @@ -611,7 +609,6 @@
leastPixelDiffSelector: getInputValue(stateEls['pixel-diff-selector']),
useNetworkInformationApi: getInputValue(stateEls['network-info']),
useDtsForTimestampOffset: getInputValue(stateEls['dts-offset']),
calculateTimestampOffsetForEachSegment: getInputValue(stateEls['offset-each-segment']),
useForcedSubtitles: getInputValue(stateEls['forced-subtitles'])
}
}
Expand Down
60 changes: 36 additions & 24 deletions src/playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ export class PlaylistController extends videojs.EventTarget {
vhs: this.vhs_,
parse708captions: options.parse708captions,
useDtsForTimestampOffset: options.useDtsForTimestampOffset,
calculateTimestampOffsetForEachSegment: options.calculateTimestampOffsetForEachSegment,
captionServices,
mediaSource: this.mediaSource,
currentTime: this.tech_.currentTime.bind(this.tech_),
Expand Down Expand Up @@ -682,9 +681,14 @@ export class PlaylistController extends videojs.EventTarget {
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `loadedplaylist`
this.mainSegmentLoader_.pause();
this.mainSegmentLoader_.playlist(media, this.requestOptions_);

this.mainSegmentLoader_.load();
if (this.waitingForFastQualityPlaylistReceived_) {
this.runFastQualitySwitch_();
} else {
this.mainSegmentLoader_.load();
}

this.tech_.trigger({
type: 'mediachange',
Expand Down Expand Up @@ -746,7 +750,12 @@ export class PlaylistController extends videojs.EventTarget {
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `mediachange`
this.mainSegmentLoader_.pause();
this.mainSegmentLoader_.playlist(updatedPlaylist, this.requestOptions_);
if (this.waitingForFastQualityPlaylistReceived_) {
this.runFastQualitySwitch_();
}

this.updateDuration(!updatedPlaylist.endList);

// If the player isn't paused, ensure that the segment loader is running,
Expand Down Expand Up @@ -961,9 +970,9 @@ export class PlaylistController extends videojs.EventTarget {

/**
* Re-tune playback quality level for the current player
* conditions. This will reset the main segment loader
* and the next segment position to the currentTime.
* This is good for manual quality changes.
* conditions. This method will perform destructive actions like removing
* already buffered content in order to readjust the currently active
* playlist quickly. This is good for manual quality changes
*
* @private
*/
Expand All @@ -972,28 +981,28 @@ export class PlaylistController extends videojs.EventTarget {
this.logger_('skipping fastQualityChange because new media is same as old');
return;
}

this.switchMedia_(media, 'fast-quality');
// Reset main segment loader properties and next segment position information.
// Don't need to reset audio as it is reset when media changes.
// We resetLoaderProperties separately here as we want to fetch init segments if
// necessary and ensure we're not in an ended state when we switch playlists.
this.resetMainLoaderReplaceSegments();
}

/**
* Sets the replaceUntil flag on the main segment soader to the buffered end
* and resets the main segment loaders properties.
*/
resetMainLoaderReplaceSegments() {
const buffered = this.tech_.buffered();
const bufferedEnd = buffered.length ? buffered.end(buffered.length - 1) : 0;
// we would like to avoid race condition when we call fastQuality,
// reset everything and start loading segments from prev segments instead of new because new playlist is not received yet
this.waitingForFastQualityPlaylistReceived_ = true;
}

runFastQualitySwitch_() {
this.waitingForFastQualityPlaylistReceived_ = false;
// Delete all buffered data to allow an immediate quality switch, then seek to give
// the browser a kick to remove any cached frames from the previous rendtion (.04 seconds
// ahead was roughly the minimum that will accomplish this across a variety of content
// in IE and Edge, but seeking in place is sufficient on all other browsers)
// Edge/IE bug: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14600375/
// Chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=651904
this.mainSegmentLoader_.pause();
this.mainSegmentLoader_.resetEverything(() => {
this.tech_.setCurrentTime(this.tech_.currentTime());
});

// Set the replace segments flag to the buffered end, this forces fetchAtBuffer
// on the main loader to remain, false after the resetLoader call, until we have
// replaced all content buffered ahead of the currentTime.
this.mainSegmentLoader_.replaceSegmentsUntil = bufferedEnd;
this.mainSegmentLoader_.resetLoaderProperties();
this.mainSegmentLoader_.resetLoader();
// don't need to reset audio as it is reset when media changes
}

/**
Expand Down Expand Up @@ -1455,11 +1464,14 @@ export class PlaylistController extends videojs.EventTarget {

// cancel outstanding requests so we begin buffering at the new
// location
this.mainSegmentLoader_.pause();
this.mainSegmentLoader_.resetEverything();
if (this.mediaTypes_.AUDIO.activePlaylistLoader) {
this.audioSegmentLoader_.pause();
this.audioSegmentLoader_.resetEverything();
}
if (this.mediaTypes_.SUBTITLES.activePlaylistLoader) {
this.subtitleSegmentLoader_.pause();
this.subtitleSegmentLoader_.resetEverything();
}

Expand Down
Loading

0 comments on commit e304c20

Please sign in to comment.