Skip to content

Commit 624e46c

Browse files
authored
Merge branch 'main' into media3log
2 parents 0868535 + 5fc6781 commit 624e46c

File tree

325 files changed

+9766
-1200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

325 files changed

+9766
-1200
lines changed

RELEASENOTES.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
* Add `void mute()` and `void unmute()` methods to Player that preserve
1010
and consequently restore Player's volume before and after setting it to
1111
zero.
12+
* Publish utility classes `WakeLockManager`, `WifiLockManager`,
13+
`AudioFocusManager`, `AudioBecomingNoisyManager` and
14+
`StuckPlayerDetector` previously used by `ExoPlayer` internally to allow
15+
reuse for other players
16+
([#1893](https://github.com/androidx/media/issues/1893)).
1217
* Fix `ForwardingPlayer` listener handling when the underlying delegate
1318
player uses reference equality for comparing listener instances
1419
([#2675](https://github.com/androidx/media/issues/2675)).
@@ -37,6 +42,10 @@
3742
`ExoPlayer.Builder.setWakeMode` to `C.WAKE_MODE_LOCAL`.
3843
* Ensure renderers don't consume data from the next playlist item more
3944
than 10 seconds before the end of the current item.
45+
* Add `setSeekBackIncrementMs`, `setSeekForwardIncrementMs` and
46+
`setMaxSeekToPreviousPositionMs` to `ExoPlayer` to update these settings
47+
after construction
48+
([#2736](https://github.com/androidx/media/issues/2736)).
4049
* Add pre-caching functionality in `DefaultPreloadManager`. Apps now can
4150
return
4251
`DefaultPreloadManager.PreloadStatus.specifiedRangeCached(startPositionMs,
@@ -94,6 +103,12 @@
94103
* Add support for `COMMAND_SET_AUDIO_ATTRIBUTES` and audio focus handling
95104
in `CompositionPlayer`.
96105
* Use `InAppMp4Muxer` as default muxer.
106+
* Add `EditedMediaItem.Builder#setSpeed()` and deprecate
107+
`Effects#createExperimentalSpeedChangingEffects()`.
108+
* Add support for speed changing in secondary sequences in
109+
`CompositionPlayer`.
110+
* Replace `forceAudioTrack` and `forceVideoTrack` with `trackTypes` in
111+
`EditedMediaItemSequence`.
97112
* Track Selection:
98113
* Add `TrackSelectionParameters.selectTextByDefault` to prefer the
99114
selection of any text track without specifying other more specific
@@ -132,6 +147,11 @@
132147
the whole file).
133148
* Add support for extracting HEIC Motion Photos. The `HeifExtractor` can
134149
now parse HEIC files containing embedded video and audio tracks.
150+
* MP3: Change `FLAG_ENABLE_INDEX_SEEKING` to prefer seeking information
151+
from metadata headers (like Xing and VBRI) when available, falling back
152+
to index-based seeking if no other seeking information is present. This
153+
improves performance for files with seeking metadata
154+
([#2839](https://github.com/androidx/media/issues/2839)).
135155
* Inspector:
136156
* Introduced a new `:media3-inspector` module to serve as the dedicated
137157
home for media inspection utilities. This module now houses a new
@@ -144,6 +164,9 @@
144164
extract frames with support for HDR video, video effects, and custom
145165
decoder selection. It should be created via its `Builder` for a specific
146166
`MediaItem`.
167+
* FrameExtractor: Add `getThumbnail()` to extract a representative
168+
thumbnail frame from a media file without requiring a specific
169+
timestamp.
147170
* DataSource:
148171
* Audio:
149172
* Make `AudioProcessor` instances aware of seeking.
@@ -159,6 +182,7 @@
159182
* Add support for float PCM samples in `Sonic`.
160183
* Add support for 16 bit PCM samples in `ToFloatPcmAudioProcessor`.
161184
* Video:
185+
* Disable codec reuse for Dolby-Vision content with different profiles.
162186
* Text:
163187
* Fix parsing of CEA-6/708 subtitles in Dolby Vision content
164188
([#2775](https://github.com/androidx/media/issues/2775)).
@@ -174,6 +198,7 @@
174198
* Add key request info like URL and latency to
175199
`AnalyticsListener.onDrmKeysLoaded`
176200
([#1001](https://github.com/androidx/media/issues/1001)).
201+
* Move provisioning request data from a URL parameter to the POST body.
177202
* Effect:
178203
* Muxers:
179204
* Add `MediaMuxerCompat`, a drop-in replacement for framework
@@ -191,6 +216,16 @@
191216
are optional but recommended for Full service stream requests. To find
192217
the network code, see
193218
[this article](http://support.google.com/admanager/answer/7674889).
219+
* Bump IMA dependency to 3.37.0 which requires enabling core library
220+
desugaring. This must also be enabled by dependent apps too. See IMA's
221+
[config notes](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/get-started#2.-add-the-ima-sdk-to-your-project).
222+
* Support IMA DAI custom UI options in SSAI URI builder. Custom UI options
223+
for server side ad insertion include “Skippable” and “About This Ad”
224+
rendering support. The feature is currently available for selected
225+
publishers behind an allow list. This change also upgrades the IMA SDK
226+
version to 3.38.0
227+
([release notes](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/history))
228+
to access the custom UI options API.
194229
* Session:
195230
* Add new parameter to `MediaSession.Callback.onPlaybackResumption` to
196231
indicate if the call happens to gather information only or to start
@@ -232,6 +267,10 @@
232267
media key event `Intent` arriving in `onStartCommand()`. This is fixed
233268
by handling 'KEYCODE_HEADSETHOOK' just like `KEYCODE_MEDIA_PLAY_PAUSE`
234269
([#2816](https://github.com/androidx/media/pull/2816)).
270+
* Fix a bug where Surface size was not communicated between the session
271+
and the controller, resulting in the failure to apply video effects in
272+
demo-session. If you are using a controller, this might be a breaking
273+
change if your player cannot handle a `setVideoSurfaceHolder` call.
235274
* UI:
236275
* Add `ProgressStateWithTickInterval` class and the corresponding
237276
`rememberProgressStateWithTickInterval` Composable to
@@ -247,6 +286,12 @@
247286
* Add `ContentFrame` Composable to `media3-ui-compose` which combines
248287
`PlayerSurface` management with aspect ratio resizing and covering with
249288
a shutter.
289+
* Work around a known API 34 platform bug causing stretched/cropped videos
290+
when using `SurfaceView` inside a Compose `AndroidView` and hence
291+
affecting `ContentFrame` and `PlayerSurface` Composables with
292+
`SURFACE_TYPE_SURFACE_VIEW`
293+
([#1237](https://github.com/androidx/media/issues/1237),
294+
[#2811](https://github.com/androidx/media/issues/2811)).
250295
* Create a new `media3-ui-compose-material3` module and add
251296
Material3-themed Composables (PlayPauseButton, NextButton,
252297
PreviousButton, SeekBackButton, SeekForwardButton, RepeatButton,
@@ -270,6 +315,9 @@
270315
* Reset `LiveConfiguration` to the value provided by the `MediaItem` of
271316
the `DashMediaSource` when released and when the media item is updated
272317
by the user ([#2606](https://github.com/androidx/media/issues/2606)).
318+
* Avoid crashes caused by invalid manifest updates that were not reported
319+
as player errors
320+
([#2805](https://github.com/androidx/media/issues/2805))).
273321
* Smooth Streaming extension:
274322
* RTSP extension:
275323
* Handle error of missing RTP packets when processing fragmented NAL units
@@ -292,6 +340,8 @@
292340
use in `DefaultCastOptionsProvider#toMediaQueueItem`, when available.
293341
* Enable remote to local transfers in `DefaultCastOptionsProvider`.
294342
* Add support for Cast in the Session demo.
343+
* Add support for displaying a media route button on a Composable UI.
344+
* Add support for displaying a media route button on an action bar menu.
295345
* Test Utilities:
296346
* Add maximum time diff for the auto-advancing behavior of `FakeClock`. It
297347
defaults to 1 second, but is configurable via `FakeClock.Builder`.

constants.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ project.ext {
6262
androidxTestRunnerVersion = '1.5.2'
6363
androidxTestRulesVersion = '1.5.0'
6464
androidxTestTruthVersion = '1.5.0'
65+
desugarJdkLibsVersion = '2.1.5'
6566
lottieVersion = '6.6.0'
6667
truthVersion = '1.4.0'
6768
okhttpVersion = '4.12.0'

demos/compose/src/main/java/androidx/media3/demo/compose/data/videos.kt

Lines changed: 0 additions & 24 deletions
This file was deleted.

demos/composition/src/main/java/androidx/media3/demo/composition/CompositionPreviewActivity.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ import android.Manifest
1919
import android.content.pm.ActivityInfo
2020
import android.content.pm.PackageManager
2121
import android.graphics.Bitmap
22+
import android.graphics.Color
2223
import android.os.Build.VERSION.SDK_INT
2324
import android.os.Bundle
2425
import android.os.LocaleList
26+
import android.view.SurfaceView
27+
import android.view.View.INVISIBLE
28+
import android.view.View.VISIBLE
2529
import androidx.activity.compose.BackHandler
2630
import androidx.activity.compose.setContent
2731
import androidx.activity.enableEdgeToEdge
@@ -84,6 +88,7 @@ import androidx.compose.material3.adaptive.navigation.rememberSupportingPaneScaf
8488
import androidx.compose.runtime.Composable
8589
import androidx.compose.runtime.LaunchedEffect
8690
import androidx.compose.runtime.getValue
91+
import androidx.compose.runtime.key
8792
import androidx.compose.runtime.mutableStateOf
8893
import androidx.compose.runtime.remember
8994
import androidx.compose.runtime.rememberCoroutineScope
@@ -261,6 +266,24 @@ class CompositionPreviewActivity : AppCompatActivity() {
261266
playerView.player = viewModel.compositionPlayer
262267
playerView.setTimeBarScrubbingEnabled(!isOverlayPlacementActive)
263268
playerView.setUseController(!isOverlayPlacementActive)
269+
// TODO: b/449957627 - Remove once internal pipeline is migrated to FrameConsumer.
270+
if (viewModel.frameConsumerEnabled) {
271+
playerView.setShutterBackgroundColor(Color.TRANSPARENT)
272+
viewModel.outputRenderer.setOutputSurface(
273+
(playerView.videoSurfaceView as SurfaceView).holder.surface
274+
)
275+
// Workaround to ensure the Surface is recreated when switching from CPU to GPU
276+
// rendering.
277+
if (SDK_INT >= 34) {
278+
(playerView.videoSurfaceView as SurfaceView).setSurfaceLifecycle(
279+
SurfaceView.SURFACE_LIFECYCLE_FOLLOWS_VISIBILITY
280+
)
281+
}
282+
} else {
283+
playerView.setShutterBackgroundColor(Color.BLACK)
284+
}
285+
playerView.videoSurfaceView?.visibility = INVISIBLE
286+
playerView.videoSurfaceView?.visibility = VISIBLE
264287
},
265288
modifier = Modifier.fillMaxSize(),
266289
)
@@ -333,6 +356,20 @@ class CompositionPreviewActivity : AppCompatActivity() {
333356
},
334357
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
335358
)
359+
Row(
360+
verticalAlignment = Alignment.CenterVertically,
361+
horizontalArrangement = Arrangement.SpaceBetween,
362+
modifier = Modifier.fillMaxWidth(),
363+
) {
364+
Text(
365+
text = stringResource(R.string.frame_consumer_enabled),
366+
modifier = Modifier.textPadding(),
367+
)
368+
Switch(
369+
checked = uiState.outputSettingsState.frameConsumerEnabled,
370+
onCheckedChange = { isEnabled -> viewModel.onFrameConsumerEnabledChanged(isEnabled) },
371+
)
372+
}
336373

337374
Row(
338375
verticalAlignment = Alignment.CenterVertically,

demos/composition/src/main/java/androidx/media3/demo/composition/CompositionPreviewViewModel.kt

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import androidx.lifecycle.ViewModelProvider
3030
import androidx.lifecycle.viewModelScope
3131
import androidx.media3.common.AudioAttributes
3232
import androidx.media3.common.Effect
33+
import androidx.media3.common.GlObjectsProvider
3334
import androidx.media3.common.MediaItem
3435
import androidx.media3.common.OverlaySettings
3536
import androidx.media3.common.PlaybackException
@@ -50,6 +51,7 @@ import androidx.media3.demo.composition.data.OverlayAsset
5051
import androidx.media3.demo.composition.data.OverlayState
5152
import androidx.media3.demo.composition.data.PlacedOverlay
5253
import androidx.media3.demo.composition.data.PlacementState
54+
import androidx.media3.demo.composition.effect.DemoRenderingFrameConsumer
5355
import androidx.media3.demo.composition.effect.LottieEffectFactory
5456
import androidx.media3.effect.BitmapOverlay
5557
import androidx.media3.effect.DebugTraceUtil
@@ -75,6 +77,7 @@ import com.google.common.base.Ticker
7577
import java.io.File
7678
import java.io.IOException
7779
import java.util.UUID
80+
import java.util.concurrent.ExecutorService
7881
import java.util.concurrent.TimeUnit
7982
import kotlin.math.cos
8083
import kotlin.math.roundToInt
@@ -94,8 +97,24 @@ class CompositionPreviewViewModel(application: Application) : AndroidViewModel(a
9497
val uiState: StateFlow<CompositionPreviewState> = _uiState.asStateFlow()
9598

9699
var compositionPlayer by mutableStateOf(createCompositionPlayer())
100+
var refreshPlayerViewKey by mutableStateOf(0)
97101
val EXPORT_ERROR_MESSAGE = application.resources.getString(R.string.export_error)
98102
val EXPORT_STARTED_MESSAGE = application.resources.getString(R.string.export_started)
103+
internal var frameConsumerEnabled: Boolean = false
104+
internal val outputRenderer: DemoRenderingFrameConsumer by lazy {
105+
DemoRenderingFrameConsumer(glExecutorService) { error ->
106+
_uiState.update { currentState ->
107+
currentState.copy(snackbarMessage = "Preview error: $error")
108+
}
109+
Log.e(TAG, "Preview error", error)
110+
}
111+
}
112+
private val glExecutorService: ExecutorService by lazy {
113+
Util.newSingleThreadExecutor("CompositionDemo::GlThread")
114+
}
115+
private val glObjectsProvider: GlObjectsProvider by lazy {
116+
DemoRenderingFrameConsumer.SingleContextGlObjectsProvider()
117+
}
99118
private var transformer: Transformer? = null
100119
private var outputFile: File? = null
101120
private var exportStopwatch: Stopwatch =
@@ -196,6 +215,13 @@ class CompositionPreviewViewModel(application: Application) : AndroidViewModel(a
196215
DebugTraceUtil.enableTracing = enable
197216
}
198217

218+
fun onFrameConsumerEnabledChanged(isEnabled: Boolean) {
219+
_uiState.update {
220+
it.copy(outputSettingsState = it.outputSettingsState.copy(frameConsumerEnabled = isEnabled))
221+
}
222+
previewComposition()
223+
}
224+
199225
fun onIncludeBackgroundAudioChanged(isEnabled: Boolean) {
200226
_uiState.update {
201227
it.copy(outputSettingsState = it.outputSettingsState.copy(includeBackgroundAudio = isEnabled))
@@ -738,7 +764,13 @@ class CompositionPreviewViewModel(application: Application) : AndroidViewModel(a
738764

739765
private fun createCompositionPlayer(): CompositionPlayer {
740766
val playerBuilder = CompositionPlayer.Builder(getApplication())
741-
if (uiState.value.compositionLayout != COMPOSITION_LAYOUT[0]) {
767+
frameConsumerEnabled = uiState.value.outputSettingsState.frameConsumerEnabled
768+
if (uiState.value.outputSettingsState.frameConsumerEnabled) {
769+
playerBuilder.setGlThreadExecutorService(glExecutorService)
770+
playerBuilder.setGlObjectsProvider(glObjectsProvider)
771+
uiState.value.outputSurface?.let { outputRenderer.setOutputSurface(it) }
772+
playerBuilder.experimentalSetFrameConsumer(outputRenderer::queue)
773+
} else if (uiState.value.compositionLayout != COMPOSITION_LAYOUT[0]) {
742774
playerBuilder.setVideoGraphFactory(MultipleInputVideoGraph.Factory())
743775
}
744776
playerBuilder.setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true)

demos/composition/src/main/java/androidx/media3/demo/composition/data/CompositionState.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package androidx.media3.demo.composition.data
1717

1818
import android.graphics.Bitmap
19+
import android.view.Surface
1920
import androidx.compose.ui.geometry.Offset
2021
import androidx.compose.ui.geometry.Size
2122
import androidx.media3.common.util.UnstableApi
@@ -39,6 +40,7 @@ import java.util.UUID
3940
*/
4041
@UnstableApi
4142
data class CompositionPreviewState(
43+
val outputSurface: Surface? = null,
4244
val availableLayouts: List<String> = emptyList(),
4345
val compositionLayout: String,
4446
val snackbarMessage: String? = null,
@@ -153,6 +155,7 @@ sealed interface PlacementState {
153155
*/
154156
@UnstableApi
155157
data class OutputSettingsState(
158+
val frameConsumerEnabled: Boolean = false,
156159
val includeBackgroundAudio: Boolean = false,
157160
val resolutionHeight: String,
158161
val hdrMode: Int,

0 commit comments

Comments
 (0)