shaka-project / shaka-player

JavaScript player library / DASH & HLS client / MSE-EME player
Apache License 2.0
7.21k stars 1.34k forks source link

Seeking to certain points of a video leads to buffering happening outside of the desired range #284

Closed javess-zz closed 8 years ago

javess-zz commented 8 years ago

I'm testing shaka player with a fairly standard MPD. The total duration of my video is around 540 s.

When I try to use seeking I'm finding a very weird issue where if I execute the following command in the chrome console:

document.getElementById('video').currentTime = 100

The video gets stuck in a buffering state. When I check the buffered property of the video I can see that for some reason the buffer starts a few seconds after the 100s mark.

> document.getElementById('video').currentTime = 100.0
< 100
> document.getElementById('video').buffered.start(0)
< 109.412426
> document.getElementById('video').buffered.end(0)
< 127.04

Oddly enough if I try to seek using the same method to the 200s mark it works fine and the buffers include the time I'm trying to play.

> document.getElementById('video').currentTime = 200.0
< 200
> document.getElementById('video').buffered.start(0)
< 193.329342
> document.getElementById('video').buffered.end(0)
< 221.08

It seems like in some cases the player is fetching the chunk just ahead of the one the one that I need. Is there some configuration I could have missed? What are good ways to try to debug this issue?

joeyparrish commented 8 years ago

There are a number of ways a manifest could be inaccurate, and we do our best to compensate. But some content is just broken (badly-encoded, missing or wrong information in the manifest, etc.) It could also be a true bug in the client. I don't think I've seen exactly this behavior before, so it's hard to guess.

Could you also check these values after seeking to 100?

app.player_.videoSource_.streamsByType_.video.sbm_.sourceBuffer_.buffered.start(0);
app.player_.videoSource_.streamsByType_.video.sbm_.sourceBuffer_.buffered.end(0);
app.player_.videoSource_.streamsByType_.audio.sbm_.sourceBuffer_.buffered.start(0);
app.player_.videoSource_.streamsByType_.audio.sbm_.sourceBuffer_.buffered.end(0);

The video element's buffered range is the intersection of the individual SourceBuffer ranges, so it would be informative to know what the SourceBuffers have to say. Often-times, one stream or the other is actually the cause.

Also, is the stream publicly available? If our team had access to the manifest and the content, that would really help. If this is not something you can share publicly, please feel free to send me a private email.

javess-zz commented 8 years ago

Running the values of the audio and video buffer independently yield similar results

> app.player_.videoSource_.streamsByType_.video.sbm_.sourceBuffer_.buffered.start(0);
< 109.4
> app.player_.videoSource_.streamsByType_.audio.sbm_.sourceBuffer_.buffered.start(0);
< 109.412426
> app.player_.videoSource_.streamsByType_.video.sbm_.sourceBuffer_.buffered.end(0);
< 226.8
> app.player_.videoSource_.streamsByType_.audio.sbm_.sourceBuffer_.buffered.end(0);
< 540

I'll send you the link to the stream privately so you can check it out.

joeyparrish commented 8 years ago

Thanks, @javess. We'll take a look and try to reproduce.

joeyparrish commented 8 years ago

Here's a simplified version of what I'm seeing in the manifest:

<SegmentTemplate timescale="25000" duration="175454" startNumber="0" media="segment_$Number$.m4s" initialization="init.mp4"/>

duration / timescale gives each segment a length of 7.018 seconds. Segment 0 starts at t=0, segment 1 starts at t=7.018, etc.

Let's calculate the segment which contains t=100. 100 / 7.018 = 14.249, so we expect timestamp 100 to be in segment 14. According to the manifest, segment 14 should start at t=98.254 and end at t=105.272.

If I examine the segments, this is what I find:

Segment Number Calculated Timestamp Actual Timestamp
0 0 0
1 7.018 10.920
2 14.036 22.920
3 21.054 32.920
... ... ...
14 98.254 109.400

So it seems that your manifest is inaccurate from the very beginning. I don't think it's reasonable for the player to detect or handle this.

What encoder are you using? How did you create this particular piece of content?

javess-zz commented 8 years ago

joey this was handed to me by a coworker but I believe it was done using bitmovin.

How did you examine the segments? I've been looking for a way to manually do that for a while

joeyparrish commented 8 years ago

I used mp4info from Bento4. Here's the skeleton of what I did:

# Download segments
wget http://foo.bar/path/to/init.mp4
wget http://foo.bar/path/to/segment_0.m4s

# Combine media segment with init segment so Bento4 can read the segment
cat init.mp4 segment_0.m4s > s0.mp4

# Show the first 10 frames and their timestamps:
mp4info --verbose --show-samples s0.mp4 | grep cts | head -n 10

Output looks like this:

[000001] size=   227 duration=  1000 (    40 ms) offset=      4134 dts=         0 (         0 ms) cts=      2000 (        80 ms) [0] [S] <I>
[000002] size=    41 duration=  1000 (    40 ms) offset=      4361 dts=      1000 (        40 ms) cts=      6000 (       240 ms) [0]     <P>
[000003] size=    37 duration=  1000 (    40 ms) offset=      4402 dts=      2000 (        80 ms) cts=      4000 (       160 ms) [0]     <B>
[000004] size=    37 duration=  1000 (    40 ms) offset=      4439 dts=      3000 (       120 ms) cts=      3000 (       120 ms) [0]     <B>
[000005] size=    37 duration=  1000 (    40 ms) offset=      4476 dts=      4000 (       160 ms) cts=      5000 (       200 ms) [0]     <B>
[000006] size=    43 duration=  1000 (    40 ms) offset=      4513 dts=      5000 (       200 ms) cts=     10000 (       400 ms) [0]     <P>
[000007] size=    39 duration=  1000 (    40 ms) offset=      4556 dts=      6000 (       240 ms) cts=      8000 (       320 ms) [0]     <B>
[000008] size=    37 duration=  1000 (    40 ms) offset=      4595 dts=      7000 (       280 ms) cts=      7000 (       280 ms) [0]     <B>
[000009] size=    37 duration=  1000 (    40 ms) offset=      4632 dts=      8000 (       320 ms) cts=      9000 (       360 ms) [0]     <B>
[000010] size=    43 duration=  1000 (    40 ms) offset=      4669 dts=      9000 (       360 ms) cts=     14000 (       560 ms) [0]     <P>
joeyparrish commented 8 years ago

Since this seems to be badly-encoded or badly-packaged content, I'm going to close this issue. Please follow up with bitmovin for resolution and feel free to reference this conversation for the technical details. Thanks for using Shaka!