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

DashManifest playback results in IndexOutOfBoundsException #1329

Closed
1 task
JonWatson opened this issue Apr 29, 2024 · 4 comments
Closed
1 task

DashManifest playback results in IndexOutOfBoundsException #1329

JonWatson opened this issue Apr 29, 2024 · 4 comments
Assignees
Labels

Comments

@JonWatson
Copy link

JonWatson commented Apr 29, 2024

Version

Media3 1.2.1

More version details

No response

Devices that reproduce the issue

Bravia 4K GB(and other Bravia TVs) - Android versions 9-12
Hopper Plus - Android 11
Various other smart TVs - Android version 9-12
Google Chromecast TV - Android 12
Galaxy S20 FE 5G - Android 13

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

No response

Reproduction steps

Cannot reproduce, crash logs in Crashlytics

Expected result

Expect to play Dash manifest without crashes, even if there is an error

Actual result

Dash playback crashes on some devices

Fatal Exception: java.lang.IndexOutOfBoundsException: Index: 12, Size: 9
at java.util.ArrayList.get(ArrayList.java:437)
at androidx.media3.exoplayer.dash.manifest.DashManifest.getPeriod(DashManifest.java:128)
at androidx.media3.exoplayer.dash.DashMediaPeriod.(DashMediaPeriod.java:158)
at androidx.media3.exoplayer.dash.DashMediaSource.createPeriod(DashMediaSource.java:609)
at androidx.media3.exoplayer.source.MaskingMediaPeriod.createPeriod(MaskingMediaPeriod.java:131)
at androidx.media3.exoplayer.source.MaskingMediaSource.onChildSourceInfoRefreshed(MaskingMediaSource.java:213)
at androidx.media3.exoplayer.source.WrappingMediaSource.onChildSourceInfoRefreshed(WrappingMediaSource.java:154)
at androidx.media3.exoplayer.source.WrappingMediaSource.onChildSourceInfoRefreshed(WrappingMediaSource.java:49)
at androidx.media3.exoplayer.source.CompositeMediaSource.lambda$prepareChildSource$0(CompositeMediaSource.java:117)
at androidx.media3.exoplayer.source.BaseMediaSource.refreshSourceInfo(BaseMediaSource.java:90)
at androidx.media3.exoplayer.dash.DashMediaSource.processManifest(DashMediaSource.java:971)
at androidx.media3.exoplayer.dash.DashMediaSource.onUtcTimestampResolutionError(DashMediaSource.java:905)
at androidx.media3.exoplayer.dash.DashMediaSource.access$600(DashMediaSource.java:100)
at androidx.media3.exoplayer.dash.DashMediaSource$1.onInitializationFailed(DashMediaSource.java:892)
at androidx.media3.exoplayer.util.SntpClient$NtpTimeCallback.onLoadError(SntpClient.java:344)
at androidx.media3.exoplayer.upstream.Loader$LoadTask.handleMessage(Loader.java:494)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.os.HandlerThread.run(HandlerThread.java:67)

Media

DRM protected private media

Bug Report

@tonihei
Copy link
Collaborator

tonihei commented May 13, 2024

We fixed google/ExoPlayer#10838 in Media3 1.2.0, which looks very similar. So just to double-check - you are seeing this on version Media3 1.2.1?

@tonihei
Copy link
Collaborator

tonihei commented May 16, 2024

I found the likely reason for this issue that still exists even after the linked bug was fixed. The linked issue only fixed it for immediate player.prepare() calls after an exception. But if the new playback attempt happens at a later point, this problem can still happen.

copybara-service bot pushed a commit that referenced this issue May 17, 2024
This case is most likely to happen when re-preparing a multi-period
live stream after an error. The live timeline can easily move on to
new periods in the meantime, creating this type of update.

The behavior before this change has two bugs:
 - The player resolves the new start position to a subsequent period
   that existed in the old timeline, or ends playback if that cannot
   be found. The more useful behavior is to restart playback in the
   same live item if it still exists.
-  MaskingMediaSource creates a pending MaskingMediaPeriod using the
   old timeline and then attempts to create the real period from the
   updated source. This fails because MediaSource.createPeriod is
   called with a periodUid that does no longer exist at this point.
   We already have logic to not override the start position and need
   to extend this to also not prepare the real source.

Issue: #1329
PiperOrigin-RevId: 634833030
copybara-service bot pushed a commit that referenced this issue May 17, 2024
This is a fix for the fix in 319854d. The original fix did
not reset the firstPeriodId to avoid any id clashes with future
updates. This however only works under the assumption that the
next manifest load at the next call to prepare() is exactly the
same as the current manifest. This is not true unless the call
happens very quickly (and may fail even then). Instead we should
keep the existing manifest directly as a reference so we can use
it to find the number of removed periods when we get a new manifest
at the next call to prepare().

Issue: #1329
PiperOrigin-RevId: 634853524
@JonWatson
Copy link
Author

Hi @tonihei , sorry for the late response but yes we are on 1.2.1.

I see you found a new possible cause, thank you for looking into this!

@tonihei
Copy link
Collaborator

tonihei commented May 21, 2024

The commits above should this the issue I believe (will be released with 1.4.0-alpha02). If you are seeing it again after this release, please let us know.

@tonihei tonihei closed this as completed May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants