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

Catch-up player starts from beginning when manifest transitions from 'dynamic' to 'static' #3263

Closed
5 tasks done
mrp1977 opened this issue May 26, 2020 · 21 comments
Closed
5 tasks done
Assignees
Milestone

Comments

@mrp1977
Copy link

mrp1977 commented May 26, 2020

Environment
  • Link to playable MPD file: See below
  • Dash.js version:All
  • Browser name/version: All
  • OS name/version:All
Steps to reproduce
  1. Please provide clear steps to reproduce your proble
    The below will give a time relevant URL which can then be used in the player.

echo "https://live.unified-streaming.com/scte35/scte35.isml/.mpd?vbegin=$(($(date -u +%s)-240))&vend=$(($(date -u +%s)+60))"

using vbegin and vend in Unified Streaming software returns a manifest between the stated periods

  1. If the bug is intermittent, give a rough frequency if possible
    no
Observed behaviour

Describe what the player is doing that is unexpected or undesired behaviour.

Adding a vbegin in the past and a vend in the future to a livestream URL when the vend reaches wallclock time and the manifest transitions from a 'dynamic' to a 'static' rather than continuing to play the stream the player stalls and then starts from the vbegin time again.

Expected behaviour - Despite manifest transition from dynamic to static content should continue playing until vend.

Manifest changes as per https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf section 4.6
Examples of both static and dynamic manifests are attached.

dynamicmanifest.txt
staticmanifest.txt

Console output
Paste the contents of the browser console here.
You may need to enable debug logging in dash.js by calling player.updateSettings({ 'debug': { 'logLevel': dashjs.Debug.LOG_LEVEL_DEBUG }}) if you are using your own page.
@bbert
Copy link
Contributor

bbert commented Jun 4, 2020

Hi @mrp1977,
We will address this issue very soon

@bbert
Copy link
Contributor

bbert commented Jun 4, 2020

@mrp1977 please maintain the source stream available so that we can use it to fix and test

@bbert
Copy link
Contributor

bbert commented Jun 9, 2020

@mrp1977 please check current development version in which PR #3280 has been merged
Let us know if that resolves correctly your issue

@bbert
Copy link
Contributor

bbert commented Jun 9, 2020

We have to consider also the DVR window range since the timeShiftBufferDepth is not provided in the dynamic manifests. Thus DVR window is considered infinite and then start from 0 (1/1/1970)
@dsilhavy any idea? Should we then refer to effective SegmentTimeline to determine DVR window?

@dsilhavy
Copy link
Collaborator

dsilhavy commented Jun 9, 2020

When the transition from dynamic to static happens is a @mediaPresentationDuration attribute added? If so presentationDuration should be equal to @mediaPresentationDuration

Edit: Or does your question apply to dynamic streams without tsbd in general?

@bbert
Copy link
Contributor

bbert commented Jun 10, 2020

The question applies to dynamic streams without tsbd in general

@tskamaldeep
Copy link

Hi,
Just thought I would add a note here, as an initiation into the implementation details of the dash.js framework. Kindly clarify:
When a live stream drops out (or fails over), the publisher usually switches to the archive or static version of the manifest. In these instances, we added a feature known as the switchToLiveFailover in our framework which enables to:

  • Wait for the static version of the manifest to be published.
  • Connect to this version of the manifest (usually took about 30-60 secs in the event of sudden failover), during which time there would be an effort to re-connect to the stream.
  • On re-connection to the static manifest, there would be a seek issued to the same exact timestamp where the failover instance was observed (saved from earlier), enabling a resumption of the viewing session at the same instance.
  • If the live stream (dyanamic type) completed gracefully, a reconnection to the archive stream would be near instantaneous. (within one-two segments of time interval). If so, archive playback would ideally start from the beginning of the recorded stream.

These being the asks, could you kindly clarify if the intended feature request above is for the same purpose of adding an accurate 'switchToLiveArchiveOnEOS' option?

@bbert
Copy link
Contributor

bbert commented Jun 12, 2020

I'am not sure I fully understood but I would answer yes.
Thanks to PR #3280 you will be able to playback the live stream up to the end, even if record is stopping meanwhile.
Then you would'nt need this "switchToLiveArchiveOnEOS" mechanism.
Does it answer to your question?

@boy-vd
Copy link

boy-vd commented Jun 15, 2020

Thanks for picking up and fixing this issue so quickly @bbert. We (@mrp1977 and me, both working for Unified Streaming) have tested playback in the nightly build and the player no longer stalls in Chrome and Firefox when the MPD switches from 'dynamic' to 'static', as expected.

As for your question about 'timeShiftBufferDepth': in the past our sub-clipping behavior for live scenarios would include a growing value for this as long as the MPD was still dynamic, but we noticed that players didn't handle that well.

