This is more consistent with the other MediaItem inner classes which are
all Configurations.
The old class and fields are left deprecated for backwards
compatibility.
MediaItem.Builder#setClippingProperties is directly renamed (without
deprecation) because it only exists on the dev-v2 branch and hasn't
been included in a numbered ExoPlayer release.
PiperOrigin-RevId: 399471414
Before releasing r2.15.0, we had a regression that crashed
PlaybackStatsListener. A change in the AnalyticsCollector made
it to send an additional AnalyticsListener.onEvents() callback after
calling Player.release() and AnalyticsListener.onEvents() appeared
to arrive with event times that were not monotonically increasing.
The AnalyticsListener.onEvents() callback that contained
AnalyticsListener.EVENT_PLAYER_RELEASED was called with a timestamp that
was smaller than event times of previously AnalyticsListener.onEvents()
calls.
A first fix changed the order of events being forwarded to
AnalyticsListener. Upon calling Player.release(), the AnalyticsCollector
would call AnalyticsListener.onPlayerReleased() and its associated
AnalyticsListener.onEvents() on the same stack call. This fix maintained
that event times are monotonically increasing, but made
AnalyticsListener.onPlayerReleased() be called earlier.
This change:
- Further changes AnalyticsCollector to ensure that
AnalyticsListener.onPlayerReleased() and its related
AnalyticsListener.onEvents() are the last callbacks to be called,
and the associated timestamp is bigger than previously reported
event times.
- Adds an instrumentation test to guard against the regression.
PiperOrigin-RevId: 399437724
The fix for Issue: #8776 was to release and null-out dummySurface if
it doesn't match the security level of the decoder. But it's possible
that this.surface is already set to this.dummySurface, in which case we
must also null out this.surface otherwise we will later try and re-use
the old, released DummySurface instance.
This logic already exists in MCVR#onReset, so I pulled it into a
releaseDummySurface() helper function.
Issue: #9476
#minor-release
PiperOrigin-RevId: 399420476
For Automotive devices, surround encodings can be supported via
the passthrough path. Therefore, include automotive in the allowed
device types in the isDirectPlaybackSupported checks. The automotive
system feature is checked, rather then UI_MODE_TYPE_CAR, because
the UI_MODE_TYPE_CAR can be force enabled via
android.app.UiModeManager.enableCarMode(), whereas FEATURE_AUTOMOTIVE
cannot be forced.
This aligns with other MediaItem.FooConfiguration class names and also
more clearly represents that this class encapsulates information used
for local playback that is lost when serializing MediaItem between
processes.
The old class and fields are kept (deprecated) for backwards
compatibility.
PiperOrigin-RevId: 398742708
- If DownloadService is configured to run as a foreground service,
it will remain started and in the foreground when downloads are
waiting for requirements to be met, with a suitable "waiting for
XYZ" message in the notification. This is necessary because new
foreground service restrictions in Android 12 prevent to service
from being restarted from the background.
- Cases where requirements are not supported by the Scheduler will
be handled in the same way, even on earlier versions of Android.
So will cases where a Scheduler is not provided.
- The Scheduler will still be used on earlier versions of Android
where possible.
Note: We could technically continue to use the old behavior on
Android 12 in cases where the containing application still has a
targetSdkVersion corresponding to Android 11 or earlier. However,
in practice, there seems to be little value in doing this.
PiperOrigin-RevId: 398720114
The MIME type is currently required to select a SubtitleDecoder
implementation in the TextRenderer. Future changes might remove this
requirement, so we pre-emptively mark the field as @Nullable.
The change in SingleSampleMediaSource ensures the track still maps to
the TextRenderer, otherwise it shows up as unmapped. Passing null MIME
type to MediaItem.Subtitle constructor now results in this from
EventLogger:
TextRenderer [
Group:0, adaptive_supported=N/A [
[ ] Track:0, id=null, mimeType=text/x-unknown, language=en, supported=NO_UNSUPPORTED_TYPE
]
]
PiperOrigin-RevId: 398010809
Both license and provisioning requests could be considered 'DRM
requests', and these headers are only sent on license requests, so
rename them to reflect that.
The old field remains deprecated for backwards compatibility.
PiperOrigin-RevId: 397980021
This change only calls setters if we need to override the existing value
(or more specifically, set a value that's absent).
PiperOrigin-RevId: 397979904
The type is already UUID so there's no need to duplicate that info in
the field name, and 'scheme' is a widely used term throughout both
ExoPlayer and android.os.MediaDrm documentation.
The old field remains deprecated for backwards compatibility.
The MediaItem.DrmConfiguration.Builder#setUuid method is renamed
directly (without deprecation) because it's not yet part of a released
ExoPlayer version.
PiperOrigin-RevId: 397961553
This takes advantage of the new MediaItem.LiveConfiguration.Builder
This change will always allocate a new LiveConfiguration.Builder and
LiveConfiguration, but preserves the behaviour of keeping the same
MediaItem instance if no values have changed.
PiperOrigin-RevId: 397961427
Issue: #9430
The current supported SDP (RFC2327) spec only allows for alpha-numeric
characters in the attribute-field. RFC4566 (section 9, token type) allowed
extra characters, and this CL adds the support.
PiperOrigin-RevId: 397301173
This is known to silently drop the value. This setter is now deprecated
in favour of `MediaItem.Builder#setDrmConfiguration(MediaItem.DrmConfiguration)`,
which requires a UUID in order to construct the `DrmConfiguration`
instance.
Issue: #9378 tracks correctly propagating the DRM info out of
`DownloadRequest#toMediaItem`.
PiperOrigin-RevId: 397291013
The previous implementation did the following (after skipping any ID3
headers at the start of the stream):
1. Skip forward byte-by-byte looking for a sync word (0xFFF)
2. Assume this indicates the start of an ADTS frame and read the size
a) If frameSize <= 6 immediately return false
3. Skip forward by frameSize and expect to find another ADTS sync word
(with no further scanning).
b) If we find one, great! Loop from step 2.
a) If we don't find one then assume the **last** sync word we found
wasn't actually one, so loop from step 1 starting one extra byte
into the stream. This means we're looking for a sync word we would
have skipped over in step 3.
The asymmetry here comes from the different handling of frameSize <= 6
(immediately return false) and frameSize being 'wrong because it doesn't
lead to another sync word' (scan the file again from the beginning for
alternative sync words).
With this change both these cases are handled symmetrically (always scan
for alternative sync words). Step 2a) becomes the same as 3b): Loop back
to the beginning of the stream with an incremented offset and scan for
another sync word.
#minor-release
PiperOrigin-RevId: 397285756
The deprecated `Player.addListener(EventListener)`
is moved out of Player into its subclasses
(CastPlayer and ExoPlayer).
This is unlikely to break users because:
- the method has been deprecated in the last major version
- the method is still present in the major implementations
If an users is affected, they can either:
- use ExoPlayer instead of Player
- (recommended) switch to Player.Listener.
Additionally update the threading guarantees that did not
reflect the current implementation.
PiperOrigin-RevId: 397272144
* Avoid ActivityManager log spam by only calling startForeground once,
and subsequently updating the notification via NotificationManager.
* Tweak demo app service to make it a tiny bit easier to swap the Scheduler.
PiperOrigin-RevId: 397179398
The second getScheduler() call violates the documentation of
the class, which states that getScheduler() is not called if
foregroundNotificationId if FOREGROUND_NOTIFICATION_ID_NONE.
Presumably implementing subclasses would return null, in which
case this didn't do any harm, but we should make sure the
implementation behaves as documented regardless.
PiperOrigin-RevId: 397167603
This is a pre-requisite step for merging SimpleExoPlayer into
ExoPlayer, because when StubExoPlayer extends ExoPlayer, it needs
a matching constructor.
PiperOrigin-RevId: 397065374
This was originally reported on #9390. There was a bug that when HLS
loads failed, the player would endlessly retry and never fail with a
player error.
This change fixes a bug in HlsSampleStreamWrapper.onPlaylistError()
which would return true for a playlist whose load encountered an error
but could not be excluded, whereas the method should return false.
Issue: #9390
#minor-release
PiperOrigin-RevId: 397045802
*** Original commit ***
Ensure MediaSourceFactory instances can be re-used
This fixes DefaultDrmSessionManager so it can be used by a new Player
instance (by nulling out its reference to the playback thread, which is
unique per-Player instance). This only works if the
DefaultDrmSessionManager is 'fully released' before being used by the
second Player instance, meaning that the reference count of the manager
and all its sessions is zero.
#exofixit
Issue: #9099
***
PiperOrigin-RevId: 396861138
Previously the released preacquired sessions would start their keepalive
timeout, and so no additional resources would be freed in time for the
manager to retry the session acquisition.
This change adds an additional purge of keepalive sessions *after* the
preacquired sessions are released, which fixes the problem.
#exofixit
#minor-release
PiperOrigin-RevId: 396613352
This is was reported in #9257 where the PlaybackStatsListener may try to
access an emtpy ArrayList.
Issue: #9257
#minor-release
#exofixit
PiperOrigin-RevId: 396329373
This is a candidate fix for #8906. As mentioned in that issue,
negative positions within windows might be (kind of) valid in
live streaming scenarios, where the window starts at some
non-zero position within the period. However, negative positions
within periods are definitely not valid. Neither are positions
that exceed the period duration.
There was already logic in ExoPlayerImplInternal to prevent a
resolved seek position from exceeding the period duration. This
fix adds the equivalent constraint for the start of the period.
It also moves the application of the constraints into Timeline.
This has the advantage that the constraints are applied as part
of state masking in ExoPlayerImpl.seekTo, removing any UI flicker
where the invalid seek position is temporarily visible.
Issue: #8906
PiperOrigin-RevId: 395917413
Instead of selecting the base URL initially or when a load error occurs, it is now selected when a chunk or initialization chunk is created. The selected base URL is then assigned to `RepresentationHolder.lastUsedBaseUrl` that is excluded in case of a load error. For a next chunk another base URL will be selected by using the `BaseUrlExclusionList`.
#minor-release #exo-fixit
PiperOrigin-RevId: 395721221
The new name is consistent with the corresponding parameters to `onVolumeChanged`, `setDeviceVolume` and `onDeviceVolumeChanged`.
PiperOrigin-RevId: 395705288
Since playlist support was added, it's possible for the player to "have media"
and be in STATE_IDLE. The STATE_IDLE documentation therefore became incorrect.
Issue: #8946
#exofixit
#minor-release
PiperOrigin-RevId: 395653716
This fixes DefaultDrmSessionManager so it can be used by a new Player
instance (by nulling out its reference to the playback thread, which is
unique per-Player instance). This only works if the
DefaultDrmSessionManager is 'fully released' before being used by the
second Player instance, meaning that the reference count of the manager
and all its sessions is zero.
#exofixit
#minor-release
Issue: #9099
PiperOrigin-RevId: 395490506
SubtitleExtractor is using IndexSeekMap with only one position to
indicate that its output is seekable. SubtitleExtractor is keeping Cues
in memory anyway so more seek points are not needed. SubtitleExtractor
gets notified about seek occurrence through seek() method. Inside that
method extractor saves seekTimeUs, and on the next call to read()
extractor outputs all cues that should be displayed at this time and
later.
PiperOrigin-RevId: 395477127
Some server will send partial URIs in the RTP-Info header, while the RTSP spec
requires absolute URLs.
Issue: #9346
#exofixit
PiperOrigin-RevId: 395452741
The C2 MP3 decoder produces an extra output buffer when draining after
end-of-stream is queued. This output buffer has a later timestamp than the last
queued input buffer so we need to calculate its timestamp to detect a stream
change in the correct position.
Before this CL we used the original input buffer timestamp as the largest
queued timestamp, which caused the stream change to be detected at the correct
position because the original input buffer timestamp was slightly larger than
the actual last output buffer timestamp. After this change we use exact
calculated timestamp as the largest queued timestamp. I manually verified
gapless continues to work on a device using the C2 MP3 decoder by comparing
output of the MP3 gapless and MP3 gapless stripped playlists in the demo app,
and that the last buffer timestamp now matches.
#exofixit
PiperOrigin-RevId: 395428928
- Fix focus when pausing and resuming
- Prevent repeated readout of the playback position when paused
#exofixit
#minor-release
Issue #9111
PiperOrigin-RevId: 395301765
The current detection logic checks that the two byte terminator starts
at an even position in the ID3 data, where-as it should check that it
starts at an even position relative to the start of the string.
#minor-release
#exofixit
Issue: #9087
PiperOrigin-RevId: 395274934
Simplifies the SubtitleExtractor implementation. Makes the extractor
more aligned with the Extractor interface documentation by removing
STATE_DECODING in which extractor was doing nothing in term of input
and output while returning RESULT_CONTINUE at the same time.
PiperOrigin-RevId: 395267468
C should only hold constants.
Also resolve the TODO in getErrorCodeForMediaDrmErrorCode(), and
annotate the deprecated methods with Error Prone's @InlineMe to
facilitate automated refactoring of callers.
PiperOrigin-RevId: 395244855
This typically happens if there's a discontinuity in the stream.
It's better to say we don't know, than it is to return a negative
position.
Issue: #8346
#exofixit
#minor-release
PiperOrigin-RevId: 395224088
This CL contains integration of the ExoplayerCuesDecoder and the
SubtitleExtractor with the player. The SubtitleExtractor is integrated
inside the DefaultMediaSourceFactory. The flag was added to the
state of the DefaultMediaSourceFactory to let user decide between the
ProgressiveMediaSource and the SingleSampleMediaSource as a source for
subtitles. Choosing the ProgressiveMediaSource will cause data to flow
through the SubtitleExtractor and eventually the ExoplayerCuesDecoder.
PiperOrigin-RevId: 394500305
Empty buffer with flag C.BUFFER_FLAG_END_OF_STREAM is send at the end
of the stream. Handling that flag properly is necessary to make the
ExoplayerCuesDecoder work properly with components like TextRenderer.
PiperOrigin-RevId: 394472642
Extractor was not calling endTracks() and seekMap() on the
extractorOutput which are required to finish the preparation.
At that point extractor does not support seeking.
PiperOrigin-RevId: 393994848
In the old version, the transcoder uses decoder.isEnded() alone as the criteria
to stop the encoding/muxing process. It's rectified to:
- On decoder ending, signal the encoder of EOS after writing all decoded frames to it.
- On encoder ending, write end track to muxer.
PiperOrigin-RevId: 393322114
Make this behaviour optional, so it can be disabled for
AnalyticsCollectorTest where we don't use
FakeExoMediaDrm.LicenseServer.
PiperOrigin-RevId: 393133721
This cl doesn't implement completely the API for
`ExoPlayerImpl` as
`onTrackSelectionParametersChanged` is not called.
The follow up cl adds `TrackSelectionParameters` in PlaybackInfo
to correctly propagate the change event and mask it.
Additionally `TrackSelectionParameters` is serialized as a Parcelable
for now. It is transitioned to bundleable in a follow up cl.
PiperOrigin-RevId: 392899918
- Android 12 will not allow our download service to be
restarted from the background when conditions that
allow downloads to continue are met. As an interim
(and possibly permanent) solution, we'll keep the
service in the foreground if there are unfinished
downloads that would continue if conditions were met.
- Keeping the service in the foreground requires a
foreground notification. Hence we need to be able to
generate a meaningful notification for this state.
PiperOrigin-RevId: 391969986
StyledPlayerControlView was checking whether the player is an ExoPlayer
instance to set the track selector. This means that, if apps were
wrapping an ExoPlayer in a ForwardingPlayer (to replace a
ControlDispatcher for example), the track selector wasn't set anymore.
#minor-release
PiperOrigin-RevId: 391776305
Samples are serialized using our custom CueEncoder. Information in
which format samples are encoded is needed by Renderer to decide which
decoder to use. Extractor receives Format object in the constructor and
prepares new Format object with sampleMimeType moved to codecs field
and new sampleMimeType set to "custom serialized exoplayer Cue".
PiperOrigin-RevId: 391739866
Most of those objects needs to be sent to MediaControler.
`TrackSelectior.Parameters` could have stayed Parcelable,
but it needs to be `Bundleable` as it inherit from
`TrackSelectionParameters` that is and needs to be
serializable anyway for the demo app.
As a result it has also been migrated to bundleable.
PiperOrigin-RevId: 391353293
SubtitleExtractor.release() releases the underlying SubtitleDecoder.
This change introduces the STATE_RELEASED state. The extractor
handles the new state in the read() and seek() methods.
PiperOrigin-RevId: 391046478
SubtitleExtractor is a component that extracts subtitle data taken from
ExtractorInput into samples. Samples are pushed into an ExtractorOutput
(usually SampleQueue). As a temporary solution SubtitleExtractor uses
SubtitleDecoder to extract Cues from input data.
PiperOrigin-RevId: 390319875
The prototype is built upon Transformer and took many references from
TransformerAudioRenderer.
Please take a look and we can discuss more details.
PiperOrigin-RevId: 390192487
The result is plumbed back to `MediaCodecRenderer` via a new
`DrmSession#requiresSecureDecoder` method.
This allows us to use the `MediaDrm#requiresSecureDecoder` method added
in Android 12:
https://developer.android.com/reference/android/media/MediaDrm#requiresSecureDecoder(java.lang.String)
This change also removes
`FrameworkMediaCrypto#forceAllowInsecureDecoderComponents`, replacing it
with equivalent logic in `FrameworkMediaDrm#requiresSecureDecoder`.
PiperOrigin-RevId: 389616038
Adding a CHANGE_FRAME_RATE_STRATEGY_ALWAYS strategy is
omitted from this commit, since adding it is more complicated
than just plumbing it through and leaving everything else
unchanged. Specifically, VideoFrameReleaseTimeHelper would
need updating to behave differently when such a strategy is
enabled. It currently calls setFrameRate in cases such as
pausing, seeking and re-buffering, on the assumption that
changes to the underlying display refresh rate will only be
made if they can be done seamlessly. For a mode in which
this will not be the case, it makes more sense to stick to
the content frame-rate when these events occur. It may also
make sense to only use explicit content frame-rate values,
and not those inferred from individual frame timestamps.
Finally, for adaptive content containing a mix of frame-rates,
it makes sense to use the maximal frame-rate across all
variants, and to avoid calling setFrameRate on switches from
one variant to another.
Applications that know the frame-rate of their content can
set ExoPlayer's strategy to CHANGE_FRAME_RATE_STRATEGY_OFF and
then use setFrameRate directly on the output surface. Note that
this is likely to be a better option for apps than anything we
could implement in ExoPlayer, because the application layer
most likely knows the frame-rate of the content earlier than
ExoPlayer does (e.g., to perform the disruptive mode switch
at the same time as an activity transition).
Adding CHANGE_FRAME_RATE_STRATEGY_ALWAYS will be deferred
until there's clear demand for it. In the meantime, we'll
recommend the alternative approach above.
PiperOrigin-RevId: 389610965
This CL moves SubtitleDecoder and all its dependencies
to common in order to enable using it in extractor
module while implementing SubtitleExtractor.
PiperOrigin-RevId: 388979021
This CL introduces two classes:
* CueEncoder - encodes list of Cue object into byte array.
* CueDecoder - decodes byte array into list of Cue objects.
This two classes are necessary in order to push Cues through SampleQueue. This classes are meant to be used by subtitle Extractor.
PiperOrigin-RevId: 388932088
These API levels have both been finalized. We're also calling methods
from these API levels directly, which may not exist if a device is
running a non-finalized R or S release.
PiperOrigin-RevId: 388903410
Issue: #9254
#minor-release
We used to allow only alphanumerical characters in session id. The spec also
allows "$", "-", "_", ".", "+" (RFC2326 Sections 3.4 and 15.1).
PiperOrigin-RevId: 388873742
This change removes ERROR_CODE_IO_NETWORK_UNAVAILABLE,
ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED, and ERROR_CODE_IO_DNS_FAILED
in favor of keeping only ERROR_CODE_IO_NETWORK_CONNECTION_FAILED.
PiperOrigin-RevId: 388715972
- Fix use of getTimestampOffsetUs in TsExtractor where
getFirstSampleTimestampUs should have been used.
- Don't reset TimestampAdjuster if it's in no-offset mode.
- Improve comment clarity
#minor-release
PiperOrigin-RevId: 388682711
For audio-only playlists, when formats are communicated to the app with
AnalyticsListener.onDownstreamFormatChanged(), the passed MediaLoadData
do not indicate this is an audio track and therefore the
PlaybackStatsListener cannot derive audio format-related information.
This change sets the main SampleStreamWrappers track type to AUDIO, if
the master playlist contains only audio variants.
Issue: #9175
#minor-release
PiperOrigin-RevId: 388676060
The AnalyticsCollector releases listeners lazily so that listener
callbacks triggered on the application looper after
SimpleExoPlayer.release() are still handled. The change in ListenerSet
to post the onEvents callback on the front of the application looper
changed (correctly) how onEvents are propagated, however this made
the AnalyticsCollector deliver onEvents with out-of-order EventTimes.
This change fixes AnalyticsCollector to trigger onPlayerReleased() and
the matching onEvents() event in the correct order.
#minor-release
PiperOrigin-RevId: 388668739
This change aligns all the names for classes that are 'holders of static
methods' to be `ApiNN`. Classes that hold state are named meaningfully
based on that state.
PiperOrigin-RevId: 388641064
This CL addresses the github issue [#8946](https://github.com/google/ExoPlayer/issues/8964). That issue requests support for `font-size` CSS property in WebVTT subtitle format. This CL:
* Adds support for `font-size` property by extending capabilities of WebVTT `CssParser`. Implementation of `font-size` property value parsing is based on the one in `TtmlDecoder`.
* Adds unit test along with test file containing WebVTT subtitles with all currently supported `font-size` units.
#minor-release
PiperOrigin-RevId: 388423859
- Use timestampOffsetUs == C.TIME_UNSET directly as the way of
determining whether the adjuster has determined the offset,
rather than relying on lastSampleTimestampUs checks for this.
- Remove comment referring to lastSampleTimestampUs as holding
the "adjusted PTS". Its value may not have originated from a PTS
timestamp. It's also confusing to refer to it as "adjusted"
given timestampOffsetUs has not been applied to it.
- Fix PassthroughSectionPayloadReader to make sure it'll never
output a sample with an unset timestamp.
#minor-release
PiperOrigin-RevId: 388226180
Prior to this change, an initalized TimestampAdjuster that's then
reset with DO_NOT_OFFSET would incorrectly continue to apply the
offset.
Also add a test case for this issue, and for some other simple use
cases.
#minor-release
PiperOrigin-RevId: 388182645
DefaultHttpDataSource and OkHttpDataSource can share the same error code
assigning logic.
Fixes CronetDataSource's handling of closed connection.
PiperOrigin-RevId: 387791679
The dokka javadoc generation tool complains when parameter names don't match between a method and its override. This change updates occurrences where there is currently a mismatch.
PiperOrigin-RevId: 387367509
The dokka javadoc generation tool complains when parameter names don't match between a method and its override. This change updates occurrences where there is currently a mismatch.
Notable renamings that might be controversial:
- `onPlaybackStateChanged(int state)` to `onPlaybackStateChanged(int playbackState)` affected a lot of lines but seems more consistent with other '-Changed' methods.
- `handleMessage(int messageType, Object payload)` to `handleMessage(int messageType, Object message)`
- `ExtractorInput` and `DataSource` inherit `DataReader` which had `read(byte[] target, ...`, while data sources normally called the first parameter `buffer`. I have standardized these all to use `buffer` even though it looks out of place in the `ExtractorInput` interface (which has more `read` methods with `target`).
PiperOrigin-RevId: 387290360
The documentation on ByteArrayOutputStream and GZIPOutputStream isn't
completely clear that an IOException will *never* happen, so
AssertionError seems a bit strong - but it seems very unlikely, so we
just use IllegalStateException instead.
#minor-release
PiperOrigin-RevId: 387169297
The inference is used when nesting DataSourceExceptions. It is removed because
nesting does not add additional value in surfacing the exceptions, and it is
better to assign an error code at the throw site (in the "leaf" or the bottom
most data source).
PiperOrigin-RevId: 386919118
* @Flags is not a TYPE_USE annotation, so should appear before any modifiers and after Javadocs.
(see go/java-style#s4.8.5-annotations)
This CL looks good? Just LGTM and Approve it!
This CL doesn’t look good? This is what you can do:
* Suggest a fix on the CL (go/how-to-suggest-fix).
* Revert this CL, by replying "REVERT: <provide reason>"
* File a bug under go/error-prone-bug for category ErrorProneStyle if the change looks generally problematic.
* Revert this CL and not get a CL that cleans up these paths in the future by
replying "BLOCKLIST: <provide reason>". This is not reversible! We recommend to
opt out the respective paths in your CL Robot configuration instead:
go/clrobot-opt-out.
This CL was generated by CL Robot - a tool that cleans up code findings
(go/clrobot). The affected code paths have been enabled for CL Robot in //depot/google3/java/com/google/android/libraries/media/METADATA which is reachable following include_presubmits from //depot/google3/third_party/java_src/android_libs/media/METADATA.
Anything wrong with the signup? File a bug at go/clrobot-bug.
#codehealth
PiperOrigin-RevId: 386849198
The reason this was not an IO error code is that before other
IOExceptions were classified, this catch would grab non-IO error
codes, like ParserException. Now that we are getting closer to
the final state, we can assume IOExceptions are ok to classify
as IO error codes (unlike, for example, ParserExceptions or
DrmSessionExceptions).
PiperOrigin-RevId: 386496752
Using all lower case RTSP headers is perfectly valid, as the spec mandates case
insensitively. However, some RTSP servers do not implement the RTSP spec
closely and does not recognize the lower case headers. This change aims
at using the header names as defined in the RTSP spec to maximize compatibility.
Issue: #9182
PiperOrigin-RevId: 386224566