Set KeepAliveMonitor to send a keep-alive message at half the timeout value, if provided, by the RTSP Setup response.
Issue: androidx/media#662
PiperOrigin-RevId: 570946237
This gets rid of the reliance on the decode only flag that is still
set on input buffers to the decoder if they are less than the start
time.
We still need to set and check the decode-only flag in SimpleDecoder
to ensure compatbility with custom decoders that use the flag while
it's not fully removed.
PiperOrigin-RevId: 570736692
The interface requires the implementation to return null if the
decode-only flag is set. So instead of setting the flag and returning
null, we can simply not call the method and assume it's null.
The only reason where this wouldn't work is if the metadata format
has keyframe-like logic and requires previous metadata to decode
the next one. This is not something we came across before and it seems
ignorable. If that feature is needed in the future, we should instead
add a method to MetadataDecoder to set the first output timestamp.
#minor-release
PiperOrigin-RevId: 570399838
In some cases, SimpleDecoder output needs to be skipped for rendering
because the decoder produces no data. This is one of the remaining
usages of BUFFER_FLAG_DECODE_ONLY at the moment and can be more
directly solved without using the flag. SimpleDecoder still needs to
check the flag though for backwards compatbility with custom decoders
while the flag is not completely removed.
PiperOrigin-RevId: 570345233
The library already maintains the subscribed controllers internally. This
change adds `MediaLibrarySession.getSubscribedControllers(mediaId)` to
access subscribed controllers for a given media ID.
To accept a subscription, `MediaLibraryService.Callback.onSubscribe` is
required to return `RESULT_SUCCESS`. So far, this isn't the case for the
default implementation of the library.
This change implements `Callback.onSubscribe` to conditionally
provide `RESULT_SUCCESS`. The default calls `Callback.onGetItem(mediaId)` to
assess the availability of the media item. If the app retruns `RESULT_SUCCESS`
with a browsable item, the subscription is accepted. If receiving a valid item
fails, the subscription is rejected.
Issue: androidx/media#561
PiperOrigin-RevId: 568925079
Before this change, media button events are routed from `onStartCommand`
of the `MediaSessionService` to the `MediaSessionCompat`, resolved by
the legacy library to a session command called on
`MediaSessionCompat.Callback` from where the command is delegated back
to the Media3 session.
With this change the keycode is resolved directly to a Media3 command
that is sent to the session through the media notification controller
of the session.
After this change, a playback or custom command sent to the session
from a notification, either as a pending intent (before API 33) or as
a legacy session command, look the same and the caller is the
media notification controller on all API levels.
PiperOrigin-RevId: 568224123
ExoPlayer will not fail playback if an RTSP server responds to the Options request with an unknown RTSP method request type. ExoPlayer will parse the response and just not call methods it does not know how to use.
Issue: androidx/media#613
PiperOrigin-RevId: 568152076
With this change, the notification controller that is connected by
`MediaNotificationManager`, is used as a proxy controller of the
System UI controller. An app can use the proxy at connection time
and during the lifetime of the session for configuration of the
platform session and the media notification on all API levels.
This includes using custom layout and available player and session
commands of the proxy to maintain the platform session (actions,
custom actions, session extras) and the `MediaNotification.Provider`.
The legacy System UI controller is hidden from the public API,
instead the app interacts with the Media3 proxy:
- System UI is hidden from `MediaSession.getConnectedControllers()`.
- Calls from System UI to methods of `MediaSession.Callback`/
`MediaLibrarySession.Callback` are mapped to the `ControllerInfo`
of the proxy controller.
- When `getControllerForCurrentRequest()` is called during an operation of
System UI the proxy `ControllerInfo` is returned.
PiperOrigin-RevId: 567606117
Removed `ExoPlayer.experimentalSetOffloadSchedulingEnabled` as scheduling will be enabled by default when offload is enabled for audio-only playback.
In addition, the `experimental` key word was taken out of the following
method signatures:
* `ExoPlayer.experimentalIsSleepingForOffload`
* `AudioOffloadListener.onExperimentalSleepingForOffloadChanged`
* `AudioOffloadListener.onExperimentalOffloadedPlayback`
PiperOrigin-RevId: 565035289
The class currently disallows offsets of periods in their windows
except for the very first window. This is not necessary because
we can use TimeOffsetMediaPeriod to eliminate the offset if needed.
This makes the class more useful for many use cases, in particular
for using it with ClippingMediaSource.
Issue: google/ExoPlayer#11226
PiperOrigin-RevId: 563702120
This callback asks to correct the media time in a composition, but doesn't
provide the MediaPeriodId as the necessary context to do this.
PiperOrigin-RevId: 563699344
This change avoids using a framework API that is deprecated since
API 31 and works around difficulties with this deprecated API on
devices from some manufacturers on API 33/34.
Manually tested with BT headphone connected to:
- Samsung SM-G920F (API 24)
- Pixel (API 28)
- Samsung SM-A515W (API 33)
- Pixel 6 Pro (API 33)
(verified manually with devices and adb output of dumpsys)
Issue: androidx/media#167
PiperOrigin-RevId: 562890206
Created new method `AudioSink#setOffloadDelayPadding` that will set delay and padding data onto an `AudioTrack` using `AudioTrack#setOffloadDelayPadding`. This feature adds support for offloaded, gapless Opus playback as the content requires the capability to set padding data post-`AudioSink#configure`.
PiperOrigin-RevId: 562518193
Currently, we only support sending Common Media Client Data (CMCD) data through custom HTTP request headers, added capability to configure and transmit it as HTTP query parameters.
PiperOrigin-RevId: 561591246
If a RtspMediaSource is used within a combining source like MergingMediaSource, then it could become stuck in a loop of calling continueLoading when the source has not actually started loading yet.
Issue: androidx/media#577
PiperOrigin-RevId: 561322900
The period index was calculated relative to the contentTimeline
of the DAI stream, but then used with the full timeline of the
player. This means it currently only works when the stream is the
only or first item in the playlist.
Issue: androidx/media#571
PiperOrigin-RevId: 560023412
The first call to method `registerInputStream` doesn't block.
Later successive calls to the method blocks until the previous register call
finishes.
PiperOrigin-RevId: 559694490
This removes concurrent access from `rtspLoaderWrappers`. Previously
there was a race between the playback thread clearing & re-adding
entries to this list in `retryWithRtpTcp()`, and the loading thread
accessing the entries in `InternalListener.track()` (implemented from
`ExtractorOutput`).
This change means each `ExtractorOutputImpl` uses exactly one
`SampleQueue` for its one `TrackOutput`. When the `RtspLoaderWrapper`
instances are replaced in `retryWithRtpTcp()`, any stale instances will
only be able to access their own (also stale) `SampleQueue` instances
(vs before, where the stale `ExtractorOutput` could accidentally access
'new' `SampleQueue` instances via the `rtspLoaderWrappers` field).
As well as fixing a race condition in the prod code, this also de-flakes
`RtspPlaybackTest`.
#minor-release
PiperOrigin-RevId: 559130479
This picks up a fix to ensure Android Studio puts the `@OptIn`
annotation in the correct place:
https://issuetracker.google.com/251172715
This also introduces a transitive dependency from `media3-common` on
the Kotlin standard library, so this CL also includes some updates to
the dev guide to document how apps can avoid including this dep if
they want.
PiperOrigin-RevId: 558821673
When the foreground service type is set to `mediaPlayiback` this shouldn't
be required. However, some reports from users say that setting the
foreground service behavor fixes some problems on some devices. Setting
it explicitely with this change makes sure users don't have to do that
workaround themselves.
Issue: androidx/media#167
PiperOrigin-RevId: 557608577
This changes the default logic of shouldShowPlayButton to show a play
button while the playback is temporarily suppressed. This helps to
provide better UI feedback to the fact that playback stopped and
provides a quick way for users to override the suppression and attempt
to restart playback.
Some apps may want to keep the legacy behavior depending on their app's
needs. Hence, we also add a config parameter to set this behavior both
in MediaSession and our default UI components.
Issue: google/ExoPlayer#11213
PiperOrigin-RevId: 557129171
Modifies the `ChunkSource.getNextChunk(long, long, List, ChunkHolder)` method in the `ChunkSource` interface to `ChunkSource.getNextChunk(LoadingInfo, long, List, ChunkHolder)`.
LoadingInfo contains additional parameters, including `playbackRate` and `lastRebufferRealtimeMs` in addition to the existing `playbackPositionUs`. The additional parameters will allow us to pass these information to Common Media Client Data (CMCD) logging.
PiperOrigin-RevId: 555148768
Modifies the `SequenceableLoader.continueLoading(long)` method in the `SequenceableLoader` interface to `SequenceableLoader.continueLoading(LoadingInfo)`.
`LoadingInfo` contains additional parameters, including `playbackSpeed` and `lastRebufferRealtimeMs` in addition to the existing `playbackPositionUs`. The additional parameters will allow us to pass these information to Common Media Client Data (CMCD) logging.
By using the `LoadingInfo` object, we ensure future flexibility to add more fields without causing any breaking changes to the API.
PiperOrigin-RevId: 555123961
When hardware buttons are used to control the volume of the remote device, the call propagates to `MediaSessionCompat.setPlaybackToRemote(volumeProviderCompat)`. However, `volumeProviderCompat` was created incorrectly when the new device volume commands were present (COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS and COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS), i.e. with volumeControlType = `VOLUME_CONTROL_FIXED`. This resulted in `VolumeProviderCompat` which doesn't call `onSetVolumeTo` or `onAdjustVolume` and hence doesn't propagate the calls to the `Player`. Instead, it only worked with the deprecated commands which ensured the volumeControlType was `VOLUME_CONTROL_ABSOLUTE`.
This bug was introduced in c71e4bf1ff (1.0 media 3 release) when `PlayerWrapper`'s call to `createVolumeProviderCompat` was mostly rewritten to handle the new commands, but the two if-statements were not amended. Note: this change fixes the bug only for Android 11 and below. For 12 and above, there is a tracking bug for the regression that was introduced: https://issuetracker.google.com/issues/201546605http://Issue: androidx/media#554
#minor-release
PiperOrigin-RevId: 554966361
This fixes a bug with playing very short audio files, introduced by
fe710871aa
The existing code using floor integer division results in playback never
transitioning to `STATE_ENDED` because at the end of playback for the
short sample clip provided `currentPositionUs=189937`,
`outputSampleRate=16000` and `(189937 * 16000) / 1000000 = 3038.992`,
while `writtenFrames=3039`. This is fixed by using `Util.ceilDivide`
so we return `3039`, which means
`AudioTrackPositionTracker.hasPendingData()` returns `false` (since
`writtenFrames ==
durationUsToFrames(getCurrentPositionUs(/* sourceEnded= */ false))`).
#minor-release
Issue: androidx/media#538
PiperOrigin-RevId: 554481782
We currently only force the first frame if the frame timestamp is
greater than the stream *offset*.
This is wrong for two reasons:
1. The timestamp and the offset are not comparable and it should be
the stream start position.
2. The check should only be applied at stream transitions where we
need to make sure that a new first frame isn't rendered until we
passed the transition point.
We have to fix both issues together, because fixing just issue (1)
causes seeks to before the start position to no longer render the
frame (and playback will be stuck). A new test covers this case.
We also amend the stream transition test case to actually test what it
promises to test and add a test for prerolling samples at the
beginning, to ensure the first frame is still renderered.
Issue: androidx/media#291
PiperOrigin-RevId: 552858967
Fix short term reference picture list parsing. Before this change, `deltaPocS0`
was derived by adding one to the value of the syntax element
`delta_poc_s0_minus1`, but (maybe surprising) the specification actually says
that `DeltaPocS0[stRpsIdx][i]` should be assigned the negation
`-(delta_poc_s0_minus1[i] + 1)` on the first iteration, then that value added
to the previous value on previous iterations. See equations (7-67) to (7-70) in
the 2021-08 version of the H.265/HEVC specification.
Also read the number of long term reference pictures once rather than on every
loop iteration (subsection 7.3.2.2.1).
PiperOrigin-RevId: 551852999
Instead of `text/x-exoplayer-cues`, we will use `application/x-media3-cues`.
The prefix should be `application` not `text` since the encoded form is arbitrary bytes, not necessarily text. The name should not reference `exoplayer`, since the Media3 Extractors (which are not part of `exoplayer`) produce this format.
PiperOrigin-RevId: 550181852
Alters the OverlayShaderProgram implementation to support rotations, however we need to apply the transformations separately in order for them to work as expected so the matrix is removed from the interface in favour of explicit methods.
Adds a rotation test to ensure this ability doesn't regress
PiperOrigin-RevId: 549890847
Updated `ExoTrackSelection` to provide the most recent bitrate estimate, enabling the inclusion of measured throughput (mtp) as a CMCD-Request field in Common Media Client Data (CMCD) logging.
Additionally, made changes to the `checkArgument` methods in `CmcdLog` to prevent the use of default values in certain cases.
#minor-release
PiperOrigin-RevId: 549369529
*** Original commit ***
Rollback of b69b33206e
*** Original commit ***
Mark output sample as decode-only based on start time
We currently do the same check on the input timestamps and
expect the output timestamps to match. Some codecs produce
samples with modified timestamps and the logic is a lot safer
when the comparison with the start time is done on the output
side of the codec.
Issue: google/ExoPlayer#11000
***
***
PiperOrigin-RevId: 549019403
This ensures the DownloadService stays functional on Android 14
where defining this type is required. On Android 14 and above,
the app also needs to define the DATA_SYNC permission, which is
added to the demo app as well. In the future, this service type
will no longer be supported and DownloadService needs to be
rewritten with another background scheduling framework.
Issue: google/ExoPlayer#11239
PiperOrigin-RevId: 548994842
Add Ogg ID Header and Comment Header Pages to the Ogg encapsulated Opus for offload playback. This further matches the RFC 7845 spec and provides initialization data to decoders.
PiperOrigin-RevId: 548080222
This change also marks the buttons of the custom layout as
enabled/disabled according to available commands in the controller.
Accordingly, `CommandButton.Builder.setEnabled(boolean)` is deprecated
because the value is overridden by the library.
Issue: androidx/media#38
#minor-release
PiperOrigin-RevId: 547272588
Also parse the PCM encoding for lpcm in MP4, and update `MatroskaExtractor`
similarly.
Tested manually in the demo app using an MP4 with 24-bit big endian audio.
PiperOrigin-RevId: 546878505
This changes all MediaSources in our library to allow updates to
their MediaItems (if supported).
Issue: google/ExoPlayer#9978
Issue: androidx/media#33
PiperOrigin-RevId: 546808812
This is only needed for instrumentation tests and should not
be included in regular builds.
#minor-release
Issue: androidx/media#499
PiperOrigin-RevId: 545913113
This allows MediaSources to accept MediaItem updates after creation.
This CL adds the handling and plumbing logic in `ExoPlayerImpl`,
`ExoPlayerImplInternal`, `MediaSourceList` and `MaskingMediaSource`.
It also updates all forwarding/wrapping sources to forward these calls
to their wrapped instance.
The actual functionality is only added to `FakeMediaSource` instances in
tests so far.
PiperOrigin-RevId: 545450210
We introduced truncation to 32 chars in <unknown commit>
and included indent and offset in the calculation. I think this is
technically correct, but it causes problems with the content in
Issue: google/ExoPlayer#11019 and it doesn't seem a problem to only truncate actual
cue text (i.e. ignore offset and indent).
#minor-release
PiperOrigin-RevId: 544677965
Auto-resume playback when the removal of playback suppression due to unsuitable output is conveyed via change in playback suppression to Player.PLAYBACK_SUPPRESSION_REASON_NONE within a configurable timeout defaulting to 5 minutes.
PiperOrigin-RevId: 544411987
Instead of playing or pausing itself, the ExoPlayer implementation should only update the playback suppression reason as and when audio outputs are added or removed dynamically.
PiperOrigin-RevId: 544379033
*** Original commit ***
Mark output sample as decode-only based on start time
We currently do the same check on the input timestamps and
expect the output timestamps to match. Some codecs produce
samples with modified timestamps and the logic is a lot safer
when the comparison with the start time is done on the output
side of the codec.
Issue: google/ExoPlayer#11000
***
PiperOrigin-RevId: 543379665
This change uses this new method everywhere we currently `instanceof`
check an `Extractor` directly. This allows us to introduce
wrapping/delegating `Extractor` instances - because the `instanceof`
checks will continue to operate on the underlying instance.
HLS is a slightly different case, because it directly re-instantiates
`Extractor` instances, which is not compatible with an arbitrary
wrapping structure. Luckily the only `Extractor` instances that HLS
re-instantiates do not support muxed subtitles, so won't be wrapped
in the first place (although future changes might use the
delegating-`Extractor` pattern for other purposes, which might affect
HLS).
PiperOrigin-RevId: 542550928
Devices pre-API 33 are not able to comprehend the position reset that occurs by the HAL in offloaded gapless track transitions.
PiperOrigin-RevId: 542503662
Some events may arrive after the playlist is cleared (e.g. load
cancellation). In this case, the DefaultPlaybackSessionManager may
create a new session for the already removed item.
We already have checks in place that ignore events with old
windowSequenceNumbers, but these checks only work if the current
session is set (i.e. the playlist is non-empty). The fix is to add
the same check for empty playlists by keeping note of the last
removed window sequence number.
PiperOrigin-RevId: 541870812
FakeClock currently doesn't work well with Espresso and Compose UI
tests because view interactions in both frameworks intentionally idle
the main looper to handle pending UI effects. However, this also
advances playback progress even though we want to deterministically
trigger progress from the test itself.
To solve this problem, we can detect the idling Robolectric call and
postpone any further updates until we leave this state.
PiperOrigin-RevId: 541831050
Add a Wear OS specific implementation of 'Player.Listener' to help resolving the playback suppression due to unsuitable output by launching a system media output switcher dialog.
PiperOrigin-RevId: 541698125
The APIs /related fields for playback suppression due to unsuitable output should be renamed from '..SuppressPlaybackWhenNoSuitableOutputAvailable' to '..SuppressPlaybackOnUnsuitableOutput'
PiperOrigin-RevId: 540555715
The existing NullableType has been deprecated 5 years ago and causes
crashes in Kotlin apps because Kotlin doesn't recognize this annotation
as a nullable type annotation.
While we can't align on a single @Nullable annotation yet, we can at
least replace this one by JSR305's @Nonnull(MAYBE) as it fulfils all
requirements, including full Kotlin compatiblity. To avoid the
cumbersome name, we can redefine it as our own @NullableType
annotation. (We can't use @Nullable to avoid name clashes with the main
@Nullable annotation from AndroidX)
Issue: google/ExoPlayer#6792
PiperOrigin-RevId: 540497469
We currently do the same check on the input timestamps and
expect the output timestamps to match. Some codecs produce
samples with modified timestamps and the logic is a lot safer
when the comparison with the start time is done on the output
side of the codec.
Issue: google/ExoPlayer#11000
PiperOrigin-RevId: 540228209
With playback suppression in place, the devices can be added when the playback on ExoPlayer is in the suppression state. Also, it is quite possible that a suitable audio output device on which playback is ongoing gets removed requiring the Player to pause the playback. These requirements can be fullfilled using AudioDeviceCallbacks which has been implemented with this change.
PiperOrigin-RevId: 539559193
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
When the source is prepared again after stop, the period uid
is calculated by subtracting the `firstPeriodId` from the
period uid that is passed in to `createPeriod`. When this
happens after stop, the uid from the old period uid that
is still stored and has the value of the last played uid.
Hence the `firstPeriodId` must not be reset when released.
Issue: google/ExoPlayer#10838
PiperOrigin-RevId: 539028570
Add support for including Common Media Client Data (CMCD) in the outgoing requests of adaptive streaming formats DASH, HLS, and SmoothStreaming.
API structure and API methods:
* CMCD logging is disabled by default, use `MediaSource.Factory.setCmcdConfigurationFactory(CmcdConfiguration.Factory cmcdConfigurationFactory)` to enable it.
* All keys are enabled by default, override `CmcdConfiguration.RequestConfig.isKeyAllowed(String key)` to filter out which keys are logged.
* Override `CmcdConfiguration.RequestConfig.getCustomData()` to enable custom key logging.
NOTE: Only the following fields have been implemented: `br`, `bl`, `cid`, `rtp`, and `sid`.
Issue: google/ExoPlayer#8699
#minor-release
PiperOrigin-RevId: 539021056
This CL introduces the new public API setSuppressPlaybackWhenUnsuitableOutput which if set to TRUE will cause suppression of a requested playback if that is going to happen on an unsuitable audio output (e.g. builtin speaker on a WearOS device).
PiperOrigin-RevId: 538867212
This change is for Android 12 and below, where the buttons are derived from the actions added with the notification. From Android 13 (https://developer.android.com/about/versions/13/behavior-changes-13#playback-controls), the system derives media controls from `PlaybackState` actions.
When adding the actions onto the notification, the logic will iterate all the command buttons. The `COMMAND_KEY_CONPACT_VIEW_INDEX` extra will be checked for each button. If that extra is set for the three buttons on the compact view, then the customized buttons and their order will be used. Otherwise, the compact view will be "seekPrev" (if any), "play/pause" (if any), "seekNext" (if any) buttons (in such order).
Issue: androidx/media#410
PiperOrigin-RevId: 538797874
The sample timestamp carried by the emsg box can have a significant delta when comparing to the earliest presentation timestamp of the segment. Using this timestamp to intialize the timestamp offset in TimestampAdjuster will cause the media sample to have a wrong adjusted timestamp. So we should defer adjusting the metadata sample timestamp until the TimestampAdjuster is initialized with a real media sample.
PiperOrigin-RevId: 538172841
When initiated by MediaController, it should be possible for `MediaSession` to pass `MediaItems` to the `Player` if they have `LocalConfiguration`. In such case, it is not required to override `MediaSession.Callback.onAddMediaItems`, because the new current default implementation will handle it.
However, in other cases, MediaItem.toBundle() will continue to strip the LocalConfiguration information.
Issue: androidx/media#282
#minor-release
PiperOrigin-RevId: 537993460
With `AudioOffloadModePreference` `AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED`, the `DefaultTrackSelector` will select a single audio track that it finds is offload compatible. If not any audio track is supported in offload, then no track will be selected.
PiperOrigin-RevId: 537877183
This is a breaking change, but the alternatives seem either equally
breaking or worse, since the only way to make this non-breaking is
to add the `Throwable` overloads as `default` methods. It's then
unclear how we would ever migrate to these being the 'only' methods
or whether we'd have to keep both forms forever (which results in
duplication in the `Logger` implementations).
The clean break here also makes it clear that the `message` parameter
of `Log.Logger.{d,i,w,w}()` no longer automatically includes any info
from the `Throwable` passed to the static `Log.{d,i,w,e}() methods.
----
This CL also cleans up the javadoc on the static `Log.{d,w,i,e}` methods
since they no longer necessarily call straight through to the
corresponding `android.util.Log` methods (and haven't since <unknown commit>
and Issue: google/ExoPlayer#10185).
PiperOrigin-RevId: 537817974
*** Original commit ***
ExoPlayer: Add setVideoFrameProcessorFactory().
This allows apps to use a custom VideoFrameProcessor implementation for video
playback. This may be useful, for example, when outputting to a texture.
***
PiperOrigin-RevId: 536391597
Deprecated field `MediaItem.playbackProperties` remains for backwards compatibility, but its type is changed from `MediaItem.PlaybackProperties` to `MediaItem.LocalConfiguration`. The private `MediaItem` constructor will now also take in a `LocalConfiguration` argument instead.
PiperOrigin-RevId: 535648420
This change removes it from `Player.Listener` and `AnalyticsListener`,
use `onPositionDiscontinuity` with `DISCONTINUITY_REASON_SEEK` instead.
#minor-release
PiperOrigin-RevId: 534757426
Added piping to present offload support from the audio sink to the renderer and track selection. Applications can set offload mode preference and with both sink support and compatible track selection, renderer will be configured for offload.
PiperOrigin-RevId: 534450534
This change merges some duplicate sections, moves some items to more
appropriate sections and removes unnecessary items (deprecations are
self-documenting, so don't need to be included here).
#minor-release
PiperOrigin-RevId: 534363065
This change deprecates `PlayerView.setUseArtwork(boolean)` and
introduces `setArtworkDisplayMode(mode)` and
`artworkDisplayMode="off|fit|fill"` instead.
- off: no artwork is displayed (like deprecated useArtwork=false)
- fit: letterbox like media (like deprecated useArtwork=true)
- fill: scales the artwork to fill the entire width/weight of the player view
#minor-release
PiperOrigin-RevId: 534167226
Fix a bug when seeking in an opus container. The calculations inside
DefaultOggSeeker may overflow a long primitive.
Issue: androidx/media#391
#minor-release
PiperOrigin-RevId: 534128513
This allows apps to use a custom VideoFrameProcessor implementation for video
playback. This may be useful, for example, when outputting to a texture.
PiperOrigin-RevId: 534044831
In terms of MCVR with a `VideoRendererEventListener`, the video size is set to
0/0 right after `onVideoDisabled()` is called and is set to the actual size as
soon as the video size is known after 'onVideoEnabled()`.
For ExoPlayer and in terms of the `Player` interface, `Player.getVideoSize()`
returns a video size of 0/0 when `Player.getCurrentTracks()` does not support
`C.TRACK_TYPE_VIDEO`. This is ensured by the masking behavior of
`ExoPlayerImpl` that sets an empty track selection result when the playing
period changes due to a seek or timeline removal.
When transitioning playback from a video media item to the next, or when
seeking within the same video media item, the renderer is not disabled.
#minor-release
PiperOrigin-RevId: 533479600
This is useful for cases where only certain types (e.g. only video)
from a source are needed and other tracks should be filtered out
completely to avoid later track selection issues.
#minor-release
PiperOrigin-RevId: 533394658
Use Kotlin Charsets from the `kotlin.text` package, the `java.nio.charset.StandardCharsets` or the `com.google.common.base.Charsets` instead.
#minor-release
PiperOrigin-RevId: 532469103
Use a non deprecated constructor that includes the option to provide a `channelDescriptionResourceId` parameter.
#minor-release
PiperOrigin-RevId: 532450975
This change enables the IMA extension to play live DASH streams
with DAI support. Samples streams can be found and played in the
main demo app.
Issue: google/ExoPlayer#10912
#minor-release
PiperOrigin-RevId: 532407708
Use a non-deprecated constructor that accepts additional fields(`cause`, `responseBody`) to enhance error logging.
#minor-release
PiperOrigin-RevId: 532190896
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).
The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.
Issue: google/ExoPlayer#8046
PiperOrigin-RevId: 532151471
The periodic updates are only meant to happen while we are in the
same period or ad. This was already guaranteed except for two cases:
1. The Player in a session has updated its state without yet calling
its listeners
2. The session scheduled a PlayerInfo update that hasn't been sent yet
... and in both cases, the following happened:
- The change updated the mediaItemIndex to an index that didn't exist
in a previous Timeline known to the Controller
- One of the period position updates happened to be sent at exactly
this time
This problem can be avoided by only scheduling the update if we are
still in the same period/ad and haven't scheduled a normal PlayerInfo
update already.
Since new MediaControllers may still connect to old sessons with this
bug, we need an equivalent change on the controller side to ignore such
buggy updates.
PiperOrigin-RevId: 532089328
Adding items to an empty playlist is slightly different from adding
items to a non-empty playlist, because the former usually requires to
handle a change in the current item, position and playback state,
while the latter is not expected to affect the current item, position
or state.
The current ExoPlayer and SimpleBasePlayer code doesn't account for
this difference, leading to inconsistent behavior between
setMediaItem(s) and addMediaItem(s) when called on an empty playlist.
PiperOrigin-RevId: 530549928
The media button has API support with
`Callback.getPlaybackResumption()` that apps need to override to provide
a playlist to resume playback with.
Issue: androidx/media#167
PiperOrigin-RevId: 529495845
* Implement RendererCapabilities.Listener in DefaultTrackSelector.
* Add new methods TrackSelector.invalidateForRendererCapabilitiesChange and TrackSelector.InvalidateListener.onRendererCapabilitiesChanged.
* Add new field allowInvalidateSelectionsOnRendererCapabilitiesChange to DefaultTrackSelector.Parameter to allow opt-in of the renderer capabilities detection feature.
* Add logics of triggering track reselection when renderer capabilities change.
PiperOrigin-RevId: 529067433
Systems accepting URIs should treat schemes as case-insensitive
([RFC 3986 Section 3.1](https://www.rfc-editor.org/rfc/rfc3986#section-3.1)):
> An implementation should accept uppercase letters as equivalent to
> lowercase in scheme names (e.g., allow "HTTP" as well as "http") for
> the sake of robustness
PiperOrigin-RevId: 528735287
References to the service are kept from MediaSessionStub
and from a long-delayed Handler messages in ConnectionTimeoutHandler.
Remove strong references from these places by making the timeout
handler static and ensuring ConnectedControllersManager only keeps
a weak reference to the service (as it's part of MediaSessionStub).
Issue: androidx/media#346
PiperOrigin-RevId: 527543396
To reliably reject the System UI playback resumption notification on
all API levels (specifically API 30), the backward compatibility layer
needs to return `null` for the library root.
This is not possible in the Media3 implementation. This change allows
an app to return a `LibraryResult.ofError(RESULT_ERROR_NOT_SUPPORTED)`
that then is translated to return null by the backwards compatibility
layer.
Issue: androidx/media#355
Issue: androidx/media#167
Issue: androidx/media#27
See https://developer.android.com/guide/topics/media/media-controls#mediabrowserservice_implementation
PiperOrigin-RevId: 527276529
This is a helper method that can used to obtain information about
the controller that is currently calling a Player method.
PiperOrigin-RevId: 527268994
This simplifies the addition of new fields in the future.
Also do some misc clean up for the volume limit values:
- Add some documentation to mention assumed defaults
- Add the IntRange annotations to match the ones we have in Player
already
- Mention the limits in the relevant Player methods
- Avoid bundling default values
- Improve range checks for masking in MediaController
PiperOrigin-RevId: 526029619
This is a bug currently, where commands are created once but never
updated again if the actions in MediaSessionCompat are changed.
PiperOrigin-RevId: 525999084
If the limited number of input buffers causes reading of all samples except the last one conveying end of stream, then the last frame will not be rendered.
PiperOrigin-RevId: 525974445
`findDecoder/EncoderForFormat` seem to be more restrictive than querying
`MediaCodecList` as done for playback, and it's not clear that the cases where
no codec is found correspond to actual cases that would fail given that it
seems this returns an empty string for many cases in production.
Switch to using `MediaCodecUtil` and `EncoderUtil` for querying codecs instead.
PiperOrigin-RevId: 525078321
The sessions may have different application threads for their players,
and the service with its notification provider runs on the main thread.
To ensure everything runs on the correct thread, this change labels
methods where needed and fixes thread access in some places.
Issue: androidx/media#318
PiperOrigin-RevId: 524849598
This check was a leftover from when the metadata was generated from
the MediaItem only. Since we moved to the actual MediaMetadata fields,
the check is completely unnecessary and prevents accessing metadata
when the GET_CURRENT_MEDIA_ITEM command is not available.
#minor-release
PiperOrigin-RevId: 524837587
In `ExternalTextureManager` in seemingly rare cases end of stream is signaled
at the point where a frame is currently pending processing. In that case the
video end of stream signal was lost. If the muxer timeout was enabled this
case would result in throwing an exception, but otherwise the operation would
get stuck
Add code to signal end of stream in `onInputFrameProcessed` as well, so that we
signal end of stream when the pending frame is handled.
Tested by running
`TransformerEndToEndTest.loopingTranscodedVideo_producesExpectedResult` several
times.
PiperOrigin-RevId: 524361069
The overrides specified by a MediaController may not use the exact
same TrackGroup instances as known to the Player because the groups
have been bundled to and from the controller. This bundling may
alter the instance slightly depending on the version used on each
side of the communication and the fields set (e.g. Format.metadata
is not supported for bundling).
This issue can be solved by creating unique track group ids for
each group on the session side before bundling. On the way back,
the groups in the track selection parameters can be mapped backed
to their original instances based on this id.
#minor-release
Issue: androidx/media#296
PiperOrigin-RevId: 523986626
Previously, ExoPlayerImpl had volume flags hardcoded to SHOW_UI, but now the developer can choose what happens on volume change. The old methods have been deprecated.
PiperOrigin-RevId: 523974358
The setter command is only used for setPlaylistMetadata and can
be named COMMAND_SET_PLAYLIST_METADATA. The getter commnad is
used to access getMediaMetadata and getPlaylistMetadata and can
be better named COMMAND_GET_METADATA to reflect this usage.
PiperOrigin-RevId: 523673286
Previously `ChannelMixingAudioProcessor` output float because it was
implemented using the audio mixer's float mixing support.
Move the implementation over to just using the `ChannelMixingMatrix` and make
it publicly visible in the common module so it can be used by apps for both
playback and export.
Also resolve a TODO that no longer had a bug attached by implementing support
for putting multiple mixing matrices to handle different input audio channel
counts, and fix some nits in the test code.
Tested via unit tests and manually configuring a `ChannelMixingAudioProcessor`
in the transformer demo app and playing an audio stream that identifies
channels, and verifying that they are remapped as expected.
PiperOrigin-RevId: 523653901
It is not possible to provide a safe deprecation path because
BaseTrackSelection can't easily know which of the methods is
implemented by subclasses.
PiperOrigin-RevId: 523471578
`sed` has a different in-place command line syntax in FreeBsd
than GNU tools. This change makes the `sed` commands work with
FreeBSD `sed` on OSX in bash and zsh shells.
Issue: androidx/media#217
PiperOrigin-RevId: 522043938
MediaItems are not meant to be unique in a playlist. If a legacy
session publishes multiple items that get converted to equal MediaItems,
the current code fails because we look up queue ids in a Map (that
doesn't allow duplicate entries).
Fix this by storing a simple list of items with additional data.
#minor-release
Issue: androidx/media#290
PiperOrigin-RevId: 521993802
* Add a new event `onAudioCapabilitiesChanged` in `AudioSink.Listener` interface.
* Add an interface `RendererCapabilities.Listener`, which will listen to `onRendererCapabilitiesChanged` events from the renderer.
* Add `getRendererCapabilitiesReceiver` method for `TrackSelector`, and register/unregister the `TrackSelector` as the `RendererCapabilitiesReceiver` (if implemented) when the `ExoPlayer` is initialized/released.
* Trigger the `AudioSink.Listener.onAudioCapabilitiesChanged` and further `RendererCapabilities.Listener.onRendererCapabilitiesChanged` events when the audio capabilities changes are detected in `DefaultAudioSink`.
PiperOrigin-RevId: 521427567
The `DashMediaSource` wrongly added an offset to the media times set
to the `MediaLoadData`. With this the `startTimeMS` and `endTimeMs`
don't represent the positions in the period but in the stream.
`DashMediaSource` was the only call site that was setting the offset
to a non-zero value. So if we are using 0 for the `DashMediaSource`
as well, the offset is redundant and we can remove it everywhere.
PiperOrigin-RevId: 520682026
For multi-period live streams the content timeline for
which the global ad playback state has been split needs
to be kept together to not run into a race between
timeline refreshes and ad events.
PiperOrigin-RevId: 520358964
If RTSP Setup Request with UDP receives HTTP Error Status 461 UnsupportedTransport, then client will retry with TCP.
Issue: google/ExoPlayer#11069
PiperOrigin-RevId: 518807829
* Add `release` method to Renderer and AudioSink interfaces.
* Call the `release` method for renderers when the ExoPlayer is going to be released.
PiperOrigin-RevId: 517135677
While playback thread is 'asleep' during audio offload playback, the playbackInfo.positionUs is not being constantly updated. During this time, the returned value from getCurrentPosition should return an estimate based on the most recent value and playback speed.
PiperOrigin-RevId: 516550509