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

[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH #1300

Merged
merged 4 commits into from
Dec 4, 2023

Conversation

peaBerberian
Copy link
Collaborator

@peaBerberian peaBerberian commented Oct 12, 2023

This PR improves several parts around the detection of the live edge of the content, especially when the DASH availabilityTimeOffset property is set, which may indicate that some segments announced in the MPD may or may not be ready to be fetched.

It also adds the getLivePosition method to the RxPlayer, and allows for a more precize initial position choice by the RxPlayer when the live position is known.

Gains are mostly for some ad-switched DASH contents and DASH low-latency live contents. Behavior should not change that much for other cases.

Set better initial position for live contents

Only when an explicit clock has been communicated to the RxPlayer (that is, either through DASH <UTCTiming> elements or through the serverSyncInfos loadVideo option), we will now by default initially play dynamic DASH contents close to the current date indicated by that clock.

Previously, rules were complex (and in a way they still are), but if segments were explicitely declared in the DASH MPD, we could consider the end of the last declared segment as the true live position, and thus begin playback close to it.

This is problematic in the rare scenario (but one that we encounter today) where the DASH MPD actually already includes segments that is intended to be played in the future (so, not now).
For example a trick exists when doing ad-switching, where you might want to declare all segments from an ad break in advance to simplify/optimize your back-end, but still want the player to start playback at a "live" position (and not close to that ad break's end like it would have done without this PR). Here, you thus want the player to not rely on the last segment's end to define its starting position - it would be beginning playback in the "future".

new getLivePosition API

A new API, getLivePosition, was added to let the RxPlayer communicate what the live edge of the content is.

Previously getMaximumPosition filled that need. But now that we handle cases where segments further than the live position might already be loaded and seeked to, it seems that getMaximumPosition should be set to the MPD's last requestable segment's end whereas a new getLivePosition method should be added so that an application can display to the user what the generally-intended maximum playable position is if playing further than live is forbidden (as it should be in most cases I guess).

Sadly, for technical reasons detailed below, this method will only return a pertinent result in that aforementioned case if a clock has been explicitely communicated to the RxPlayer (again, either through DASH <UTCTiming> elements or through the serverSyncInfos loadVideo option) for DASH contents.
For all other cases, this value should be very close to or equal to what would have been returned by getMaximumPosition.

availabilityTimeOffset treatment

I realize that the availabilityTimeOffset attribute was never used when a SegmentTimeline was present. In that case, we just always assumed that all segments announced in the MPD were directly available.
This does not seem to be in accordance with DASH specs which seems to allow segments to be announced in the manifest BEFORE they can actually be requested.

I ended up relying on a complex behavior, which is not fully spec-compliant (I'm generally against this but hear me up :P), but which makes more sense for the DASH MPD we encounter in practice.

The behavior depends on multiple criteria, described below.

When it's a SegmentTimeline-based Representation:

  • If at least one of either the availabilityTimeOffset OR the availabilityTimeComplete attribute (or both) is linked to that Representation AND an explicit clock has been provided to the RxPlayer (either from an UTCTiming element in the MPD or from the serverSyncInfos loadVideo option) we try at best to apply the specification or at least what I understood of it: only segments which are available up to their "adjusted availability start time" are available.

    Basically, we will only download a segment seen in the MPD if MPD attributes tells us that it should be fully available (which could be simplified as: when the clock + availabilityTimeOffset is equal or superior to that segment's end + the MPD@availabilityStartTime).

    Moreover, the new RxPlayers getLivePosition API will return the new value of the synchronized clock, as expected.

  • If no availabilityTimeOffset nor availabilityTimeComplete is explicitely set on the MPD for this Representation's segments, or if at least one of them is set BUT no explicit clock has been communicated to the RxPlayer, we just consider that all announced segments are available.

    This is NOT what I interpreted from the various DASH specs but it seems to be a more adapted logic relative to the contents I encountered.

    The advantage of doing this is that we can request the last segments of an MPD even when the given clock is not synchronized to the server's, with the assumption that segments announced in the MPD are only available segments.

    The main disadvantage of doing this is that we may request segments which are not considered to be requestable yet but which are in the MPD.
    If this does happen in the future for any content, I may correct this behavior, but for now, it seems that announcing future segments is mainly done either for low-latency contents or ad-switching where the availabilityTimeOffset attribute seems to be set.

    This is why this special behavior is only enabled when availabilityTimeOffset and availabilityTimeComplete are NOT found, in which case we assume that it is just a "regular" content, or when no clock is provided in which case we assume that the user's clock is unreliable.

    Also in that case, the new RxPlayer's getLivePosition API may weirdly return a position based on the maximum segment's end encountered on the last refreshed manifest, which may be completely wrong.

When it's a SegmentTemplate without SegmentTimeline Representation:

  • The rules I understood from the DASH specs are always applied, only they are based on the perhaps-unsynchronized Date.now()-based cliend-side clock if no clock was explicitely communicated to the RxPlayer (again, either from an UTCTiming element in the MPD or from the serverSyncInfos loadVideo option).

    In that case, the new RxPlayer's getLivePosition API will be based on the user clock.

    We're forced to rely on the user's clock here, as no segment are listed when no SegmentTimeline is present in the MPD.

When it's any other segment indexing scheme:

  • No special rule apply as other types should not be used for live contents (which I guess are the only contents which are concerned here).

In reality, rules are even more complex because we may have a mix of SegmentTimeline and SegmentTemplate without SegmentTimeline in the same MPD, but describing the whole logic in details would be too long here.

@peaBerberian peaBerberian changed the base branch from master to next October 12, 2023 12:56
@peaBerberian peaBerberian force-pushed the feat/getLiveEdge branch 6 times, most recently from 7b9cece to d3f0772 Compare October 13, 2023 09:03
@peaBerberian peaBerberian added the Priority: 2 (Medium) This issue or PR has a medium priority. label Nov 2, 2023
@peaBerberian peaBerberian merged commit 8d70305 into next Dec 4, 2023
3 checks passed
peaBerberian added a commit that referenced this pull request Dec 5, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Dec 5, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Dec 7, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Dec 19, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Dec 20, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Dec 22, 2023
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Jan 3, 2024
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Jan 3, 2024
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Jan 11, 2024
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Jan 15, 2024
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
peaBerberian added a commit that referenced this pull request Jan 23, 2024
[WIP] Add getLivePosition API and better handle availabilityTimeOffset for DASH
@peaBerberian peaBerberian mentioned this pull request Jan 24, 2024
@peaBerberian peaBerberian deleted the feat/getLiveEdge branch February 7, 2024 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: 2 (Medium) This issue or PR has a medium priority.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants