This was reported for SSA/ASS in PR #8265, but it seems to me the
SubRip part of the Matroska spec is similarly loose, so this change
handles null-terminated strings in both.
PiperOrigin-RevId: 345452667
The `AudioProcessor` interface requires that no more input is queued after
queueing end of stream, but `DefaultAudioSink` did queue more input and the
implementation of `SonicAudioProcessor` actually relied on this to drain output
at the end of the stream.
Fix this behavior by getting `Sonic` output in `getOutput` and having
`DefaultAudioSink` only queue input to processors that are not draining.
Also add TODOs to clean up audio processor implementations where the code
handles interaction that doesn't conform to the interface.
PiperOrigin-RevId: 345406478
Previously `MediaPeriodQueue` would return null if an ad media URI hadn't
loaded yet, but this meant that the player could be stuck in `STATE_READY` if
an `AdsLoader` unexpectedly didn't provide an ad URI. Fix this behavior by
masking ad media periods. `MaskingMediaPeriod` no longer requires a
`MediaSource` to instantiate it.
This also fixes a specific case where playback gets stuck when using the IMA
extension with an empty ad where the IMA SDK unexpectedly doesn't notify the ad
group fetch error.
Issue: #8205
PiperOrigin-RevId: 344984824
- Retire YouTube streams. They're flaky (e.g., one of them has transformed into
an audio only stream!). There is also a desire for us to stop relying on special
non-expiring YouTube URLs.
- Reorganize the remaining streams.
PiperOrigin-RevId: 344421031
The ref'd issue was marked as a doucmentation candidate, but I think
the confusion likely arises from the lack of "next" and "previous" in
the method names. Our other UI components also support enabling each
button individually, so this also brings notifications in line with
those.
Issue: #6491
#exofixit
PiperOrigin-RevId: 344058969
RunnableFutureTask is not reusable. Trying to reuse it meant that a
failure in one doWork() call would cause subsequent download() calls
to (a) not block until the runnable has finished executing (does not
apply when using a direct executor), and (b) throw the same failure
as thrown from the first doWork() call.
This could cause #8078 if the initial failure occurred before the
content length was resolved. Retries are not blocked on their work
completing due to (a), and the download would be marked as failed due
to (b). The work itself could then resolve the content length, which
causes the stack trace in this issue.
Issue: #8078
PiperOrigin-RevId: 343498252
The demo app has two states for downloads, as per DownloadTracker.isDownloaded.
It's either "downloaded or downloading" (isDownloaded returns true, and the UI
shows a blue tick) or it's "not downloaded or failed (isDownloaded returns
false, and the UI does not show a blue tick).
toggleDownload is out of sync in that it treates "failed" as belonging to the
first state rather than the second. This means tapping on the grey tick in the
UI in this case appears to be a no-op (tapping it again will make something
happen).
This change aligns things by making toggleDownload re-download in the case a
previous download failed. In the future we could consider having three states,
so failed downloads could be disambiguated properly. Unclear whether it's a
good complexity/benefit trade-off for the demo app though!
#minor-release
PiperOrigin-RevId: 343464364
When a stream has duplicate timestamps we currently discard to
the last sample with the specified discardTo timestamp, but
it should be the first one to adhere to the method doc and the
intended usage.
#minor-release
PiperOrigin-RevId: 343458870
Background:
1. When the player has multiple audio renderers, by default they share a
single AudioSink.
2. When any new renderer is enabled, all disabled renderers are reset
prior to the new renderer being enabled. This is to give them a chance
to free up resources in case the renderer being enabled needs them. These
reset calls are expected to be no-ops for renderers that have never been
enabled.
The issue:
The problematic case arises when there are two audio renderers and a third
renderer (e.g., text) is being enabled. In this case, the disabled audio
renderer's reset call ends up resetting the AudioSink that's shared with the
enabled audio renderer. The enabled audio renderer is then unable to make
progress, causing playback to freeze.
This is a minimal fix that directly prevents the mentioned issue. There are
multiple follow-ups that would probably make sense:
1. Having ExoPlayerImplInternal track which renderers need to be reset, and
only resetting those renderers rather than all that are disabled. This
seems like a good thing to do regardless, rather than relying on those
calls being no-ops.
2. If we want to continue sharing AudioSink, we need to formalize this much
better and make sure we have good test coverage. Messages like
MSG_SET_VOLUME are also delivered to the AudioSink multiple times via
each of the renderers, which works currently because DefaultAudioSink
no-ops all but the first call in each case. This is pretty fragile though!
Issue: #8203
PiperOrigin-RevId: 343296081
This is inline with other show-toast-on-error cases in this method, and avoids
leaving the user on a completely black screen.
Note that the maybeRequestReadExternalStoragePermission is an exception because
it's not actually an error case.
#minor-release
PiperOrigin-RevId: 343264869
ExoPlayer's traditional HLS preparation works by loading a chunk from each track
group, and then tries to use the sample information plus the master playlist
information to generate the preparation's resulting TrackGroups.
There are 3 possible scenarios:
- Supported case: Each variant has a single codec string per track type. We can
assign each track the codec string which matches the loaded sample's type.
- Supported case: Each variant has more than one codec string, but each track
group has a single track. This is the case when different languages use
different codecs. In this case, we can assign whichever codec matches the
loaded sample's mime type.
- Unsupported case: Each variant has more than one codec string, and track
groups contain more than one track. We are not able to safely map tracks to
codec strings because that would require loading a chunk from each track
(which would considerably delay preparation).
Broken in:
4783c329cc
PiperOrigin-RevId: 343072201
This ensures the buffer is not full when the `DefaultLoadControl` determines
whether we should continue loading and thus prevents a false warning about
not having enough memory left.
PiperOrigin-RevId: 342616623