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

BehindLiveWindowException in HlsChunkSource -->getNextChunk #1782

Closed
Geppetto76 opened this issue Aug 26, 2016 · 32 comments
Closed

BehindLiveWindowException in HlsChunkSource -->getNextChunk #1782

Geppetto76 opened this issue Aug 26, 2016 · 32 comments
Assignees
Labels

Comments

@Geppetto76
Copy link

Hi,
If I use ExoPlayer dev-v2, when I use the HLS streaming link
http://viacomitalytest-lh.akamaihd.net/i/sbshdlive_1@195657/master.m3u8

I get this error:

ExoPlayerImplInternal: Source error.

com.google.android.exoplayer2.source.BehindLiveWindowException
    at com.google.android.exoplayer2.source.hls.HlsChunkSource.getNextChunk(HlsChunkSource.java:212)
    at com.google.android.exoplayer2.source.hls.HlsSampleStreamWrapper.continueLoading(HlsSampleStreamWrapper.java:302)
    at com.google.android.exoplayer2.source.CompositeSequenceableLoader.continueLoading(CompositeSequenceableLoader.java:55)
    at com.google.android.exoplayer2.source.hls.HlsMediaSource.continueLoading(HlsMediaSource.java:210)
    at com.google.android.exoplayer2.ExoPlayerImplInternal.maybeContinueLoading(ExoPlayerImplInternal.java:1069)
    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleContinueLoadingRequested(ExoPlayerImplInternal.java:1057)
    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:289)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:148)
    at android.os.HandlerThread.run(HandlerThread.java:61)
    at com.google.android.exoplayer2.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)

however with release-v1, streaming works well.

How can I fix the problem?
Thanks.

@ojw28
Copy link
Contributor

ojw28 commented Aug 26, 2016

HLS is known broken in V2 currently. We'll be pushing fixes shortly.

@xuxucode
Copy link

xuxucode commented Sep 19, 2016

I am facing same problem with r2.0.0, any update?

@jonasevcik
Copy link

@ojw28 Is there a possibility to get involved in HLS support development? I've written a bunch of fixes in that regard, so I can provide them here. There is no clear public timeline of this project, so I'm worried I may be doing duplicate work:)

@AquilesCanta
Copy link
Contributor

Hi, guys, I am currently taking care of Hls support. We are currently working on this but we have quite a lot going on. I already have in mind a few ways of minimizing the BLWEs you are getting, but it is blocked by some new features being added. Once those go through, I will address this directly. I am curious about the fixes you speak about, @jonasevcik. If you don't mind giving me an overview, we can consider adding them to Exoplayer.

@jonasevcik
Copy link

@AquilesCanta all my changes are available in a fork here https://github.com/jonasevcik/ExoPlayer/tree/startover (everything originating from the dev-v2 branch)

Quick summary of the changes:

  • added support for #EXT-X-PLAYLIST-TYPE - it made seeking possible in live events
  • live playlists (not live events) start playback 3 chunks from end of the playlist
  • live playlists (incl. live events) are refreshed periodically according to the specs

known issue

  • playlist is not being refreshed while playback is paused

Everything is implemented without breaking or introducing new interfaces.

If you give me more info regarding the timeline and planned features, I can get more involved.

@AquilesCanta
Copy link
Contributor

added support for #EXT-X-PLAYLIST-TYPE - it made seeking possible in live events

This will have to wait until we add live seeking support in HLS, its on the map so it is a matter of time. Once I get to it, we can look at the possibility of integrating it. In the meantime, we have to wait for a few other more basic things to get pushed.

live playlists (not live events) start playback 3 chunks from end of the playlist

This is already happening in V2, right? Have you checked the released version?

live playlists (incl. live events) are refreshed periodically according to the specs

This is already happening while playing in V2. Haven't thought about:

playlist is not being refreshed while playback is paused

I haven't given much thought to the paused case, as it will be directly addressed once live HLS seeking is supported. I will keep in touch once I get to HLS live seeking. Please give the latest v2 release a try and let me know if something I said is incorrect. Thanks for your interest.

@jonasevcik
Copy link

added support for #EXT-X-PLAYLIST-TYPE - it made seeking possible in live events

This will have to wait until we add live seeking support in HLS, its on the map so it is a matter of time. Once I get to it, we can look at the possibility of integrating it. In the meantime, we have to wait for a few other more basic things to get pushed.

Ok

live playlists (not live events) start playback 3 chunks from end of the playlist

This is already happening in V2, right? Have you checked the released version?

This is correct. Sorry, my bad.

live playlists (incl. live events) are refreshed periodically according to the specs

This is already happening while playing in V2.

Refreshing of a live playlist is now better, but still not perfect. See, refresh can occur only when this condition is met
if (chunkIndex >= mediaPlaylist.segments.size())
It is too late to start refreshing while playing the last chunk. Then, if you don't meet the condition regarding min. refresh time, you'll get stuck. Live playlists should be refreshed periodically regardless current playback position. That's the main design flaw.
Another minor issue is not refreshing according to the time defined in the spec:

When a client loads a Playlist file for the first time or reloads a
Playlist file and finds that it has changed since the last time it
was loaded, the client MUST wait for at least the target duration
before attempting to reload the Playlist file again, measured from
the last time the client began loading the Playlist file.

If the client reloads a Playlist file and finds that it has not
changed then it MUST wait for a period of one-half the target
duration before retrying.

Current implementation doesn't look for changes in downloaded playlist, so refreshing happens at rate >= target_duration / 2. If the playlist wasn't changed, refreshing it at the rate of target_duration is sufficient.

@AquilesCanta
Copy link
Contributor

It is too late to start refreshing while playing the last chunk. Then, if you don't meet the condition regarding min. refresh time, you'll get stuck. Live playlists should be refreshed periodically regardless current playback position. That's the main design flaw.

Can you please clarify? This

if (chunkIndex >= mediaPlaylist.segments.size())

has nothing to do with the playback position. In other words, refreshing the playlist does not have anything to do with playback position. We used to poll the playlist, if I remember correctly. We now only poll it (with half the target duration time interval) when we get to the live edge while loading the chunks. If I am playing the end of the live window(far away from the live edge), I don't see a reason to reload the media playlist (can you provide an example? Or maybe a fragment from the spec? I didn't see a paragraph that states that it is mandatory to refresh the media playlist periodically).

On the other hand, If I am playing near the live edge, then the loading position will get to the live edge as well, at which point we might need to refresh the playlist periodically to see whether a new segment has been added. This, we do at the rate advised by the spec (half the target duration). Also, playing too near the live edge is not advisable as per:

If the EXT-X-ENDLIST tag is not
present and the client intends to play the media normally, the client
SHOULD NOT choose a segment which starts less than three target
durations from the end of the Playlist file. Doing so can trigger
playback stalls.

Is there something I am missing here?

Also,

Current implementation doesn't look for changes in downloaded playlist, so refreshing happens at rate >= target_duration / 2. If the playlist wasn't changed, refreshing it at the rate of target_duration is sufficient.

This is suggesting we increase the refresh interval, not decrease it, when we finally get a different playlist. I assume

If the playlist wasn't changed, refreshing it at the rate of target_duration is sufficient.

meant "If the playlist was changed". This is indeed out of spec but, in my opinion, with no greatly negative consequences (does not mean you will get stuck or anything like it, we are just refreshing twice when the spec says we should refresh once). Will look into it, though.

@ojw28
Copy link
Contributor

ojw28 commented Sep 23, 2016

I don't see a reason to reload the media playlist

Aside from anything else (or what the spec says), this will be required for seeking in the live window. We should IMO be prioritizing doing this (i.e. moving the playlist refresh logic up to HlsMediaSource, making it periodic and exposing the live window).

@jonasevcik
Copy link

@AquilesCanta

has nothing to do with the playback position. In other words, refreshing the playlist does not have anything to do with playback position.

It's related to buffering position. I oversaw retryInMs part, which wasn't present in earlier versions and might caused trouble. Now it's alright. Nevertheless, @ojw28 is right, periodical refreshing of the playlist is vital when you want to implement correct seeking in live window or live events (I know that seeking in a live window or live events is not supported now). Now, you will get the information updated only when you reach the last chunk. So it may not be written in the spec, but makes sense in terms of not seeking out of the range of the live window or allowing a user to seek into gradually growing end of a live event.

This is suggesting we increase the refresh interval, not decrease it, when we finally get a different playlist. I assume

Correct.

@hienandroid
Copy link

How to fix this problem ? Please help me, i see this problem in the release 2.0.0

@jonasevcik
Copy link

The trouble lies in HlsChunkSource in this loop:

for (int i = newMediaPlaylist.segments.size() - 1; i >= 0; i--) {
      offsetToLiveInstantSecs -= newMediaPlaylist.segments.get(i).durationSecs;
      if (offsetToLiveInstantSecs < 0) { //trouble maker
        return newMediaPlaylist.mediaSequence + i;
      }
}

This playlist is specific, because it contains only 3 chunks. Calculation of offsetToLiveInstantSecs is not accurate, so we end up with a few spare seconds, unable to meet the condition offsetToLiveInstantSecs < 0 (because of the short playlist). Solution is either modify this condition, or provide one more condition in the beginning of this method:

    HlsMediaPlaylist oldMediaPlaylist = variantPlaylists[oldVariantIndex];
    HlsMediaPlaylist newMediaPlaylist = variantPlaylists[newVariantIndex];

    if (oldMediaPlaylist.mediaSequence == newMediaPlaylist.mediaSequence) {
      return previousChunkIndex + 1;
    }

This seems to be working for me. Weird, this was working ok in v1.

@AquilesCanta
Copy link
Contributor