Instead of re-adding 'timeShiftBufferDepth', would it perhaps be a good and valid way to solve your issue by aligning 'availabilityStartTime' with the start of the requested sub-clip (while also adding a 'presentationTimeOffset' to compensate for the different 'availabilityStartTime', so that the UNIX epoch-based timestamps in the URLs can be maintained)? Or do you perhaps have other suggestions?

Unfortunately, the DASH-IF Guidelines for Implementation do not offer very clear guidance on this (version 4.3, paragraph 4.6.2):

The MPD@availabilityStartTime should be removed or be maintained from the live MPD since all resources referenced in the MPD are available. If the MPD@availabilityStartTime is maintained for a portion of the live program that is offered in the static MPD the Period@start value (including the presentation time offset and the start number) and the presentation duration shall be set accordingly. The relationship to the wall-clock time should be maintained by offsetting the Period@start without changing the MPD@availabilityStartTime.

And the work-in-progress version has even less to say about it: https://dashif-documents.azurewebsites.net/Guidelines-TimingModel/master/Guidelines-TimingModel.html#timing-mpd-updates-theend

@bbert
Copy link
Contributor

bbert commented Jun 15, 2020

The problem is that until the guidelines are not specified for this use case, servers and players will try to adapt to each other.
As you said, you had to remove 'timeShiftBufferDepth' since players didn't handle that well.
Maybe it would be a better solution to fix players so that they can handle that.

One suggestion, on player side, would be:

  • if 'timeShiftBufferDepth' is set in manifest then rely on it to determine the DVR window length
  • else if 'timeShiftBufferDepth' is NOT set, then rely on the effective (video) SegmentTimeline from manifest to determine the DVR window length

What do you think? @dsilhavy ?

@tskamaldeep
Copy link

@bbert, thank you very much for your response.

In this instance, the vbegin is mentioned as being behind the currentTime.
The vend is mentioned as being ahead of currentTime (allowing for time to transition from dynamic to static).
While the stream transitions, the live stream is still connected for playback. Following transition, the stream starts from beginning as an on-demand clip for the mentioned clipping duration.

When the user gives a vbegin, 4 minutes behind current time, they would expect to see the playback start at that instant, rather than the player at live edge and then start from the beginning on completion of transition. Could you kindly correct me if not accurate?
There are two instances then:

  1. vend value before the current epoch time:
    In this instance, we have the manifest as a static for sure and playback would be from vbegin to vend instantaneously.
  2. vend value ahead of the current epoch time:
    If the playback has to start from vbegin, then we alter the start timestamp to the start of the subclip and play at live edge until vend is reached. Once vend is reached, the transition completes and the static manifest generation indicates end of the subclip.

Would you advise that I start another issue thread for considering the switchToArchive feature for implementation? It may be suited for recovery from stream failover too.

Regards

I'am not sure I fully understood but I would answer yes.
Thanks to PR #3280 you will be able to playback the live stream up to the end, even if record is stopping meanwhile.
Then you would'nt need this "switchToLiveArchiveOnEOS" mechanism.
Does it answer to your question?

@dsilhavy
Copy link
Collaborator

Regarding timeShiftBufferDepth problem:

  • According to the spec: If timeShiftBufferDepth is not set this value is infinite. Consequently, in my opinion a player can expect all segments from the media presentation to be available. However, the problem would be to generate a valid segment url in case SegmentTimeline with $time is used if segments have been removed from the MPD.
  • Instead of adjusting the timeShiftBufferDepth over time, can you adjust the availabilityStartTime? If availabilityStartTime equals the start time of your presentation, omitting the timeShiftBufferDepth would still lead to a valid DVR window right?

@bbert
Copy link
Contributor

bbert commented Jun 16, 2020

When the user gives a vbegin, 4 minutes behind current time, they would expect to see the playback start at that instant, rather than the player at live edge and then start from the beginning on completion of transition. Could you kindly correct me if not accurate?

Yes, you can start the playback by providing the vbegin time as a start time to the player.

There are two instances then:

  1. vend value before the current epoch time:
    In this instance, we have the manifest as a static for sure and playback would be from vbegin to vend instantaneously.
  2. vend value ahead of the current epoch time:
    If the playback has to start from vbegin, then we alter the start timestamp to the start of the subclip and play at live edge until vend is reached. Once vend is reached, the transition completes and the static manifest generation indicates end of the subclip.

What do you mean by alter the start timestamp?
If you know the vbegin (without parsing manifest) you can provided this vegin as the playback start time (as an url anchor).

@dsilhavy:

Regarding timeShiftBufferDepth problem:

According to the spec: If timeShiftBufferDepth is not set this value is infinite. Consequently, in my opinion a player can expect all segments from the media presentation to be available. However, the problem would be to generate a valid segment url in case SegmentTimeline with $time is used if segments have been removed from the MPD.
Instead of adjusting the timeShiftBufferDepth over time, can you adjust the availabilityStartTime? If availabilityStartTime equals the start time of your presentation, omitting the timeShiftBufferDepth would still lead to a valid DVR window right?

