-
Notifications
You must be signed in to change notification settings - Fork 458
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
Startup failure/freeze when additional discontinuity tags in alternate audio/text tracks #323
Comments
I can repro this with 2.17.1 where startup hangs in May I ask you to try this out with a recent release of ExoPlayer? Either with the demo app or your own app? I did repro in the demo app with 2.17.1 and then checked out tag r2.18.0. You can do the same with the most recent release if that's easier than upgrading your app:
I have applied these changes above for 2.17.1, 2.18.0 and tip of tree and I can repro on 2.17.1 only. |
I was able to test 2.18.5 and that did work when the additional I created an example here: https://storage.googleapis.com/mlbapp-streaming-resources/big_buck_bunny_disc/bunny_text.m3u8 This has a couple discontinuity tags about 2 min in to the text track and will start playing fine - but will not allow playback at any point past the text's discontinuity tags. I tested this on 2.18.5 (without the chunkless preparation change) |
Thanks for the stream. I can repro this with the current version as you describe. |
The stream that you shared above, includes subtitle renditions that have discontinuities that are not present in the video or audio renditions. When encountering such a discontinuity, the player/timestamp adjuster waits until the adjustment in the main track to be adjusted. If this does not happen, the player falls into the buffering state that you observe and is stalling playback. I can repro this behavior. That's not much news for you, it's what you mentioned above. This behavior is in place in ExoPlayer since a good while and worked in the sense that we never got complaints that I am aware of. I was wondering why because it obviously stalls playback and we would have people tell us. I think the reason for not hearing such complaints is that the HLS Authoring Guide from Apple who owns the spec says:
I understand that you created such a stream for testing purposes by adding the discontinuities in the text rendition. I haven't tested on Apple devices or with other players but it seems to me that the implementation in ExoPlayer is following the authoring specification. Given this I was wondering what the reason for having such streams are. Personally I wouldn't go beyond the authoring guidelines from Apple when producing content because it may not work with some players and player makers may point to that spec regarding this. Can you give me some context on why you are attempting to create such content? |
This is from our media technology team:
|
Thanks for the context. In general I think its a good strategy to stick to the authoring guidelines for us as a player. This allows players to make changes in the future and not to be locked into something specific to partners content or suddenly not supporting it anymore with an update in the future. However, I also think that if this is a function of the exceptional network conditions described above, playback shouldn't silently stall without the player or app being aware of it. If the player would throw an exception in this case, the app can decide to restart playback from the live edge and continue playback that way. Hence what we can do is to throw an Exception when playback stalls for too long. The resulting playback exception for live stream can then be caught and the live stream can be restarted. |
I agree with that solution - an error would be much more helpful to at least get an understanding of what is wrong allow that to report the error so we can react to the failure. |
Thanks for the feedback. We look into this and update the issue here when a fix lands. It's planned to include this in the next release. Thanks again for reporting! |
Add `HlsMediaSource.Factory.setTimestampAdjusterInitializationTimeoutMs(long)` to set the timeout for the loading thread to wait for the `TimestampAdjuster` to initialize. If the initialization doesn't complete before the timeout, a `PlaybackException` is thrown to avoid the playback endless stalling. The timeout is set to zero by default. This can avoid HLS playback endlessly stalls when manifest has missing discontinuities. According to the HLS spec, all variants and renditions have discontinuities at the same points in time. If not, the one with discontinuities will have a new `TimestampAdjuster` not shared by the others. When the loading thread of that variant is waiting for the other threads to initialize the timestamp and hits the timeout, the playback will stall. Issue: androidx/media#323 #minor-release PiperOrigin-RevId: 539108886
Add `HlsMediaSource.Factory.setTimestampAdjusterInitializationTimeoutMs(long)` to set the timeout for the loading thread to wait for the `TimestampAdjuster` to initialize. If the initialization doesn't complete before the timeout, a `PlaybackException` is thrown to avoid the playback endless stalling. The timeout is set to zero by default. This can avoid HLS playback endlessly stalls when manifest has missing discontinuities. According to the HLS spec, all variants and renditions have discontinuities at the same points in time. If not, the one with discontinuities will have a new `TimestampAdjuster` not shared by the others. When the loading thread of that variant is waiting for the other threads to initialize the timestamp and hits the timeout, the playback will stall. Issue: #323 #minor-release PiperOrigin-RevId: 539108886
Add `HlsMediaSource.Factory.setTimestampAdjusterInitializationTimeoutMs(long)` to set the timeout for the loading thread to wait for the `TimestampAdjuster` to initialize. If the initialization doesn't complete before the timeout, a `PlaybackException` is thrown to avoid the playback endless stalling. The timeout is set to zero by default. This can avoid HLS playback endlessly stalls when manifest has missing discontinuities. According to the HLS spec, all variants and renditions have discontinuities at the same points in time. If not, the one with discontinuities will have a new `TimestampAdjuster` not shared by the others. When the loading thread of that variant is waiting for the other threads to initialize the timestamp and hits the timeout, the playback will stall. Issue: #323 #minor-release PiperOrigin-RevId: 539108886 (cherry picked from commit db3e662)
Add `HlsMediaSource.Factory.setTimestampAdjusterInitializationTimeoutMs(long)` to set the timeout for the loading thread to wait for the `TimestampAdjuster` to initialize. If the initialization doesn't complete before the timeout, a `PlaybackException` is thrown to avoid the playback endless stalling. The timeout is set to zero by default. This can avoid HLS playback endlessly stalls when manifest has missing discontinuities. According to the HLS spec, all variants and renditions have discontinuities at the same points in time. If not, the one with discontinuities will have a new `TimestampAdjuster` not shared by the others. When the loading thread of that variant is waiting for the other threads to initialize the timestamp and hits the timeout, the playback will stall. Issue: androidx/media#323 #minor-release PiperOrigin-RevId: 539108886 (cherry picked from commit 4eb56cf)
@marcbaechinger this is related to an issue that has been on my plate for years now :-( google/ExoPlayer#8952 There are some live packagers in the wild that independently package segments from transcoded streams that can dropout (UDP streams, or just raw un-conditioned TS streams). They have a variety of methods that fall under the HLS "standard" but do not play to the guidelines (similar in the DASH world to meeting the ISO standard but falling short of the DASH-IF Guidelines). These produce fun things like:
Oliver and I went back and forth a lot on this, and I have come to his camp, these are media problems the player should not try to fix. That said, freezing playback (either stuck in ready or stuck in buffering) is not good either. We'll be pulling in the solution that @tof-tof put in for our version when this happens (retrying "fixes" the freeze, and allows logging the issue). Might be time to visit un-commenting this code as well: Line 1773 in d13a0f4
Perhaps with a settable threshold that defaults to infinite (effectively then the same behavior as the commented out code has). The issue is marked closed: google/ExoPlayer#7030 But I'm sure if I dig up the pro-bowl video from the issue it will still hang AndroidX (FWIW AvPlayer mostly just looses AV sync on these, an even worse behavior but at least one that is not blamed on the player) Love your thoughts on this? |
Still agreeing to this part. It really comes down to: how can we detect the problem and what the is the right reaction to it. Am I right in assuming that the code stayed commented because it was unclear how to automatically handle the error? (see google/ExoPlayer#7030 (comment)). If not, please remind me why we left it commented out as I can't seem to find the right comment trail for it.
Do you know a good reason to make the actual threshold configurable vs a simple on-off switch? If we leave it as a threshold configuration, it's unclear to other apps what value makes sense for the purpose. A simple boolean |
@tonihei IMO report it as an error (a specific Oliver was pushing for silent automatic recovery, so that is why it stalled as commented out code. Automatic recovery is tricky, especially if the issue occurs mid-segment. I experimented with it a bit and determined it would take recovery at the timestamp adjustment level, hence the relationship to this issue: google/ExoPlayer#8952 I have an asset still I can share (the Pro Bowl recording) that "plays" in Safari (but it looses A/V sync) but hangs in ExoPlayer
I think an on-off is fine, the simple threshold is enough time to exceed a buffering span (50 seconds for VOD, much less for live) as one of the worst manifestations of the issue is the player will stall in buffering mode forever (if timestamp mismatch between audio and video exceeds the buffer window). This is because of the way the value for Happy to work with a member of my team to clean this up to some release form if we can agree on a design, I think we should:
|
Given how much we need to reset in this case, it would probably involve setting the
Sounds good to me. Having a dedicated error type allows to identify this problem explicitly for manual retry if needed.
That's interesting in that a large tolerance only helps to detect 'stuck' cases and a lower tolerance would be closer to a correctness check that kicks in even if playback could recover itself. Am I right in saying that the current commented-out thresholds are actually better because they detect malformed media directly? As long as it's an opt-in for now, we can use the lower thresholds. If we get around to add an automatic recovery attempt, we can think about making the setting opt-out. |
Media3 Version
ExoPlayer 2.17.1
Devices that reproduce the issue
All devices
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
No
Reproduction steps
Configure the player to disallow chunkless startup:
setAllowChunklessPreparation(false)
Details
Media must contain a track that that has isMasterTimestampSource set to false during the preparation step and contains 1 or more additional
#EXT-X-DISCONTINUITY
tags before the first sample chunk.This scenario causes the
timestampAdjuster
provided for that discontinuity sequence to be provided for only to a single track. That HlsMediaChunk is unable to initialize thetimestampAdjuster
causing the call :timestampAdjuster.sharedInitializeOrWait(isMasterTimestampSource, startTimeUs);
to block loading until the timestampAdjuster initialization can be completed.Since no other tracks contain the same discontinuity sequence and will not be provided with the same
timestampAdjuster
as the waiting HlsMediaChunk's - loading will never complete.Expected result
Playback starts
Actual result
Playback is stuck in loading state
Media
https://storage.googleapis.com/mlbapp-streaming-resources/big_buck_bunny_disc/x36xhzz.m3u8
Bug Report
adb bugreport
to [email protected] after filing this issue.The text was updated successfully, but these errors were encountered: