Orange-OpenSource / hasplayer.js

Http Adaptive Streaming javascript player based on HTML5 premium extensions (MSE/EME)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

range.end returned by getDVRWindowRange() is lower than actual end of live stream

vitalist82 opened this issue · comments

Hello,

we are using hasplayer.js for playing MSS+PlayReady streams.

In live streams, that have DVRWindowLength/TimeScale equal to 8hrs and total duration aprox. 1.5hr, we have a problem, when seeking back is performed, followed by few minutes of playback and then with an attempt to return to actual live position (time counted as sum of durations of all segments in manifest).

In such case, the player reports "loadNextFragment failed" for both audio and video and continues to fire timeupdate events while BufferController reports a constant Working time value and BufferLevel equal to 0 for 1 minute followed by this log:

[22:29:37.074][AbrController][video] Set playback quality: 0
[22:29:37.075][StreamController] Reset
[22:29:37.082][MediaPlayer] set config: {
	"BufferController.liveDelay": 32,
	"BufferController.minBufferTimeForPlaying": 3,
	"BufferController.minBufferTime": 32,
	"FragmentLoader.RetryAttempts": 6
} 
[22:29:37.083][AbrController][video] Set playback quality: 4 
[22:29:37.084][MediaPlayer] set config: {
	"video": {
		"ABR.keepBandwidthCondition": false
	},
	"audio": {
		"ABR.keepBandwidthCondition": true
	}
} 
[22:29:37.085]<video> # play() 
[22:29:37.167][Stream] <video> timeupdate event: 1516742860.662 
[22:29:37.167][BufferController][video] Working time = 1516742860.662, Buffer level = 0.000 
[22:29:37.168][BufferController][audio] Working time = 1516742860.662, Buffer level = 0.000 
[22:29:37.168][Stream] <video> pause event 
[22:29:37.168][Stream] stopBuffering 
[22:29:37.168][BufferController][video] STOP 
[22:29:37.169][BufferController][audio] STOP 
[22:29:37.169][MssFragmentInfoController][video] START 
[22:29:37.169][MssFragmentInfoController][video] Load next fragment for time: 1516742705.84 
[22:29:37.169][MssFragmentInfoController][video] Request fragment info https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(112000)/FragmentInfo(video=15167427058400000)?stream_id=66532392309 
[22:29:37.170][MssFragmentInfoController][video] Load request  https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(112000)/FragmentInfo(video=15167427058400000)?stream_id=66532392309 
[22:29:37.170][FragmentLoader][video] Load: https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(112000)/FragmentInfo(video=15167427058400000)?stream_id=66532392309 
[22:29:37.173][MssFragmentInfoController][audio] START 
[22:29:37.174][MssFragmentInfoController][audio] Load next fragment for time: 1516742717.36 
[22:29:37.174][MssFragmentInfoController][audio] Request fragment info https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(64000)/FragmentInfo(audio_1=15167427173600000)?stream_id=66532392309 
[22:29:37.175][MssFragmentInfoController][audio] Load request  https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(64000)/FragmentInfo(audio_1=15167427173600000)?stream_id=66532392309 
[22:29:37.176][FragmentLoader][audio] Load: https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(64000)/FragmentInfo(audio_1=15167427173600000)?stream_id=66532392309 
[22:29:37.194][Stream] Pause. 
[22:29:37.194]<video> # pause() 
[22:29:37.195][Stream] Reset 
[22:29:37.195][Stream] stopBuffering 
[22:29:37.195][MssFragmentInfoController][video] STOP 
[22:29:37.196][FragmentLoader][video] Abort XHR  
[22:29:37.196][MssFragmentInfoController][audio] STOP 
[22:29:37.197][FragmentLoader][audio] Abort XHR  
[22:29:37.197][Stream] Pause. 
[22:29:37.197]<video> # pause() 
[22:29:37.215][Warn] Code: DOWNLOAD_ERR_CONTENT, Message: Failed to download fragmentInfo segment, Data: {
	"url": "https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(112000)/FragmentInfo(video=15167427058400000)?stream_id=66532392309",
	"status": 0
} 
[22:29:37.230][Warn] Code: DOWNLOAD_ERR_CONTENT, Message: Failed to download fragmentInfo segment, Data: {
	"url": "https://dc3livecadz-a.akamaihd.net/live/channel/1010/all.ism/QualityLevels(64000)/FragmentInfo(audio_1=15167427173600000)?stream_id=66532392309",
	"status": 0
} 
[22:29:37.265][MediaPlayer] Version: 1.13.1_f1b61eb - 2017-12-1_13:0:43 
[22:29:37.265][MediaPlayer] user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko 
[22:29:37.266][MediaPlayer] Load stream:
 {
  "url": "https://dc4livecadz-a.akamaihd.net/live/channel/1010/all.ism/Manifest?event_id=66532392309&h=1e57f64553d84b86590afa5c3742e072",
  "startTime": 0,
  "protData": {
    "com.microsoft.playready": {
      "laURL": "..."
[22:29:37.266][StreamController] load url: https://dc4livecadz-a.akamaihd.net/live/channel/1010/all.ism/Manifest?event_id=66532392309&h=1e57f64553d84b86590afa5c3742e072 
[22:29:37.349][MssParser] Doing parse. 
[22:29:37.876][MssParser] Parsing complete (xmlParser: 47ms, mss2dash: 480ms, total: 0.527s) 
[22:29:37.884]<video> # reset source 
[22:29:38.509][StreamController] Manifest updated 
[22:29:38.510][StreamController] composeStreams 
[22:29:38.511][StreamController] Create stream 
[22:29:38.514][Stream] Create MediaSource 
...

Then the playback starts from live end.

When I tried to use MediaPlayer.getDVRWindowRange() to get a valid seeking range for live stream to seek to the end of the stream instead of using the sum of durations of all segments from manifest, I was getting a value, that was not actual end of the stream, but few minutes behind.

This issue is not visible, when the seek call to the end of the stream is performed quickly after the first seek call. But the longer the player plays behind the live end position, the bigger the difference between range.end and actual end of the live stream.

Seeking to range.end works without problems compared to seeking to a time value above.

Could you please suggest a proper way to seek back to actual live position (current end of live stream) from a position somewhere in the middle of the live stream?

The issue was reported on XboxOne, which is using Edge browser and it can also be reproduced on IE11.

Thanks.

Best regards,
Tomas Beranek

Hi @vitalist82 ,

the call to the getDVRWindowRange has to be done each time that a timeUpdate occurs in order to keep this window uptodate. is it what you do? Then, your seek command could be done without problems.

Nico

Hi @nicosang ,

I added the call to getDVRWindowRange to timeupdate event handler.

The returned value is updated well, but stops being updated after seeking back in the stream.

Tomas

are the fragmentInfo requests well downloaded? When you do a seek command, fragmentInfo requests are started in order to, exactly, update dvr info....

I attached full trace containing only few fragmentInfo requests.
seek-to-live-2.txt

Both seek events triggered by user interaction are included in the log.

Hi @vitalist82 ,

The problem is indeed about fragmentInfo requests. I took a look at your log. We can see that only one fragmentInfo is requested (one video and one audio). It seems that this fragmentInfo has only one tfrf box, normally there is two tfrf boxes. This boxes are important because they give timestamps of the next fragmentInfo. Do you know why you just have one box of this type?

Nico

Hi @nicosang ,

I don't know the reason for having only one tfrf box, but I can ask our stream provider.

I've been looking into https://dc3livededz-a.akamaihd.net/live/channel/1017/all.ism/QualityLevels(112000)/FragmentInfo(video=15168305732000000)?stream_id=67198504400 with MP4 Reader and it doesn't seem to contain any tfrf box.

Thanks,
Tomas

the last uuid box in the traf box is the tfrf box. My last comment was not precise enough....you should have one tfrf box with two entries in it (so, not really two tfrf boxes). Anyway, I think that adding the second entry should solve your issue....

There is a note from our stream provider:

so, when fragments are requested right up against the live edge, it's possible that there are not yet two fragments which follow the one being requested
in that case, I suspect the origin will serve fewer than the requested number of 'lookahead references'
and once that happens, the CDNs will of course cache those responses for $LONG_TIME

Could this be an explanation for this behaviour?

maybe....is it possible that you give us access to your live stream? hasplayer.js could maybe improve its behavior....

I can send you a manifest URL and apropriate LA URL with an expiration period, that should be longer, than the duration of the live event, if that would help. There will be multiple live events available tomorrow at following times:
09:00
10:00
12:00
13:00
14:30
15:00
16:45
17:15

Once the apropriate live event will start, I can send you the URLs to work with.

no problem, send me the stream when it will be available tomorrow. I'm in Europe, I hope you too...it will be easier to synchronize us.

The license should be valid for long enough. I can send you URLs of upcoming events later, when needed.

Hi Nico,

if you would like another manifest and LA URL, I can send it to you.

Regards,

Tomas

Hi @vitalist82 ,

yes, please. I didn't have enough time last friday to investigate.

Nico

Thanks Nico,

There is a live stream now, which will last for about one hour only, so I hope it will be enough. Later I will send another URLs to you. I've sent the URLs to your mailbox.

Tomas

Hey, @nicosang I'll send you a fresh Manifest/LA pair in a minute for a live stream per Tomas request.

Cheers,
Krzysztof

Hi @vitalist82 and @krozalski ,

could you, please, take a look at my last PR #215 ? I hope it will fix your issue.....

Thanks,
Nico

Hi @nicosang ,

I attached traces from the playback using hasplayer build from the fix branch.

It seems, that fragmentinfo requests are not being sent.

hasplayer-with-fix-2.txt

hasplayer-with-fix.txt

Tomas

Hi @vitalist82 ,

I can't get a valid key to decrypt stream.....

Nico

bug fixed by PR #215

Many thanks @nicosang for the fix!

Best regards,
Tomas