Future.isDone and getDone doesn't imply the Future was successful
and it may have been cancelled or failed.
In case where we handle failure, we should also handle cancellation
to avoid CancellationException to bubble up unchecked.
In demo app code where we use isDone for field initialization, we
want to crash in the failure case (usually security exception where
the connection is disallowed), but we want to gracefully handle
cancellation. Cancellation of these variables usually happens in
Activity.onDestroy/onStop, but methods may be called after this point.
#minor-release
PiperOrigin-RevId: 572178018
The current metadata updates are triggered by item transitions,
but depending on the speed of loading the playlist, the first
metadata may only be known later via metadata-change callbacks.
Slow playlist loading also means the UI stays empty and it's
beneficial to show a placeholder to avoid the impressions the
UI hangs.
Finally, clean-up by removing unused string constants and merging
all listeners into onEvents
#minor-release
PiperOrigin-RevId: 571951529
* Update AOSP copywright headers in all xml files in the Transformer demo app
* Use "end/start" instead of "right/left" to ensure correct behavior in right-to-left locales
* Simplify contrast_options and trim_options layout
PiperOrigin-RevId: 571933637
To support Automotive with the session demo, we need a separate app module.
To do this we need to split the service into its own module and make it
usable from different modules.
PiperOrigin-RevId: 568975271
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
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
Overlays may be overlaid over:
* In VideoFrameProcessor, videos or images (or texture input).
* In Compositor, other videos.
In Compositor, Overlays may consist of video, so it could be confusing
for videoFrameAnchor to contrast with overlayAnchor.
Also, rename overlayAnchor to overlayFrameAnchor, since it's modifying
the anchor in the overlay's frame, so this name seems slightly more precise.
PiperOrigin-RevId: 562004292
The actual logic scales the alpha, instead of setting it, so rename
this to what it does.
We would also prefer alpha to be scaled here, to not lose alpha information
(for example for PNGs with transparent regions).
PiperOrigin-RevId: 560121708
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
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
This doesn't currently work by default, but upcoming changes in
`TextRenderer` will make it work as expected.
Issue: google/ExoPlayer#10295
PiperOrigin-RevId: 553161628
For each event, the timestamp and presentation time is logged. The trace can
then be dumped to a tsv file and easily imported in a spreadsheet.
PiperOrigin-RevId: 550839156
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
This code is Widevine specific. `OfflineLicenseHelper.downloadLicense`
requires the passed `Format` to have a `DrmInitData.SchemeData` with
Widevine UUID and non-null `data` field. The demo app tries to check
this in advance (to avoid an exception later), but its checks are
looser than those made by `OfflineLicenseHelper`. This change tightens
the checks to match.
Issue: androidx/media#512
PiperOrigin-RevId: 549587506
The main demo app was still targeting API 29 to avoid scoped storage
restrictions. It is now updated to 34 (like the rest of the demo apps)
and handles scoped storage as it should handle it.
More specifically:
- We need to request READ_MEDIA_... permissions instead of
READ_EXTERNAL_STORAGE from API33.
- The legacy scoped storage opt-out can be removed
- READ_MEDIA_... permissions don't allow arbitrary file access
if the file doesn't end in a typical media file extension, so
this change adds a remark on the guide page to place samples
in the app-specific directory.
- We also don't have to request permissions for the app-specific
directories.
- Custom json files can't be placed in arbitray local locations
because they don't end in a media file extension, as there is
no way we can request a permission to load them. This means we
can remove the storage request logic in SampleChooserActivity.
Issue: google/ExoPlayer#6045
PiperOrigin-RevId: 549252474
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
This helps to highlight and document new requirements for apps,
e.g. to add the FOREGROUND_SERVICE_MEDIA_PLAYBACK permission for
background playback.
Issue: google/ExoPlayer#11239
PiperOrigin-RevId: 548666056
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
BaseGlShaderProgram and SingleFrameGlShaderProgram are technically color space agnostic. useHdr is passed to the TexturePool, which only uses the value to choose between high/regular precision. useHdr is therefore a bit misleading and should be generalized to "useHighPrecisionColorComponents."
PiperOrigin-RevId: 545726629
By passing this class where it's needed, implementations don't need to store it
in a field (reducing boilerplate) and it's clearer that it can't be unset when
needed.
PiperOrigin-RevId: 542823522
I created this by:
1. Downloading https://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv
2. Crafting a `test.srt` file with a text editor
3. Muxing them together:
```
$ mkvmerge -o android-screens-with-subrip.mkv \
android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv \
test.srt
```
Tested in the demo app, the subtitle track is selected by default
(default behaviour for Matroska spec afaict).
PiperOrigin-RevId: 540577912
*** Original commit ***
Rollback of 2a6f893fba
*** Original commit ***
Set video size to 0/0 when video render is disabled
In terms of MCVR wi...
***
PiperOrigin-RevId: 540525069
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
*** Original commit ***
BEGIN_PUBLIC
Set video size to 0/0 when video render is disabled
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
***
PiperOrigin-RevId: 537938947