One point is that some servers already exist and are deployed with missing 'timeShiftBufferDepth' and availabilityStartTime set to 1/1/1970

@bbert
Copy link
Contributor

bbert commented Jun 16, 2020

I've pushed a PR #3294 that proposes a fix for determining the segments availability range and thus the DVR window range in case the timeShiftBufferDepth is not provided in manifest.

At this stage, when loading a test stream from your servers, it starts playback from beginning since player fails to find a valid segment at live edge (@dsilhavy maybe related to #3217 which I broke recently). But this should be fixed very soon.

Thanks to this PR, the DVR window will increase progressively, getDuration() returns the DVR window range, i.e. from [0, <current epoch time - vbegin>] up to [0, <vend - vbegin>]

This is a proposal but we can discuss on it

@boy-vd
Copy link

boy-vd commented Jun 16, 2020

Thanks @bbert. Although I'm not sure exactly what you mean by:

At this stage, when loading a test stream from your servers, it starts playback from beginning since player fails to find a valid segment at live edge (@dsilhavy maybe related to #3217 which I broke recently). But this should be fixed very soon.

Do you refer to any 'normal' live stream from our servers, or only one that is a sub-clip with a start time in the past and an end time in the future? In the first case we do add 'timeShiftBufferDepth', in the second we don't. If your statement refers to only the use case with a sub-clip that has an end time in the future, I think it makes perfect sense for playback to begin at the start of that clip (instead of the live edge).

@dsilhavy
Copy link
Collaborator

@bbert Thanks I will check the PR
@boy-vd : I will try to answer your question in Slack this week. Haven't had the time yet.

Regarding live edge: This was fixed here: #3285 . There is still an issue in some cases when seeking back within the DVR window and returning to live. However, starting ad the live edge should work in the nightly.

I remember we had a similar PR adjusting the DVR window for SegmentTimeline manifests based on the elements in the MPD. However, this broke multiperiod which is why we came up with #3285.

I will bring up this topic in one of the IOP calls.

Question from my side: In the sub-clip case in which start is in the past and end is in the future: Why do you expect the player to begin at the start of the clip? I would expect this to be a dynamic manifest for which we calculate the live edge. What would be the difference compared to a "normal" live stream?

@boy-vd
Copy link

boy-vd commented Jun 16, 2020

Thanks @dsilhavy.

Your plan to bring this topic up for discussion in one of the IOP calls sounds great. As active contributors in DASH-IF we would happily join such a call to share our perspective, so if you could notify us beforehand that would be much appreciated.

As for your question about whether playback of this type of sub-clip should start at the beginning or at the live edge, I must admit that my previous statement was probably made too hastily: there are definitely good reasons to want to start playback at the live edge as well. I don't think it's a clear cut case of one over the other, but rather that it depends on context and type of content.

@bbert
Copy link
Contributor

bbert commented Jun 16, 2020

@boy-vd

Do you refer to any 'normal' live stream from our servers, or only one that is a sub-clip with a start time in the past and an end time in the future? In the first case we do add 'timeShiftBufferDepth', in the second we don't. If your statement refers to only the use case with a sub-clip that has an end time in the future, I think it makes perfect sense for playback to begin at the start of that clip (instead of the live edge).

I was refering to sub-clip use case. Normally player should start at live edge, but you can specify to start playback at vbegin using url anchor. (But in current version it does start at vbegin incidentally)

@dsilhavy

Question from my side: In the sub-clip case in which start is in the past and end is in the future: Why do you expect the player to begin at the start of the clip? I would expect this to be a dynamic manifest for which we calculate the live edge. What would be the difference compared to a "normal" live stream?

Sub-clip case correspond to NPVR-like streams, then when you start watching your record it may be more suitable for users to start watching at the beginning. But you're right by default it should start at live edge, but as @boy-vd said, it depends of the context and application can make the choice to start at vbegin

@dsilhavy
Copy link
Collaborator

@bbert You are right thanks for the hint. Because the DVR window is set to infinity one of the checks in StreamProcessor fails and playback starts from the beginning of the timeline:

    // Make sure that we have at least a valid request for the end of the DVR window, otherwise we might try forever
            if (getFragmentRequest(currentRepresentationInfo, liveEdge - dvrWindowSize + dvrWindowSafetyMargin, {
                ignoreIsFinished: true
            }))

I open a separate issue for that.

@dsilhavy
Copy link
Collaborator

@boy-vd We have a biweekly call with Thomas Stockhammer and Ece Öztürk from Nomor. Next one is on Tuesday:

Tuesday, June 22, 2020
10:00 AM - 11:00 AM CEST

I send you the dial in data on Slack
Repeats every 2nd Tuesday until Apr 14, 2022

@dsilhavy
Copy link
Collaborator

I close this issue, as the original problem was fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants