Skip to content

Commit

Permalink
Feat/migrate media3 (#35)
Browse files Browse the repository at this point in the history
* Re-apply CEA-708 `rowLock/columnLock` fix

This change was originally made in https://github.com/androidx/media/commit/6f8249184bd69b126c93479f918768b0cf2d0889

It was then accidentally lost in when `Cea708Parser` was merged back
into `Cea708Decoder` in https://github.com/androidx/media/commit/51b4fa2cc83b60fcb313fd0e6afd2d45fe64e535.

This is the only change made to the actual 'decoding' logic in
`Cea708Parser` between it being split from `Cea708Decoder` and merged
back in again, all the other changes in this period relate to the
implementation of the `SubtitleParser` interface, so don't need to be
preserved in `Cea708Decoder`:
https://github.com/androidx/media/commits/51b4fa2cc83b60fcb313fd0e6afd2d45fe64e535/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/Cea708Parser.java

`Cea608Parser` was also merged back into `Cea608Decoder` in
https://github.com/androidx/media/commit/25498b151ba298ef359f245e2ed80718b4adf556
and so is vulnerable to the same risk of accidental loss of changes. To
be sure, I also checked the history of this file:
https://github.com/androidx/media/commits/25498b151ba298ef359f245e2ed80718b4adf556/libraries/extractor/src/main/java/androidx/media3/extractor/text/cea/Cea608Parser.java

The only 'decoding logic' change there is https://github.com/androidx/media/commit/379cb3ba540d7044785f8355b2df9220e7f5eb8f,
which was also lost in https://github.com/androidx/media/commit/25498b151ba298ef359f245e2ed80718b4adf556.
I will send a separate change to resolve this.

PiperOrigin-RevId: 635796696

* Re-apply CEA-608 `validDataChannelTimeoutMs` assertion

This change was originally made in https://github.com/androidx/media/commit/379cb3ba540d7044785f8355b2df9220e7f5eb8f.

It was then accidentally lost in when `Cea608Parser` was merged back
into `Cea608Decoder` in https://github.com/androidx/media/commit/25498b151ba298ef359f245e2ed80718b4adf556.

This was spotted when re-doing a similar lost change to `Cea708Decoder`,
reported in https://github.com/androidx/media/pull/1315.

See reasoning on https://github.com/androidx/media/commit/e2847b3b80112e7bce0e0706604bdee8126704e5
about why this is the only 'lost' CEA-608 change.

PiperOrigin-RevId: 635803536

* Add new line between printing glsl source code in error

PiperOrigin-RevId: 635812838

* Migrate debug trace logs to track generic events for Muxer.

Track information is added to the details string where relevant.

PiperOrigin-RevId: 635815866

* Remove VideoFrameReleaseControl setter from SinkProvider

Move the parameter to the constructor instead.

PiperOrigin-RevId: 636077477

* Set image duration on all media types

This was previously only set on images because it was not ignored on
other media types. This parameter was made no-op for non-images in
https://github.com/androidx/media/commit/7b2a1b444312953f9518868f1cfc3e0b6c400d7b.

PiperOrigin-RevId: 636078142

* Make getIconResIdForIconConstant public

This allows controller apps to map these constants to suitable
icons without creating a CommandButton instance first.

PiperOrigin-RevId: 636096841

* Work around 1080p export failures on certain devices

Fall back to using software decoder for 1920x1080 for certain
devices.

PiperOrigin-RevId: 636132298

* MP3: Derive duration and bitrate from frame count in `Info` header

`Info` header is used for CBR files, but in some cases not **every**
frame in these files is the same size. This change stops using the
single frame after the `Info` frame as the 'template' (and assuming all
subsequent frames are the same size/bitrate), and instead derives the
bitrate from fields in the `Info` header. This works for files which are
'almost' constant bitrate, like the one in Issue: androidx/media#1376 where every
frame is either 1044 or 1045 bytes except the one immediately after the
`Info` frame which is 104 bytes (32kbps), resulting in a wildly
incorrect duration calculation.

PiperOrigin-RevId: 636151605

* Parse dashif:Laurl license url in mpd

* Add test and formatting changes

* Trigger silence generation when end of stream is encountered

This change avoids a muxer deadlock when:
1. Sequence of items
2. First item has audio track that is shorter than video
3. Audio finishes, and muxer refuses to write more than 500ms of video
   consecutively.

SequenceAssetLoader fails to progress to the second item. A muxer
deadlock is possible when the audio of the first item finishes,
audio end-of-stream is not propagated through AudioGraph, and muxer blocks
video, preventing SequenceAssetLoader to move to the next item in sequence.

By triggering silence generation early as soon as audio EOS is
encountered, we ensure SequenceAssetLoader can progress to the next item.

PiperOrigin-RevId: 636179966

* MP3: Make a defensive copy of the header in `XingFrame` constructor

This is currently set from `Mp3Extractor.synchronizedHeader` which
gets overwritten every time we read a new frame. It seems safer to make
this defensive copy (and there will be at most one `XingFrame` instance
per-playback, so this is not prohibitively expensive).

PiperOrigin-RevId: 636181038

* Add DV profile 10 handling in getAlternativeCodecMimeType() method

* Fragmented Mp4Muxer: add support to B-frame Muxing

Add composition time offset parameter to TRUN box to
support muxing of videos containing B-frames by FragmentedMp4Muxer.
Update TRUN box version from 0 to 1 in order to manage signed
composition time offset.

PiperOrigin-RevId: 636426397

* Update session module registration

PiperOrigin-RevId: 636482934

* Assert file size in E2E android tests that claim to complete.

Remove redundant test logic to add file size to ExportResult because
the file size is already added to export result as part of an export
finishing.

PiperOrigin-RevId: 636499236

* Add missing module registrations

PiperOrigin-RevId: 636506860

* Ignore rowLock and numLock as define in CTA-708 spec.
Update current row value when new line is added.

* revert rowLock and colomnLock changes since it will be done separately

* remove test comment

* Add cea708Decoder test for setPenLocation command and newline handling

* Rename and reshuffle tests

* Add release note

* Remove jetifier config from gradle config

None of the AndroidX libs we depend on require jetification any more.

Issue: androidx/media#1362
PiperOrigin-RevId: 636544337

* Add more details to thread assertion in onAudioCapabilitiesChanged

This helps to debug issues reported in https://github.com/androidx/media/issues/1191

PiperOrigin-RevId: 636545970

* Migrate `buildConfig` from `properties.gradle` to `build.gradle`

This is generated in response to a deprecation warning in AS:

```
The option setting 'android.defaults.buildfeatures.buildconfig=true' is deprecated.
The current default is 'false'.
It will be removed in version 9.0 of the Android Gradle plugin.
You can resolve this warning in Android Studio via `Refactor` > `Migrate BuildConfig to Gradle Build Files`
```

PiperOrigin-RevId: 636546985

* Remove deprecated `setContentTypePredicate()` methods

Use the suggested alternative on the respective
`XXXDataSource.Factory` instead.

PiperOrigin-RevId: 636560182

* Remove `OkHttpDataSource` constructors & `OkHttDataSourceFactory`

Use `OkHttpDataSource.Factory` instead.

PiperOrigin-RevId: 636585523

* Print underlying extractor name in `UnrecognizedInputFormatException`

If subtitle-parsing-during-extraction is enabled (now defaults to on),
the 'outer' extractor class name is often
`SubtitleTranscodingExtractor`, leading to some slightly useless error
messages like:

`None of the available extractors (FragmentedMp4Extractor, Mp4Extractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, TsExtractor, MatroskaExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, AviExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor, SubtitleTranscodingExtractor)`

PiperOrigin-RevId: 636834354

* Remove `PlayerMessage.setHandler(Handler)`

Use `setLooper(Looper)` instead.

PiperOrigin-RevId: 636840566

* Maintain a consistent luminance range across HDR content in effects

PQ and HLG have different luminance ranges (max 10k nits and max 1k nits resp). In GL, colors work in a normalised 0 to 1 scale, so for PQ content, 1=10k nits and and for HLG content, 1=1k nits.

This cl scales and normalises PQ content appropriately so that all HDR content works in the HLG luminance range. This fixes two things

1. Conversions between HLG and PQ are "fixed" (before the output colors looked too bright or too dark depending on which way you are converting)
2. color-altering effects will be able to work consistently across HLG and PQ content

1 is tested in this cl. 2 will be tested when ultra HDR overlays are implemented, both cases have been manually tested to ensure the output looks correct on a screen.

PiperOrigin-RevId: 636851701

* Remove `ShadowLog` references from tests

These were accidentally submitted after being added for local debugging.

PiperOrigin-RevId: 636865825

* Remove deprecated `Timeline.Window.isLive` field

PiperOrigin-RevId: 636870982

* Remove deprecated `DefaultHttpDataSource` constructors

Use `DefaultHttpDataSource.Factory` instead.

PiperOrigin-RevId: 636875524

* Remove deprecated `DashMediaSource.DEFAULT_LIVE_PRESENTATION_DELAY_MS`

Use `DashMediaSource.DEFAULT_FALLBACK_TARGET_LIVE_OFFSET_MS` instead.

PiperOrigin-RevId: 636906922

* Remove deprecated `MediaCodecInfo.isSeamlessAdaptationSupported(...)`

Use `MediaCodecInfo.canReuseCodec(...)` instead.

PiperOrigin-RevId: 636918479

* Remove deprecated `DrmSessionManager.DUMMY` and getter method

Use `DRM_UNSUPPORTED` constant instead.

PiperOrigin-RevId: 636937592

* UltraHdr: Fix calculations to apply gainmap

PiperOrigin-RevId: 636964921

* Ensure single-frame videos are correctly exported

Add a wait in DefaultCodec.signalEndOfInputStream when no
video encoder output has been seen. This avoids a thread synchronization problem
between writing frames to video surface, and signaling end of stream,
which was hit for video input of only one frame on some devices.

PiperOrigin-RevId: 637844690

* Remove deprecated format changed methods

Use the overloads with an additional `@Nullable DecoderReuseEvaluation`
parameter instead.

PiperOrigin-RevId: 637851937

* Remove unused `Util.getCommaDelimitedSimpleClassNames` method

PiperOrigin-RevId: 637854422

* Add support for ultra HDR overlays

PiperOrigin-RevId: 637863706

* Reset input capacity when setting external shader program

Before this CL, externalShaderProgramInputCapacity was not reset when
the external shader program was reset (which occurs when  the
InputSwitcher switches to an input with a different ColorInfo). This is
due to a regression introduced in https://github.com/androidx/media/commit/bef3d518d2dd11155a759d4e62bd649e32752a2d.

PiperOrigin-RevId: 637869215

* Tighten exception handling in `TestPlayerRunHelper`

This removes `throws Exception` from public methods in favour of more
specific exception types (`TimeoutException` and `PlaybackException`).

PiperOrigin-RevId: 637880546

* Remove deprecated `RendererSupport.FormatSupport` IntDef & constants

Use `C.FormatSupport` and associated constants instead.

PiperOrigin-RevId: 637890304

* Speed up image to video Export

Only sample from input bitmap when the input image has changed.
Introduce GainmapShaderProgram.newImmutableBitmap API that signals
input bitmap changes to GainmapShaderProgram (DefaultShaderProgram).

PiperOrigin-RevId: 637920207

* Add a flag to control whether input bitmap resampling can be skipped

Add DefaultVideosFrameProcessor experimental flag that controls
whether input Bitmaps are sampled once for a repeating sequence of
output frames with the same contents, or once for each output frame.

PiperOrigin-RevId: 637921350

* Add an experimental analyzer mode to Transformer.

PiperOrigin-RevId: 637926059

* Import string translations for session module

#minor-release

PiperOrigin-RevId: 638224207

* Rename test so that it runs on MH

PiperOrigin-RevId: 638237657

* Use file inserts and string replacements in overlay shaders

PiperOrigin-RevId: 638251955

* Increase h.264 buffer size in `ShadowMediaCodecConfig`

Some test media has samples larger than 100kB

PiperOrigin-RevId: 638598553

* Rename `PreloadMediaSource.PreloadControl` methods

The IntDefs in `DefaultPreloadManager.Stage` are also renamed accordingly.

PiperOrigin-RevId: 638631357

* Suppress incorrect linter error in DebugRenderersFactory method

Method should use @RequiresApi annotation instead of @SdkSuppress

PiperOrigin-RevId: 638639225

* Regenerate TransformerHdrTest goldens after removing degammaing

Degammaing has been removed in https://github.com/androidx/media/commit/cb4b2ea55c70efa80adc3e664301b1990e89eaf3. The goldens for
TransformerHdrTest (previously TransformerSequenceEffectTestWithHdr)
were not regenerated because the test wasn't running due to its name
(fixed in https://github.com/androidx/media/commit/e41a966237528148590712048dc735dabfd344ca).

PiperOrigin-RevId: 638645635

* Remove unnecessary sortKey from Mp4Muxer.addTrack()

PiperOrigin-RevId: 638647112

* Use INDEX_UNSET instead of LENGTH_UNSET for next media sequence/part

Both constants have the same value, but the method returning initial values for the media sequence/part uses `INDEX_UNSET`, so it makes sense to use it.

PiperOrigin-RevId: 638673282

* Schedule exoplayer work task to when renderers can make progress

Currently ExoPlayer schedules its main work loop on a 10 ms interval. When renderers cannot make any more progress(ex: hardware buffers are fully written with audio data), ExoPlayer should be able to schedule the next work task further than 10Ms out.

Through `experimentalSetDynamicSchedulingEnabled`, ExoPlayer will dynamically schedule its work tasks based on when renderers are expected to be able to make progress.

PiperOrigin-RevId: 638676318

* Call PreloadControl.onSourcePrepared only once for each preload request

PiperOrigin-RevId: 638677090

* Schedule exoplayer work to when MediaCodecAudioRenderer can progress

Currently ExoPlayer schedules its main work loop on a 10 ms interval. When renderers cannot make any more progress (ex: hardware buffers are fully written with audio data), ExoPlayer should be able to schedule the next work task further than 10ms out into the future.

Through `experimentalSetDynamicSchedulingEnabled` and these changes to `MediaCodecAudioRenderer`, ExoPlayer can use the data provided by the audio renderer to dynamically schedule its work tasks based on when it is expected that progress can be made.

PiperOrigin-RevId: 638677454

* Add references in javadocs to relevant listeners for Player fields

PiperOrigin-RevId: 638688864

* Use `kotlinx-coroutines-guava` in session demo app

I originally tried switching to `Futures.addCallback` (as a follow-up
to Issue: androidx/media#890), but it seemed like a good chance to go further into
Kotlin-ification.

Before this change, if the connection to the session failed, the app
would hang at the 'waiting' screen with nothing logged (and the music
keeps playing). This behaviour is maintained with the `try/catch` around
the `.await()` call (with additional logging). Without this, the failed
connection causes the `PlayerActivity` to crash and the music in the
background stops. The `try/catch` is used to flag to developers who
might be using this app as an example that connecting to the session
may fail, and they may want to handle that.

This change also switches `this.controller` to be `lateinit` instead of
nullable.

Issue: androidx/media#890
PiperOrigin-RevId: 638948568

* Schedule doSomeWork when MediaCodec signals available buffers

When running in asynchronous mode, MediaCodec will be running the CPU to signal input and output buffers being made available for use by the player. With ExoPlayer.experimentalSetDynamicSchedulingEnabled set to true, ExoPlayer will wakeup to make rendering progress when MediaCodec raises these signals. In this way, ExoPlayer work will align more closely with CPU wake-cycles.

PiperOrigin-RevId: 638962108

* Allow `ByteArrayDataSource` to resolve the byte array when opened

This is a relatively small change, and massively simplifies the work
needed for an app to consume Kotlin Multiplatform resources (without a
full `KmpResourceDataSource` implementation, which poses some
dependency challenges for now).

Issue: androidx/media#1405
PiperOrigin-RevId: 638991375

* Fix a race condition in AudioGraphInput

AudioGraphInput.onMediaItemChanged is called on input thread. Pending
media item changes are processed on processing thread, inside calls to
getOutput().
This change allows multiple pending media item changes to be enqueued,
and processed in sequence.

PiperOrigin-RevId: 638995291

* Add `FOREGROUND_SERVICE_MEDIA_PLAYBACK` permission for test session app

Foreground service type `mediaPlayback` requires permission `android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK`. The `MockMediaSessionService`, `LocalMockMediaSessionService`, `MockMediaLibraryService`
 and `LocalMockMediaLibraryService` declared in the manifest are in the `mediaPlayback` type.

PiperOrigin-RevId: 639013810

* Move effect final values and preset names and paths to arrays file.

PiperOrigin-RevId: 639034630

* Fix CMCD data assignment for init segment

The CMCD data was incorrectly added to the `dataSpec` of the media segment instead of the init segment.

Also relaxed the condition for playbackRate to be C.RATE_UNSET when creating an instance of CmcdData.Factory as there was nothing enforcing this check.

#minor-release

PiperOrigin-RevId: 639046080

* Drop API requirement from SeparableConvolution

Switch from 4-channel RGBA_16F lookup texture to 1-channel R_16F.
Do not use a bitmap when creating the lookup table texture.
Instead, fill the texture directly.
Do not manually convert 32-bit float to 16-bit. Instead, let OpenGL
libraries do this for us.

PiperOrigin-RevId: 639717235

* Make progress tests stricter.

These changes are possible because getProgress is no longer a blocking
operation on transformer.

* Tests call getProgress after every looper message executed.
* Use longer media assets for getProgress tests to give more progress
  intervals.
* Remove conditional assertions.

PiperOrigin-RevId: 639734368

* Remove module registration from HttpEngineDataSource

It used to be its own module in the first revision, but then moved
into the DataSource module as of https://github.com/androidx/media/commit/250fc80419b4b8ef1b753824e53ebdac176968f5.

PiperOrigin-RevId: 639745498

* Add an analyzer mode option to Transformer demo.

PiperOrigin-RevId: 639746452

* Fix the RELEASENOTES.md

This [commit](https://github.com/androidx/media/commit/d175223cc632f9a927a0cfe62bc808d336a8c83a) was introduced not long ago (after 1.4.0-alpha01), but has the release note added to the alpha01 release. Moving this piece of note to "unreleased changes" so that it will be included in the 1.4.0-alpha02 release note as a new change.

PiperOrigin-RevId: 639768495

* Move CEA-708 release note from 1.3.0 to 'unreleased' (1.4.0)

This was added in the wrong place as part of https://github.com/androidx/media/commit/0a58832d85a51a8ee8f50144c25d92ab8d8c0e78

PiperOrigin-RevId: 639783174

* Allow customisation of various icons in PlayerControlView

Before this change:
The only way to customize the icons was to override the drawables, e.g.
* `exo_styled_controls_play`
* `exo_styled_controls_pause`

However, that would set the drawables globally and prevent users from customizing the icons **per** PlayerView.

After the change, it is possible to provide drawable icons in the xml layout directly via `<androidx.media3.ui.PlayerView>` and
* `app:play_icon="@drawable/...`
* `app:pause_icon="@drawable/...`
* `app:vr_icon="@drawable/...`
* `app:fullscreen_exit_icon="@drawable/...`
* `app:next_icon="@drawable/...`

Note:
Two buttons that are left out of this change are fast-forward and rewind. They are more complicated due to layout insertion and customization with seek back/forward increments in the TextView.

Issue: androidx/media#1200
PiperOrigin-RevId: 639832741

* Support Separable Convolutions with negative coefficients

fragment_shader_separable_convolution_es2.glsl had optimizations that assumed
all convolution coefficients are positive. Support negative coefficients,
and add tests.

PiperOrigin-RevId: 640104741

* Add isReleased() to the Exoplayer

This avoids having to add AnalyticsListener and catching the `onPlayerReleased` callback.

The `Exoplayer.release()` method is blocking and one can be sure that the player is released if the call returned. However, the method is useful for UI testing and asserting that the player is released after a certain UI action, e.g. closing the activity or detaching a window.

PiperOrigin-RevId: 640114416

* Skip AV1 test on devices that don't support AV1 HDR encoding

Skip AV1 HDR test on some devices.

PiperOrigin-RevId: 640135455

* Update release notes for 1.4.0-alpha02

PiperOrigin-RevId: 640138307

* Version bump to media3:1.4.0-alpha02

#minor-release

PiperOrigin-RevId: 640196724

* Add icons for fastforward and rewind buttons

PiperOrigin-RevId: 640206040

* Decide whether to use the VideoSink when enabling renderer

This will simplify moving the release control inside the video sink

PiperOrigin-RevId: 640416128

* Add LanczosResample effect to scale videos in Transformer

Add SeparableConvolution.configure(inputSize) to allow effect configuration
depending on input dimensions.
Add LanczosResample.scaleToFit method to scale input images to fit inside
given dimensions.

PiperOrigin-RevId: 640498008

* MCVR: use shouldUseVideoSink where possible

Before this CL, we were checking whether the video sink was initialized
to determine whether it should be used. In the meantime,
shouldUseVideoSink has been introduced. Use this boolean to check
whether to use the video sink as it's a clearer signal.

PiperOrigin-RevId: 640499147

* Update FILE_UNKNOWN_DURATION to a longer fmp4 (~15s),

Removes the flakiness of
MediaItemExportTest.getProgress_unknownDuration_returnsConsistentStates
by using a longer input asset, such that ExoPlayer does not determine
the duration of the media.

PiperOrigin-RevId: 640502470

* Remove @UnknownInitialization DefaultCodec parameter

Using an uninitialised object seems unusual.

PiperOrigin-RevId: 640514501

* Move renderer state methods from release control to sink

PiperOrigin-RevId: 640515298

* Remove direct usages of release control when video sink is used

Usages removed in this CL are:
- onProcessedStreamChange, which was already called from the VideoSink
  (via VideoFrameRenderControl)
- setOutputSurface, which was also already called from the VideoSink
- setFrameRate, which this CL now sets in the VideoSink

PiperOrigin-RevId: 640530903

* Fix invalid state transitions for trim optimization getProgress.

Ensures valid progress state is returned. Should not return NOT_STARTED
once transformer.start has been called, until export ends.

PiperOrigin-RevId: 640533805

* Refactor trim optimization getProgress for improved readability.

This change is a no-op refactor to improve the readability of the
states returned in this method.

PiperOrigin-RevId: 640538374

* Remove unnecessary `throws Exception` from `HlsChunkSourceTest`

PiperOrigin-RevId: 640552488

* Add missing null check

PiperOrigin-RevId: 640555113

* Exit early if buffer becomes invalid

When the frame release control invalidates a buffer and returns that
the buffer must be ignored, we need to exit early before performing
additional checks that may result in method calls using the invalid
buffer.

PiperOrigin-RevId: 640555688

* MuxerWrapper: Fix spelling mistake in method name

PiperOrigin-RevId: 640838741

* Stabilize offload related error codes

PiperOrigin-RevId: 640839273

* Add CodecDetails to ExportException

This will replace the existing free-form string in the error message

PiperOrigin-RevId: 640954158

* Unify timestamp handling

Before this change, the timestamps output from composition playback is offset
with the renderer offset. After this change, the offset is removed and the
timestamp behaviour converges with Transformer, that is, the timestamps of
video/images frames will follow that of the composition. For example, with a
composition of two 10-s items, clipping the first with 2s at the start, the
timestamp of the first frame in the second item, will be 8s.

PiperOrigin-RevId: 641121358

* Fix a concurrency issue that shader capacity is set off GL thread

Also add test to cover transitions between BT709 and 601.

PiperOrigin-RevId: 641224971

* Fix timestamps in tests

https://github.com/androidx/media/commit/38a7229d9684970f3475eff203255b7d1c8cf747 changed only some of the timestamps, in fact all
of the timestamps should have the offset removed.

PiperOrigin-RevId: 641226102

* Fix test names

PiperOrigin-RevId: 641249128

* Mark `PlayerWrapper` as `final`

This package-private class isn't currently extended, so this change
makes it not possible to be extended in future.

PiperOrigin-RevId: 641270464

* Change externalShaderProgramInputCapacity to int

The field is only accessed on the GL thread.

PiperOrigin-RevId: 641273595

* Add `PlayerSurface` Compose component

Underneath, it delegates to either
* `AndroidExternalSurface` (equivalent of SurfaceView), which is generally better for power and latency
* `AndroidEmbeddedExternalSurface` (equivalent of TextureView) which is better for interactions with other widgets or applying visual effects through the graphicsLayer

Note: the resulting surface is stretched across the whole screen. Aspect ratio handling will be addressed in the follow-up changes.
PiperOrigin-RevId: 641285482

* Add support for setting and getting volume for composition preview.

PiperOrigin-RevId: 641822822

* Remember Player instance on recompositions

PiperOrigin-RevId: 641823733

* Remove incorrect 'bundleable' reference from `stringMapToBundle` param

This was accidentally copy-pasted in https://github.com/androidx/media/commit/5008417c8cd12680a3945945e00399cca05915c5

PiperOrigin-RevId: 641823991

* Set VideoSink listener when enabling MCVR

Before, the listener was set in onReadyToInitializeCodec, which means
that it was reset every time a new codec was used.

We need to set the listener every time MCVR is enabled (not only the
first time), because it might have been set by another renderer.

PiperOrigin-RevId: 641825717

* Add Transformer HDR-only assets sequence effect tests.

PiperOrigin-RevId: 641828107

* Rename "preset file" to "preset" in composition demo.
This change is made for consistency with transformer demo.

PiperOrigin-RevId: 641835714

* HDR-only assets sequence effect test: rename golden files

rename to match test name

PiperOrigin-RevId: 641836522

* Support upscaling with LanczosResample

Avoid scaling the lanczos windown function when scaling up.
When scaling up (output > input), we shouldn't scale the window
function or we risk not sampling any of the input pixels.

PiperOrigin-RevId: 641838149

* Call VideoFrameReleaseControl.setPlaybackSpeed from sink when enabled

Do not call VideoFrameReleaseControl.setPlaybackSpeed directly from
MCVR when the video sink is enabled.

PiperOrigin-RevId: 641840894

* Clarify docs on `ExoPlayer.setVideoEffects()` re calling `prepare()`

The previous wording suggested that `setVideoEffects()` may **only** be
called before `prepare()`, i.e. the effect cannot be changed during
playback. The intent is instead that `setVideoEffects()` must be called
once before playback in order to configure the effects pipeline, but
the effect can then be changed during playback by further calls to
`setVideoEffects()`.

Issue: androidx/media#1393
PiperOrigin-RevId: 641853629

* Remove most nullness marking from Transformer demos

The nullness checking is very verbose and redundant in some places, for
example, the ensures-non-null marking in the transformer activity, and it makes
changing features in the demo app more time consuming. The cost/benefit balance
seems to be in favor of removing this for demo code.

Note: the ExoPlayer main demo has nullness checks turned off.
PiperOrigin-RevId: 641890618

* Tidy passing views in transformer demos

PiperOrigin-RevId: 641891515

* Rename "preset file" to just "preset" in transformer demo

The new name means we can add streams and other sources that aren't files in
future, for example, screen recording input.

PiperOrigin-RevId: 641894319

* Fix an invalid javadoc link

PiperOrigin-RevId: 641895590

* Create explicit key for testing 'notification controller'

Previously these tests were setting the test-only `KEY_CONTROLLER`
bundle value to the prod value of
`MediaController.KEY_MEDIA_NOTIFICATION_CONTROLLER_FLAG`, which is a bit
confusing because this is intended to be used as a `Bundle` **key**
(for a boolean value), and not a value itself.

Instead this CL creates a test-only value that can be used by
`RemoteMediaSession` and related test-only friends to indicate that
something (e.g. error or extras) should only be set on the notification
controller.

This CL also changes the logic in `MediaSessionProviderService` to
avoid needing to special-case checking for this controller key.

PiperOrigin-RevId: 641939283

* Add helper function in Track.java to copy track without edit lists.

PiperOrigin-RevId: 642038117

* Add MediaSession.Callback.onPlayerInteractionFinished

This callback is useful for advanced use cases that care about
which Player calls are batched together. It can be implemented
by triggering this new callback every time a batch of Player
interactions from a controller finished executing.

PiperOrigin-RevId: 642189491

* Add stress test for image transform

PiperOrigin-RevId: 642213253

* Reduce flakiness of getProgress tests around percentage values.

There is no requirement for the first progress value to be 0, if
progress is made instantly.

PiperOrigin-RevId: 642245457

* Add SessionError and use it in service results

This change adds `SessionError` and uses it in `SessionResult`
and `LibraryResult` to report errors to callers.

Constructors and factory method that used a simple `errorCode` to
construct error variants of `SessionResult` and `LibraryResult`
have been overloaded with a variant that uses a `SessionError`
instead. While these methods and constructors are supposed to be
deprecated, they aren't yet deprecated until the newly added
alternative is stabilized.

PiperOrigin-RevId: 642254336

* Remove `Bundleable` type & `Bundleable.Creator<Foo> CREATOR` fields

This interface is not used in the library. Callers can use the
`Bundle toBundle()` and `static Foo fromBundle(Bundle)` methods
defined directly on each type instead.

PiperOrigin-RevId: 642271609

* Increase sleep duration when video encoder ends with no output frames

This duration was not sufficient on a Pixel 3a

PiperOrigin-RevId: 642276212

* Publish the media3 session controller test app

Issue: androidx/media#78
PiperOrigin-RevId: 642277900

* Add `@CallSuper` to `TrackSelectionParameters.toBundle`

PiperOrigin-RevId: 642292328

* Clean up unecessary zero-arg `toBundle()` methods

These are no longer needed now that the `Bundleable` interface has been
removed. Public methods are deprecated, package-private ones are
removed. Callers are migrated in both cases (except where tests
explicitly exist for the deprecated method).

PiperOrigin-RevId: 642294451

* Propagate media3 session extras to media1 `PlaybackStateCompat`

PiperOrigin-RevId: 642299178

* Update `@UnstableApi` docs with a link to DAC

The code snippets in javadoc don't render correctly due to
https://issuetracker.google.com/342557694

PiperOrigin-RevId: 642309632

* Make ExportResult.processedInputs package private

Rational for keeping field package private:
Since the overall export already very complex, by looking at the output file
its hard to know if the desired processing happened or not. Since we now
support sequences with "n" media items, its even more important to know if all
the media items were processed or not.
Although the field exposes implementation details, it seems ok as we get benefit of detailed testing.

PiperOrigin-RevId: 642337888

* Pass clock to release control from sink provider

In order to do that, make the VideoSink nullable in MCVR.

We want to avoid calling VideoFrameReleaseControl.setClock directly
from MCVR when the sink is enabled. The goal is to handle all the
communication with the release control from the sink/sink provider.

PiperOrigin-RevId: 642542063

* Remove useHdr from overlaySettings

useHdr is unused option and doesn't make sense is the dynamic range of the overlay and video must match

Also reorders and adds javadoc in line with coding conventions

PiperOrigin-RevId: 642555396

* Make ImageOutput clearable

It's currently not possible to remove a previously set image output
on ExoPlayer, although the underlying renderer already supports
receiving null to clear the output. Marking the parameter as
nullable allows apps to clear it as well.

PiperOrigin-RevId: 642569081

* Suppress warning about unused return value

The return value is intentionally unused because the check
is only done to see if the reflection operation succeeds.

PiperOrigin-RevId: 642579373

* Fix minor timestamp handling issue

- Video release should check for buffer timestamp (which is renderer-offsetted), rather than the frame timestamp
- ImageRenderer should report ended after all of it's outputs are released, rather than when finished consuming its input.

Add tests for timestamp handling

PiperOrigin-RevId: 642587290

* Sync and map fatal and non-fatal errors from and to the legacy session

A fatal `PlaybackException` is mapped to a legacy playback state
in state `STATE_ERROR` with error code, message and extras. A
non-fatal error sent to controllers with `MediaSession.sendError`
is synced to the legacy session by setting error code and message
and merging the extras while preserving the rest of the state in
sync with the session player.

Vice versa, a `MediaController` connected to a legacy session receives
fatal errors through `Player.onPlayerErrorChanged()` and non-fatal errors
through `MediaController.Listener.onError()`.

Error codes are mapped in `LegacyConversions`. Values of error codes
in `@SessionError.ErrorCode` come from `@PlaybackExceptino.ErrorCode`
with the exception of `@SessionError.ERROR_IO` and
`@SessionError.ERROR_UNKNOWN`. These already exist in
`@PlaybackException.ErrorCode` and are mapped accordingly to avoid
semantic duplicates.

PiperOrigin-RevId: 642595517

* Refactors the seek test and add more test cases

PiperOrigin-RevId: 642597298

* Make nit improvements in muxer code

PiperOrigin-RevId: 642599475

* Move usages of allowReleaseFirstFrameBeforeStarted inside sink

PiperOrigin-RevId: 642611061

* Add image samples and track selection to demo app

Also move the track selection header strings to the demo app
as they are only used there (except for audio, which stays in UI)

PiperOrigin-RevId: 642616037

* Clarify semantics of MSG_SET_IMAGE_OUTPUT

The value can be null, which isn't mentioned in the docs yet

PiperOrigin-RevId: 642622583

* Split muxer android tests between parameterized and non parameterized

This will be helpful for adding more tests which need not to
be parameterized.

PiperOrigin-RevId: 642638702

* Fix single sample handling ProgressiveMediaPeriod when disabling tracks

When deselecting the single sample track and later re-selecting this
track, the current shortcuts in ProgressiveMediaPeriod don't handle
this case correctly and cause assertion failures.

In particular, this change fixes 3 issues:
 1. When re-selecting the single sample track, we have cleared the
    SampleQueue and need to reload the sample. The existing shortcut
    should only be applied to avoid the reload when starting from a
    non-zero position.
 2. When de-selecting the track, ProgressiveMediaPeriod is left in
    an inconsistent state where the sample queues are empty but
    loadingFinished is still true. Fix this by resetting
    loadingFinished to false.
 3. When seeking, we avoid reloading the stream if we can keep
    inside the existing samples. This logic assumes that all
    remaining samples will continue to be loaded in the queue.
    This condition isn't true though for single sample tracks
    that have been de-selected. They appear to support the seek
    inside the queue (=no seek necessary, always supported), but
    still require a new load if there is no ongoing one to load
    the sample. Fix this by checking this implicit assumption
    (still loading, or loading finished).

PiperOrigin-RevId: 642650248

* Schedule refresh for all the playing playlists for HLS live stream

Issue: androidx/media#1240
PiperOrigin-RevId: 642927082

* Add a checkbox to use Media3 muxer in Transformer demo app

PiperOrigin-RevId: 642941439

* Fix bug where enabling CMCD for HLS live streams causes error

Determine `nextMediaSequence` and `nextPartIndex` based on the last `SegmentBaseHolder` instance, as it can update `mediaSequence` and `partIndex` depending on whether the HLS playlist has trailing parts or not.

Issue: androidx/media#1395
PiperOrigin-RevId: 642961141

* Fix AVI extractor WAVE format extraction

Allow `WAVEFORMAT` (in addition to `WAVEFORMATEX`), which omits initialization
data.

Fix reading of bits per sample to use little endian byte order like the other
reads. See also the wave format docs linked from
https://learn.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference#avi-stream-headers.

PiperOrigin-RevId: 642962893

* Effect: Delay end of stream until all frames are rendered.

Previously, if renderFramesAutomatically = false, DefaultVideoFrameProcessor
may call onInputStreamProcessedListener after all frames have been
onOutputFrameAvailableForRendering, but before they had all been rendered and
freed.

Delay onInputStreamProcessedListener being called and subsequent DVFP
reconfiguration of effects, until all frames are rendered.

Tested using exoplayer setVideoEffects demo with playlist

PiperOrigin-RevId: 642963100

* Remove the code to restore current output position

Muxer never uses latest output position but always writes to
a specific location, so restoring its position does not add any
value.

PiperOrigin-RevId: 642996941

* Refactor mixedInput E2E test to use parameterized logic.

This CL is a pure refactor of the existing tests, iterative changes
will be done in follow-ups.

The only logic change is having all MP4 assets have the presentaton of
height=360. The old code had some with height 480.
PiperOrigin-RevId: 643020773

* Add a drop-in replacement for `MediaExtractor` in Media3

This change introduces a new class in Media3 `MediaExtractorCompat`, designed to be a drop-in replacement for platform `MediaExtractor`. While not all APIs are currently supported, the core functionality for the most common use cases of `MediaExtractor` is now available. Full API compatibility will be achieved in the future.

PiperOrigin-RevId: 643045429

* SpeedChangingAP: synchronize fields accessed from multiple threads

PiperOrigin-RevId: 643046385

* support hdr text overlays

adds luminance multiplier to allow the luminance (i.e. brightness) over a text overlay to be scaled

PiperOrigin-RevId: 643047928

* Parse 'max num reorder samples' values from h.264 and h.265 videos

This value is used in a follow-up change to re-order SEI messages
containing CEA-6/708 data from decode order to presentation order.

PiperOrigin-RevId: 643296338

* Remove PreloadConfiguration from public API

This feature isn't completed, so we should remove
the public facing API to avoid confusion.

#minor-release

PiperOrigin-RevId: 643318692

* Image support in PlayerView

Images are rendered into an ImageView (on top of the video shutter).
The image view is set to the images emitted by ExoPlayer's ImageOutput
and cleared when there is no longer a selected image track.

In order to keep the existing behavior of video tracks to only clear
the old output once the new first frame is rendered (avoiding short
periods of black between playlist items), we have to reorder this code
slightly to make it work for video and images. Both are treated in the
same way. If both are enabled, video takes precedence.

As the UI module only depends on the common module, we can't direcly
add the ImageOutput to ExoPlayer. This is done via reflection if
the provided Player is an ExoPlayer.

#cherrypick

PiperOrigin-RevId: 643320666

* Rollback of https://github.com/androidx/media/commit/cd9b914c423900edcfe1e64bfb775a601bc23844

PiperOrigin-RevId: 643329324

* Add `demo-composition` to `settings.gradle`

This was missed as part of https://github.com/androidx/media/commit/0e5a5e029455ea5e456cbb6028e9be1e87cdfe09

#cherrypick

PiperOrigin-RevId: 643331307

* Add more cases for parameterized video android tests.

PiperOrigin-RevId: 643346610

* Write moov box at the start of the file if possible

This is done by reserving some space for moov box at the start of the file and writing it there if it fits. If it doesn't fit, then it is written at the end of the file.

PiperOrigin-RevId: 643944698

* Reset release control from video sink when enabled

PiperOrigin-RevId: 643950097

* Merge pull request #1437 from MGaetan89:add_exoplayer_setMaxSeekToPreviousPosition

PiperOrigin-RevId: 643987403
(cherry picked from commit 67a7b41fa7453ac4fa06d4d9c7df68e72fbc58ea)

* Fix linter errors in `DemoMediaLibrarySessionCallback.kt`

PiperOrigin-RevId: 644002147
(cherry picked from commit ed07ac5d7de31a610b63d51242fc383d4bad9ffe)

* Update release notes for 1.4.0-beta01

#cherrypick

PiperOrigin-RevId: 644351958
(cherry picked from commit 794731607d2fd267d45f8f587812d11e655e59df)

* Version bump to media3:1.4.0-beta01

PiperOrigin-RevId: 644352776
(cherry picked from commit c07bbd333ca88ec93a9efdfcc037e406e1aa4099)

* Improve audio focus handling tests with ExoPlayer

There are a lot of tests for AudioFocusManager in isolation,
but almost none for the handling in ExoPlayer.

Add test coverage for all the common cases, including some
currently broken behavior that is indicated by TODOs.

PiperOrigin-RevId: 644319251
(cherry picked from commit e20e94fde277a8e9e9a09e502a5760772e9eb006)

* Audio focus player command clean up

The 'player commands' returned to ExoPlayerImpl instruct the
player on how to treat the current audio focus state.

The current return value when playWhenReady==false is misleading
because it implies we are definitely not allowed to play as if
we've lost focus. Instead, we should return the actual player
command corresponding to the focus state we are in.

This has no practical effect in ExoPlayerImpl as we already
ignore the 'player command' completely  when playWhenReady=false.

To facilitate this change, we also introduce a new internal
state for FOCUS_NOT_REQUESTED to distinguish it from the state
in which we lost focus.

#cherrypick

PiperOrigin-RevId: 644416586
(cherry picked from commit 66c19390e2b31106a2a467366f7945c37a273fc6)

* Allow session activity to be set per controller

PiperOrigin-RevId: 644693533
(cherry picked from commit 856d394c281cabc2b1932b003d752631549e7231)

* Use a localized fallback message for known error codes

In the case of a legacy session app providing an error
code different to `ERROR_UNKNOWN` without an error
message, a localized fallback message is provided
instead of ignoring the error.

#cherrypick

PiperOrigin-RevId: 644704680
(cherry picked from commit 6cc6444dd9be34ea3a40d2bb296247178ee86b1d)

* Use `SurfaceSyncGroup` to ensure resize transaction isn't dropped

This workaround is only applied on API 34, because the problem isn't
present on API 33 and it is fixed in the platform for API 35 onwards.

Issue: androidx/media#1237

#cherrypick

PiperOrigin-RevId: 644729909
(cherry picked from commit 968f72fec6d5452a34976824ac822782eeeb8f45)

* Move playWhenReadyChangeReason inside PlaybackInfo

This helps to keep the reason always together with the state it
is referring to, avoiding any side channels and making sure there
are no accidental inconsistencies.

#cherrypick

PiperOrigin-RevId: 644969317
(cherry picked from commit c0abd6f91ec62bc5347561c3f3174b3a660a7ba6)

* Clarify that onPlayWhenReadyChanged can be called again with new reason

Sometimes the reason for the current state may change. If we don't
report this again, users have no way of knowing that the reason
changed.

Also adjust ExoPlayerImpl and MediaControllerImplBase accordingly.
SimpleBasePlayer already adheres to this logic.

#cherrypick

PiperOrigin-RevId: 644970236
(cherry picked from commit 1d26d1891e6e3cd49a4b479723b8aba7be746c1c)

* Fix audio focus handling in ExoPlayerImpl

Some cases are not handled correctly at the moment:
 - Pausing during suppressed playback should not clear the
   suppression state.
 - Transient focus loss while paused should be reported as
   a playback suppression.

Issue: androidx/media#1436
#cherrypick
PiperOrigin-RevId: 644971218
(cherry picked from commit e84bb0d21cd114c5b726c6c3d799b194df068a14)

* Remove direct `AspectRatioFrameLayout` usage from session demo

This class is a lower-level UI component that isn't directly needed if
apps are using `PlayerView` to handle their video output (it is used as
an implementation detail of `PlayerView`).

Removing its unecessary usages from this demo avoids developers copying
this as an example when building their own apps.

#cherrypick

PiperOrigin-RevId: 644972454
(cherry picked from commit cb8f87e05e73d72ce7d2c405c4c5899dc31ade5e)

* Add null-check to `PlayerView` to avoid NPE in edit mode

Previously we assumed that `surfaceSyncGroupV34` was always non-null on
API 34, but this isn't true in edit mode. Instead we add an explicit
null-check before accessing it. We don't need to null-check it at the
other usage site because we are already null-checking `surfaceView` (via
`instanceof` check).

Issue: androidx/media#1237

#cherrypick

PiperOrigin-RevId: 645008049
(cherry picked from commit 99803066ea6d375f5527e0953aad4ecd91fbac3c)

* Use HttpEngineDataSource when supported in demo app.

HttpEngineDataSource is the recommended HttpDataSource when it is available. It uses the [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine).

#cherrypick

PiperOrigin-RevId: 646051562
(cherry picked from commit e591c37b1e60d5138a612040efba752b7b7ab8e5)

* Fix flakiness in MediaCodecVideoRendererTest

The test is flaky because the decoding process in the renderer
depends on some timing from MediaCodec beyond our control and
the new keyframe added in the test is sometimes 'dropped' when
it arrives too late.

We can fix this by controlling the test progress a bit more
tightly: first rendering with the same current time until the
key frame is processed and then start increasing the time
until we've reached the end.

#cherrypick

PiperOrigin-RevId: 646064352
(cherry picked from commit ada4dc982fac32a57db069341f1f51c6a3bb6cc5)

* In DemoUtil, don't set cookie handler when using HttpEngineDataSource.

HttpEngine does not support cookie storage.

#cherrypick

PiperOrigin-RevId: 646084702
(cherry picked from commit bb568b5150781457fe22c3d4a877e8c99bddc4a2)

* Add fail-early checks for TrackSelectorResult correctness

The two arrays need to have the same length and the selection
must match in their nullness (unless for TYPE_NONE
renderers). Clarify this more clearly in the docs and add
new asssertions for it. This avoids that the player is failing
in obscure ways much later.

Issue: androidx/media#1473
#cherrypick
PiperOrigin-RevId: 646086833
(cherry picked from commit 71ef848ec3fa4409f3cdf797226c2a51ecd15da6)

* Merge pull request #1416 from khouzam:customFormat

PiperOrigin-RevId: 646121082
(cherry picked from commit b026271c8438f227f4e15e0eaedd7223b4492037)

* Merge pull request #1479 from dryganets:sdryanets/fix-handler-usage

PiperOrigin-RevId: 646402268
(cherry picked from commit 04667284975e9fc71c137b4a8c133ca5cc626c19)

* Add guard against additional tracks reported by Extractors

Extractors should not report additional tracks once they called
ExtractorOutput.endTracks. This causes thread safety issues in
ProgressiveMediaPeriod where the array of sample queues is
extended while the playback thread accesses the arrays.

Detecting this problem early is beneficial to avoid unexplained
exceptions later one. In most cases where this may happen (namely
TS extractors finding new tracks), it's better to ignore the new
tracks instead of failing completely. So this change adds a
warning log message and assigns a placeholder output.

Note: The same workaround already exists in HlsSampleStreamWrapper
and MediaExtractorCompat.

Issue: androidx/media#1476
#cherrypick
PiperOrigin-RevId: 646427213
(cherry picked from commit 18e631ff790e0e9b3630ea8e36efb468474d0877)

* Rename DummyTrackOutput and DummyExtractorOutput

#cherrypick

PiperOrigin-RevId: 646434450
(cherry picked from commit 867410fece006122820e26be4e0bea87309a4f2e)

* Use `MediaCodec.stop()` before `release()` for surface switching bug

ExoPlayer used to call `stop()` before `release()`. This was removed in
<unknown commit>.

A framework bug introduced in Android 11 (API 30) resulted in some
DRM -> clear transitions failing during `MediaCodec.configure()`. An
investigation in Issue: google/ExoPlayer#8696 and b/191966399 identified that this was
due to `release()` returning 'too early' and the subsequent
`configure()` call was then trying to re-use a `Surface` that hadn't
been fully detached from the previous codec. This was fixed in
Android 13 (API 33) with http://r.android.com/2094347.

ExoPlayer worked around the framework bug by adding an arbitrary 50ms
sleep after a failed codec initialization, followed by retrying. This
was enough to resolve the problem in the test scenario on a OnePlus
AC2003.

Issue: androidx/media#1497 points out that 50ms might not be the appropriate delay
for all devices, so it's an incomplete fix. They suggested re-adding the
`MediaCodec.stop()` call instead. This also reliably resolves the issue
on the OnePlus AC2003 (with neither workaround in place, the problem
repros almost immediately).
PiperOrigin-RevId: 646461943

(cherry picked from commit 5fcc7433a1f188c9644d4430a828a49d06c993cb)

* Use `removeKey` method instead of setting `null` for KEY_CODECS_STRING

Setting a `null` value doesn't remove the key as expected per the `MediaFormat` API documentation, using the `removeKey` method instead which is only available starting API level 29.

PiperOrigin-RevId: 646462402
(cherry picked from commit 12c42585d25d4c51bc5d022aa282d4d36b8e1ff2)

* Merge pull request #1487 from colinkho:main

PiperOrigin-RevId: 646917527
(cherry picked from commit 6244d8605f48d1b548201a8a964a9879961b3c68)

* Send pending updates before adding discontinuity for error

When handling a playback error that originates from a future item in
the playlist, we added support for jumping to that item first,
ensuring the errors 'happen' for the right 'current item'.
See https://github.com/androidx/media/commit/79b688ef30d4a3306d4d321ddf4464b428074ea2.

However, when we add this new position discontinuity to the
playback state, there may already be other position discontinuities
pending from other parts of the code that executed before the
error. As we can't control that in this case (because it's part
of a generic try/catch block), we need to send any pending
updates first before handling the new change.

Issue: androidx/media#1483
PiperOrigin-RevId: 646968309
(cherry picked from commit 727645179b3c26e495540f4445216fd035cc7654)

* Cache audio timestamp frame position across track transition reset

Upon track transition of offloaded playback of gapless tracks, the framework will reset the audiotrack frame position. The `AudioTrackPositionTracker`'s `AudioTimestampPoller` must be made to expect the reset and cache accumulated sum of `AudioTimestamp.framePosition`.

#cherrypick

PiperOrigin-RevId: 647294360
(cherry picked from commit a58e77a5a63d51c8cb9419fc59a7f0c7459fcafe)

* Update the composition README file

PiperOrigin-RevId: 648282532
(cherry picked from commit 16ef63cdfc0f42aa445b2dbc22715bde20ac3226)

* Update translations

#cherrypick

PiperOrigin-RevId: 648385733
(cherry picked from commit 6bf2461f803ffc95c0a40c37099a655abf8448ce)

* Improve automatic error replication for legacy browsers

This change extends the error replication to a given set of
error codes (not only authentication error), but only
replicates an error if the caller of the service `Callback`
is a legacy controller. It also makes error replication
configurable so that apps can opt-out and report errors
manually instead, or define the error codes for which
replication is enabled.

The change also removes the restriction of `sendError` only
being available for Media3 controllers. Instead, sending an
error to a legacy controller updates the platform playback
state in the same way as sending the error to the media
notification controller.

#cherrypick

PiperOrigin-RevId: 648399237
(cherry picked from commit 70c063905c0831c072cb9e1fa90bfbc1fd70aa68)

* Fix index out of bounds exception when a `Subtitle` is empty

Issue: androidx/media#1516

#cherrypick

PiperOrigin-RevId: 648416119
(cherry picked from commit 711d18de0308d4de40516466d3112c8e99c549dc)

* Add OptIn annotation to method declaration in demo app file

#cherrypick

PiperOrigin-RevId: 648641357
(cherry picked from commit 0510370bd27f8fe3cd43a18dd254b5d59dc89662)

* Suppress the lint "WrongConstant" error

Lint somehow complains that the integer resulting from the bit-manipulation shouldn't be passed as an @IntDef parameter.

#cherrypick

PiperOrigin-RevId: 648687698
(cherry picked from commit afe3826d7c4b79acfe0fd165ac1940261a147040)

* Update release notes for 1.4.0-rc01

PiperOrigin-RevId: 648745388
(cherry picked from commit 9277a34253799eb83d338313cb3ae6d6f73b5d4d)

* Version bump to 1.4.0-rc01

#cherrypick

PiperOrigin-RevId: 648982615
(cherry picked from commit b531d93b90cf28b455e1cde8625d6764a6a791ae)

* Merge release notes for media3 1.4.0 stable release

#cherrypick

PiperOrigin-RevId: 653261278
(cherry picked from commit 68e8d9cb689fae7b862b3383ad3a80eff8ba85ee)

* Fix the release notes for 1.4.0 stable release

#cherrypick

PiperOrigin-RevId: 653640574
(cherry picked from commit 1cbcd20851c035b4f268d20cb8fa438d0227f162)

* Update media3 version for 1.4.0 stable release

PiperOrigin-RevId: 653654999
(cherry picked from commit 3c9332bb480b23abc3bd61b96a5f5d6d29a3b11d)

* Fix the release notes for 1.4.0 stable release

#cherrypick

PiperOrigin-RevId: 655558346
(cherry picked from commit d70ff7e4d267a3329ed102167eb60d4c4a8e4544)

* Count down three playback states to match the assertion

PiperOrigin-RevId: 648629427
(cherry picked from commit ec3a58f8dba041b780fe6e84ea7106a7298f9090)

* Fix TTML handling of inherited percentage `tts:fontSize` values

The percentage should be interpreted as relative to the size of a parent
node.

This change makes this inheritance work correctly for percentages in
both the parent and child. It does not fix the case of a non-percentage
parent size with a percentage child size.

PiperOrigin-RevId: 649631055
(cherry picked from commit bb2fd002aef583b10eba9c497770c87a3be38839)

* Refactor audioEsdsBox to esdsBox

Since the muxer supported only AAC audio codec, the esdsBox was unconditionally created within the audioSampleEntry. This CL refactors the box creation logic by moving it to the codecSpecificBox method. This is to make adding support for new audio codecs easier.

PiperOrigin-RevId: 650130935
(cherry picked from commit a2693553698bf75a6874f2a5bd7fc8b855232372)

* Add support for amr-wb audio codec.

Implement damrBox to provide support for amr-wb audio codec.

Add unit test and an Android end to end test.

PiperOrigin-RevId: 650210732
(cherry picked from commit 6e18cb00533b9d66f75d36aa0a9b3c873e6f3b26)

* Destroy eglSurface as soon as Surface changes

eglDestroySurface now unbinds surface from the GL
thread to ensure quick release of resources.

PiperOrigin-RevId: 650938712
(cherry picked from commit 70a6b5d50d359a6d8288a70758ee2a3c402167f9)

* Support for Large CodecSpecificData in ESDS box

Some external media files have CodecSpecificData greater than 128 bytes. Currently, that size
isn't fitting in one byte. Hence, added support to store large CodecSpecificDataSize, as per
ISO standard, by extending to more than one byte as required.

PiperOrigin-RevId: 650972472
(cherry picked from commit cf90d2624d114cdd3cbc8516565409dd8bd48cb7)

* Add support to MPEG4 codec in Mp4Muxer.

Add support for MPEG4 codec to enable muxing video encoded with the mp4v-es codec. Use esdsBox method to generate esds box required for Mp4v box.

PiperOrigin-RevId: 651000744
(cherry picked from commit 34a802ef38e81389471d08c2574c6019d55d14fa)

* Transform double-tap of `HEADSETHOOK` to skip-to-next

As reported in Issue: androidx/media#1493 we already use `HEADSETHOOK` to start
waiting for a double-tap, but we don't consider it for the second tap.

Similarly, we previously considered `PLAY` for the second tap, but not the first.
Only `HEADSETHOOK` and `PLAY_PAUSE` are
[documented](https://developer.android.com/reference/androidx/media3/session/MediaSession#media-key-events-mapping)
to transform double-tap to `seekToNext`. So this change removes the
`PLAY` detection from the second tap.

PiperOrigin-RevId: 651017522
(cherry picked from commit c64dacf3df9097dc2c4535674a31dac4f568d344)

* Remove stray parenthesis from `MediaSession.ControllerInfo.toString()`

#cherrypick

PiperOrigin-RevId: 651760391
(cherry picked from commit 2c7f2686b77d9be213cdca70ee4b709d83f43922)

* Add support for 3gpp amr-nb audio codec.

To support AMR audio codec(audio/3gpp) add `0x81FF` mode to create damrBox.

Add unit test and an Android end to end test.

PiperOrigin-RevId: 652438693
(cherry picked from commit 11ca78761e268044abc85e591fb5a8c2be4d2fe1)

* Add support for 3gpp h263 codec in Mp4Muxer.

Implement d263Box to provide support for muxing video encoded with the h263 codec.

PiperOrigin-RevId: 653188633
(cherry picked from commit 951f2968519090bb2a1a1e3dcb9f5dab80958dfb)

* Add support for Opus audio codec.

Implement dOpsBox to provide support for Opus audio codec

PiperOrigin-RevId: 653288049
(cherry picked from commit 01dda6d3e5fa1737d7587b08a94c01594ed9711e)

* Add EXTRAS_KEY_DOWNLOAD_STATUS to MediaContants

This was used in media1 `MediaItemDescription` to indicate the download
status of a media item. When connected to a legacy
`MediaBrowserServiceCompat` the Media3 browsers converts the legacy
media item to a Media3 `MediaItem` and converts the extras of
`MediaDescriptionCompat.extras` to `MediaMetadata.extras`.

#cherrypick

PiperOrigin-RevId: 654625502
(cherry picked from commit 225ad482b13f2c9c661f2bf70300cdf948597fdf)

* Ensure EGLSurface is released on GL thread

Add VideoFrameProcessingTaskExecutor.invoke() method that blocks until
Task has executed on GL thread.
Use that for FinalShaderProgramWrapper.setOutputSurfaceInfo

PiperOrigin-RevId: 655119768
(cherry picked from commit 9c075b692e9e76959e47e9ad3cb018d3071f9154)

* Destroy EGLSurface immediately by focusing a placeholder surface

eglDestroySurface only destroys the surface when it's made not current.
Pass the placeholder surface in FinalShaderProgramWrapper and use it
when destroying eglSurface.

PiperOrigin-RevId: 655139661
(cherry picked from commit 1797359950fbf1acceddd7f40058cbd003383544)

* Add support for Audio Vorbis codec in Mp4Muxer.

Update esdsBox to support muxing of files encoded with Vorbis audio codec .

PiperOrigin-RevId: 655159074
(cherry picked from commit b77f1d0f99b3e287bc82883054b8ce54bab95fee)

* Merge pull request #1548 from kikoso:chore/fixed_links

PiperOrigin-RevId: 657138513
(cherry picked from commit f1ed195c10a124c52309bc49cc479bf35982e74b)

* Implement MP3 `ConstantBitrateSeeker.getDataEndPosition()`

This is needed to correctly handle files with trailing non-MP3 data
(which is indicated by the length in the `Info` frame being shorter than
the overall length of the file).

The test file was generated by appending 150kB of `DEADBEEF` onto the
end of `test-cbr-info-header.mp3`, and the test asserts that the
extracted samples are identical.

Issue: androidx/media#1480

PiperOrigin-RevId: 658727595
(cherry picked from commit b09cea9e3a3f9a039b77c6e6db3ee5f450becc50)

* Fixes README instructions for depending on modules locally

#cherrypick

PiperOrigin-RevId: 659504142
(cherry picked from commit e7eef0ce346d2567e3f51090bb64ee5fe7b8f727)

* Add a method to disallow VFP destroying shared eglContext

Previously in MultiInputVideoGraph, each VFP would destroy the shared
eglContext, such that the same eglContext object is destroyed multiple times.

Adding a flag to disallow this.

The alternative being we could add a flag on the VFP constructor, but I think
that is too subscriptive (meaning if we later might want to add another boolean
to control another GL behaviour, multiple booleans would make the class less
reason-able), and would incur a lot of code changes at places.

PiperOrigin-RevId: 660354367
(cherry picked from commit 8f8e48731eeedea8636d4d31be4a0c0b9a574bec)

* Fix `IndexOutOfBoundsException` in `LegacySubtitleUtil`

This is caused when the requested "output start time" is equal to or
larger than the last event time in a `Subtitle` object.

This resolves the error in Issue: androidx/media#1516, but subtitles are still not
renderered (probably because the timestamps aren't what we expect
somewhere, but I need to investigate this part further).

#cherrypick

PiperOrigin-RevId: 660462720
(cherry picked from commit 3763e5bc1da5c5cdb458add2e95eb4e683da5b64)

* Skip invalid media description in `SessionDescriptionParser`

Some RTSP servers may provide media descriptions for custom streams that are not supported. ExoPlayer should skip the invalid media description and continues parsing the following media descriptions.

To start, ExoPlayer will still error on malformed SDP lines for media descriptions, but will now skip media descriptions with "non-parsable" formats as described by [RFC 8866 Section 5.14](https://datatracker.ietf.org/doc/html/rfc8866#section-5.14).

Issue: androidx/media#1472
PiperOrigin-RevId: 660826116
(cherry picked from commit 8b33ad581140c8d667bf99c1ad754259be56be33)

* Pass missing `length` into `SubtitleParser` from `SubtitleExtractor`

If the length of the `ExtractorInput` is not known then the
`subtitleData` field is re-sized by 1kB each time
(`SubtitleExtractor.DEFAULT_BUFFER_SIZE`), so the end of the array is
often not populated. This change ensures that `length` is propagated to
`SubtitleParser`, so that implementations don't try and parse the
garbage/zero bytes at the end of the array.

Discovered while investigating Issue: androidx/media#1516

#cherrypick

PiperOrigin-RevId: 661195634
(cherry picked from commit f37f9690f489dbe83366c93c452faf70b272cae3)

* Handle `HEADSETHOOK` as 'play' in `MediaButtonReceiver.onReceive`

Issue: androidx/media#1581

PiperOrigin-RevId: 662515428
(cherry picked from commit c48c…
  • Loading branch information
1 parent 4b8f01c commit 22cc3d9
Show file tree
Hide file tree
Showing 2,497 changed files with 207,633 additions and 28,833 deletions.
8 changes: 6 additions & 2 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ body:
label: Version
description: What version of Media3 (or ExoPlayer) are you using?
options:
- Media3 1.2.1
- Media3 1.2.0
- Media3 main branch
- Media3 pre-release (alpha, beta or RC not in this list)
- Media3 1.4.1
- Media3 1.4.0
- Media3 1.3.1
- Media3 1.3.0
- Media3 1.2.1
- Media3 1.2.0
- Media3 1.1.1 / ExoPlayer 2.19.1
- Media3 1.1.0 / ExoPlayer 2.19.0
- Media3 1.0.2 / ExoPlayer 2.18.7
Expand Down
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,20 @@ First, clone the repository into a local directory:

```sh
git clone https://github.com/androidx/media.git
cd media
```

Next, add the following to your project's `settings.gradle.kts` file, replacing
`path/to/media` with the path to your local copy:

```kotlin
gradle.extra.apply {
set("androidxMediaModulePrefix", "media-")
}
(gradle as ExtensionAware).extra["androidxMediaModulePrefix"] = "media3-"
apply(from = file("path/to/media/core_settings.gradle"))
```

Or in Gradle Groovy DSL `settings.gradle`:

```groovy
gradle.ext.androidxMediaModulePrefix = 'media-'
gradle.ext.androidxMediaModulePrefix = 'media3-'
apply from: file("path/to/media/core_settings.gradle")
```

Expand All @@ -141,17 +138,37 @@ You can depend on them from `build.gradle.kts` as you would on any other local
module, for example:

```kotlin
implementation(project(":media-lib-exoplayer"))
implementation(project(":media-lib-exoplayer-dash"))
implementation(project(":media-lib-ui"))
implementation(project(":media3-lib-exoplayer"))
implementation(project(":media3-lib-exoplayer-dash"))
implementation(project(":media3-lib-ui"))
```

Or in Gradle Groovy DSL `build.gradle`:

```groovy
implementation project(':media-lib-exoplayer')
implementation project(':media-lib-exoplayer-dash')
implementation project(':media-lib-ui')
implementation project(':media3-lib-exoplayer')
implementation project(':media3-lib-exoplayer-dash')
implementation project(':media3-lib-ui')
```

#### MIDI module

By default the [MIDI module](libraries/decoder_midi) is disabled as a local
dependency, because it requires additional Maven repository config. If you want
to use it as a local dependency, please configure the JitPack repository as
[described in the module README](libraries/decoder_midi/README.md#getting-the-module),
and then enable building the module in your `settings.gradle.kts` file:

```kotlin
gradle.extra.apply {
set("androidxMediaEnableMidiModule", true)
}
```

Or in Gradle Groovy DSL `settings.gradle`:

```groovy
gradle.ext.androidxMediaEnableMidiModule = true
```

## Developing AndroidX Media
Expand Down
747 changes: 747 additions & 0 deletions RELEASENOTES.md

Large diffs are not rendered by default.

57 changes: 50 additions & 7 deletions api.txt

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.0.1'
classpath 'com.android.tools.build:gradle:8.3.2'
classpath 'com.google.android.gms:strict-version-matcher-plugin:1.2.4'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0'
}
}
allprojects {
Expand Down
5 changes: 3 additions & 2 deletions common_library_config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ android {
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
aarMetadata {
minCompileSdk = project.ext.compileSdkVersion
}
multiDexEnabled true
}

compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand All @@ -43,5 +45,4 @@ android {

dependencies {
androidTestImplementation 'androidx.multidex:multidex:' + androidxMultidexVersion
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
26 changes: 14 additions & 12 deletions constants.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
project.ext {
releaseVersion = '1.2.1-dr10'
releaseVersionCode = 1_002_001_3_00
minSdkVersion = 16
releaseVersion = '1.4.1-dr1'
releaseVersionCode = 1_004_001_3_00
minSdkVersion = 19
// See https://developer.android.com/training/cars/media/automotive-os#automotive-module
automotiveMinSdkVersion = 28
appTargetSdkVersion = 34
Expand All @@ -23,17 +23,21 @@ project.ext {
targetSdkVersion = 30
compileSdkVersion = 34
dexmakerVersion = '2.28.3'
// Use the same JUnit version as the Android repo:
// https://cs.android.com/android/platform/superproject/main/+/main:external/junit/METADATA
junitVersion = '4.13.2'
// Use the same Guava version as the Android repo:
// https://cs.android.com/android/platform/superproject/main/+/main:external/guava/METADATA
guavaVersion = '31.1-android'
guavaVersion = '33.0.0-android'
kotlinxCoroutinesVersion = '1.8.1'
leakCanaryVersion = '2.10'
mockitoVersion = '3.12.4'
robolectricVersion = '4.10.3'
robolectricVersion = '4.11'
// Keep this in sync with Google's internal Checker Framework version.
checkerframeworkVersion = '3.13.0'
errorProneVersion = '2.18.0'
jsr305Version = '3.0.2'
kotlinAnnotationsVersion = '1.8.20'
kotlinAnnotationsVersion = '1.9.0'
// Updating this to 1.4.0+ will import Kotlin stdlib [internal ref: b/277891049].
androidxAnnotationVersion = '1.3.0'
androidxAnnotationExperimentalVersion = '1.3.1'
Expand All @@ -43,9 +47,8 @@ project.ext {
// Updating this to 1.9.0+ will import Kotlin stdlib [internal ref: b/277891049].
androidxCoreVersion = '1.8.0'
androidxExifInterfaceVersion = '1.3.6'
androidxFuturesVersion = '1.1.0'
androidxMediaVersion = '1.6.0'
androidxMedia2Version = '1.2.1'
androidxLifecycleVersion = '2.6.0'
androidxMediaVersion = '1.7.0'
androidxMultidexVersion = '2.0.1'
androidxRecyclerViewVersion = '1.3.0'
androidxMaterialVersion = '1.8.0'
Expand All @@ -54,10 +57,9 @@ project.ext {
androidxTestJUnitVersion = '1.1.5'
androidxTestRunnerVersion = '1.5.2'
androidxTestRulesVersion = '1.5.0'
androidxTestServicesStorageVersion = '1.4.2'
androidxTestTruthVersion = '1.5.0'
truthVersion = '1.1.3'
okhttpVersion = '4.11.0'
truthVersion = '1.4.0'
okhttpVersion = '4.12.0'
modulePrefix = ':'
if (gradle.ext.has('androidxMediaModulePrefix')) {
modulePrefix += gradle.ext.androidxMediaModulePrefix
Expand Down
12 changes: 6 additions & 6 deletions core_settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ include modulePrefix + 'lib-datasource'
project(modulePrefix + 'lib-datasource').projectDir = new File(rootDir, 'libraries/datasource')
include modulePrefix + 'lib-datasource-cronet'
project(modulePrefix + 'lib-datasource-cronet').projectDir = new File(rootDir, 'libraries/datasource_cronet')
include modulePrefix + 'lib-datasource-httpengine'
project(modulePrefix + 'lib-datasource-httpengine').projectDir = new File(rootDir, 'libraries/datasource_httpengine')
include modulePrefix + 'lib-datasource-rtmp'
project(modulePrefix + 'lib-datasource-rtmp').projectDir = new File(rootDir, 'libraries/datasource_rtmp')
include modulePrefix + 'lib-datasource-okhttp'
Expand All @@ -70,8 +72,10 @@ include modulePrefix + 'lib-decoder-ffmpeg'
project(modulePrefix + 'lib-decoder-ffmpeg').projectDir = new File(rootDir, 'libraries/decoder_ffmpeg')
include modulePrefix + 'lib-decoder-flac'
project(modulePrefix + 'lib-decoder-flac').projectDir = new File(rootDir, 'libraries/decoder_flac')
include modulePrefix + 'lib-decoder-midi'
project(modulePrefix + 'lib-decoder-midi').projectDir = new File(rootDir, 'libraries/decoder_midi')
if (gradle.ext.has('androidxMediaEnableMidiModule') && gradle.ext.androidxMediaEnableMidiModule) {
include modulePrefix + 'lib-decoder-midi'
project(modulePrefix + 'lib-decoder-midi').projectDir = new File(rootDir, 'libraries/decoder_midi')
}
include modulePrefix + 'lib-decoder-opus'
project(modulePrefix + 'lib-decoder-opus').projectDir = new File(rootDir, 'libraries/decoder_opus')
include modulePrefix + 'lib-decoder-vp9'
Expand All @@ -98,7 +102,3 @@ include modulePrefix + 'test-data'
project(modulePrefix + 'test-data').projectDir = new File(rootDir, 'libraries/test_data')
include modulePrefix + 'test-utils'
project(modulePrefix + 'test-utils').projectDir = new File(rootDir, 'libraries/test_utils')
include modulePrefix + 'test-session-common'
project(modulePrefix + 'test-session-common').projectDir = new File(rootDir, 'libraries/test_session_common')
include modulePrefix + 'test-session-current'
project(modulePrefix + 'test-session-current').projectDir = new File(rootDir, 'libraries/test_session_current')
2 changes: 1 addition & 1 deletion demos/cast/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ apply plugin: 'com.android.application'
android {
namespace 'androidx.media3.demo.cast'

compileSdkVersion project.ext.compileSdkVersion
compileSdk project.ext.compileSdkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.dynamite.DynamiteModule;
import com.google.common.util.concurrent.MoreExecutors;

/**
* An activity that plays video using {@link ExoPlayer} and supports casting using ExoPlayer's Cast
Expand All @@ -65,7 +66,7 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Getting the cast context later than onStart can cause device discovery not to take place.
try {
castContext = CastContext.getSharedInstance(this);
castContext = CastContext.getSharedInstance(this, MoreExecutors.directExecutor()).getResult();
} catch (RuntimeException e) {
Throwable cause = e.getCause();
while (cause != null) {
Expand Down
14 changes: 14 additions & 0 deletions demos/compose/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# ExoPlayer demo with Compose integration

This is an experimental ExoPlayer demo app that is built fully using Compose
features. This should be taken as Work-In-Progress, rather than experimental API
for testing out application development with the media3 and Jetpack Compose
libraries. Please await further announcement via Release Notes for when the
implementation is fully integrated into the library.

For an intermediate solution, use Jetpack Compose Interop with AndroidView and
PlayerView. However, note that it provides limited functionality and some
features may not be supported.

See the [demos README](../README.md) for instructions on how to build and run
this demo.
76 changes: 76 additions & 0 deletions demos/compose/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
apply from: '../../constants.gradle'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
namespace 'androidx.media3.demo.compose'

compileSdk project.ext.compileSdkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = '1.8'
}

defaultConfig {
versionName project.ext.releaseVersion
versionCode project.ext.releaseVersionCode
minSdkVersion 21
targetSdkVersion project.ext.appTargetSdkVersion
}

buildTypes {
release {
shrinkResources true
minifyEnabled true
signingConfig signingConfigs.debug
}
debug {
jniDebuggable = true
}
}

lintOptions {
// The demo app isn't indexed, and doesn't have translations.
disable 'GoogleAppIndexingWarning','MissingTranslation'
}
buildFeatures {
viewBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.0"
}
}

dependencies {
def composeBom = platform('androidx.compose:compose-bom:2024.05.00')
implementation composeBom

implementation 'androidx.activity:activity-compose:1.9.0'
implementation 'androidx.compose.foundation:foundation-android:1.6.7'
implementation 'androidx.compose.material3:material3-android:1.2.1'
implementation 'com.google.android.material:material:' + androidxMaterialVersion

implementation project(modulePrefix + 'lib-exoplayer')

// For detecting and debugging leaks only. LeakCanary is not needed for demo app to work.
debugImplementation 'com.squareup.leakcanary:leakcanary-android:' + leakCanaryVersion
}
38 changes: 38 additions & 0 deletions demos/compose/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="androidx.media3.demo.compose">

<uses-sdk/>
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.Media3ComposeDemo">

<activity
android:name="androidx.media3.demo.compose.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Loading

0 comments on commit 22cc3d9

Please sign in to comment.