if (oldMediaPlaylist.mediaSequence == newMediaPlaylist.mediaSequence) {

I think this condition is not ideal, as one of the media playlist might have been refreshed at a different moment, meaning that there is a small offset that breaks the condition (even if sequence numbers are aligned).

Also, due to splicing, this

return previousChunkIndex + 1;

should probably be

return previousChunkIndex;

If your media playlist contain the EXT-X-PROGRAM-DATE-TIME tag, we will use that for adaptation in the future and that should be the definitive solution.

Something that changed that seems to be causing some trouble is that we stopped considering sequence number alignment when adapting. Which is not a bad idea, in general, because the spec specifically states that it should not be assumed true when adapting. If you know your contents include aligned sequence numbers, you can give it a try and let me know the results.

@ishantsagar
Copy link

ishantsagar commented Sep 29, 2016

@jonasevcik I tried building from your forked repo as you mentioned above, the problem is still there. Any suggestions, I am facing the same issue with live HLS url's.

@AquilesCanta
Copy link
Contributor

We are going to try to be more conservative in out HLS implementation to minimize the occurrences of this exception. I will use this issue to track this. An enhancement will be pushed soon, around next week.

@ishantsagar
Copy link

@AquilesCanta Thanks for the update, that will be very helpful for us.

@tprochazka
Copy link

I have experience with this issue on r2.0.2 too.

1 similar comment
@gazeing
Copy link

gazeing commented Oct 9, 2016

I have experience with this issue on r2.0.2 too.

@ishantsagar
Copy link

@AquilesCanta Yes, the issue still remains in r2.0.2

@AquilesCanta
Copy link
Contributor

Guys, a commit message will appear in the thread when something is done about this. We will probably push a temporary tentative fix soon. This is being worked on.

ojw28 pushed a commit that referenced this issue Oct 14, 2016
@crossle
Copy link

crossle commented Nov 1, 2016

still remains in the latest commit

@crossle
Copy link

crossle commented Nov 8, 2016

I face the problem only download ts slow network sometimes, i think the player should not throw this Exception, should continue buffer the latest mediaSequence ts

@adnanutayim
Copy link

adnanutayim commented Jan 4, 2017

Hi There!
I am using the latest version of JWPlayer on Android and getting interrupted by BLWEs whenever I am running on a slow connection, which is forcing the app to crash.
From what I can understand, there's no way I can get the ExoPlayer instance out of the JWplayer so I can't handle the exception myself.
Is there a know walkaround for this issue?

ojw28 pushed a commit that referenced this issue Jan 24, 2017
This CL shows a de facto way to solve BLWEs until an in-player
solution is implemented.

Issue:#1782

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=145265895
@ojw28 ojw28 added the bug label Jan 30, 2017
@ojw28
Copy link
Contributor

ojw28 commented Jan 30, 2017

@AquilesCanta - Can we close this as fixed in 2.2.0?
@adnanutayim - Any JWPlayer issues should be reported to JWPlayer. We have no control over what version of ExoPlayer they're using and of any local modifications they make, so cannot provide direct support.

@AquilesCanta
Copy link
Contributor

This issue should remain open to track a default player behavior on BLWE.

An update: We have done some work to fix spurious errors actually caused by falling behind the live window. I am not sure those were affecting you guys, but still. The demoplayer now reinitializes the media source when a BLWE is thrown(d303db9). For now, this is what you should do when you get this behavior. Have a look at the demo app to have a guide. Let us know if you have any feedback.

@lazarvgd
Copy link

Hi, I have tried this solution, but for me this doesn't solve the issue. For simple use cases this error still occurs even if I reinitialize player. Is there any better workaround or solution for this issue?
Please bare with me, I am junior, so maybe I am omitting something.
Thanks

@binhbt
Copy link

binhbt commented Feb 22, 2017

I fixed this bug by retry play hls streaming at onError. This issue will be never closed because it will occur when network not stable. Problem is streaming source not on player. BR

@lazarvgd
Copy link

lazarvgd commented Feb 22, 2017

Correct me if I am wrong, you have implemented ExoPlayer.EventListener and override method onPlayerError?
Thanks

EDIT:
@binhbt
Here you can find the code where I have tried this workaround.
Please help

@tungds
Copy link

tungds commented Nov 20, 2017

Hi,
I'm using v1 - r1.5.16. And I get same problem on live. After debug on HlsChunkSource, I found some segment lost, so "NextchunkMediaSequence" less than "mediaPlaylist.mediaSequence".
My server using wowza and config window length is 10s with 3 segments. Thus, I can't fix problem from suggestion in #1074.
This link test : http://118.107.85.32:1935/test/sctv14.smil/playlist.m3u8
How can I fix this problem?
Thanks!

@ojw28
Copy link
Contributor

ojw28 commented Nov 20, 2017

  1. Use ExoPlayer V2.
  2. Use a server that provides a live window of adequate length.

@tungds
Copy link

tungds commented Nov 20, 2017

Thanks for reply,
I used Exoplayer V2 but I got another error is "response 403" while V1 still play if i skip fatal error.

@ojw28
Copy link
Contributor

ojw28 commented Nov 20, 2017

That error is unrelated to this issue.

@google google locked and limited conversation to collaborators Dec 9, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests