From cb8ae66f52be691a437b5d0125c2402d8dbc7d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaquim=20St=C3=A4hli?= Date: Thu, 25 Jan 2024 15:02:15 +0100 Subject: [PATCH] 400 single showcase file (#410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gaƫtan Muller --- .../demo/ui/player/SimplePlayerActivity.kt | 21 +++--- .../demo/ui/showcases/ShowcasesNavigation.kt | 4 +- .../integrations/MediaControllerActivity.kt | 20 +++--- .../demo/ui/showcases/layouts/SimpleStory.kt | 68 ++++++++++-------- .../ui/showcases/layouts/StoryLoadControl.kt | 41 ----------- .../ui/showcases/layouts/StoryViewModel.kt | 3 - .../ui/showcases/misc/MultiPlayerShowcase.kt | 52 +++++++++++--- .../ui/showcases/misc/MultiPlayerViewModel.kt | 69 ------------------- ...Showcase.kt => ResizablePlayerShowcase.kt} | 12 +++- .../misc/StartAtGivenTimeShowcase.kt | 11 ++- .../misc/UpdatableMediaItemShowcase.kt | 7 ++ 11 files changed, 129 insertions(+), 179 deletions(-) delete mode 100644 pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryLoadControl.kt delete mode 100644 pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerViewModel.kt rename pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/{AdaptivePlayerShowcase.kt => ResizablePlayerShowcase.kt} (95%) diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt index 2088c23f0..b284367ea 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/player/SimplePlayerActivity.kt @@ -25,8 +25,8 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle import androidx.media3.common.Player import ch.srgssr.pillarbox.analytics.SRGAnalytics import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost @@ -72,21 +72,17 @@ class SimplePlayerActivity : ComponentActivity(), ServiceConnection { val ilHost = (intent.extras?.getSerializable(ARG_IL_HOST) as URL?) ?: IlHost.DEFAULT playerViewModel = ViewModelProvider(this, factory = SimplePlayerViewModel.Factory(application, ilHost))[SimplePlayerViewModel::class.java] readIntent(intent) - lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.RESUMED) { - SRGAnalytics.trackPagView(DemoPageView("simple player", levels = listOf("app", "pillarbox"))) - } - } - lifecycleScope.launchWhenCreated { - playerViewModel.pictureInPictureRatio.collectLatest { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && playerViewModel.pictureInPictureEnabled.value) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + lifecycleScope.launch { + playerViewModel.pictureInPictureRatio.flowWithLifecycle(lifecycle, Lifecycle.State.CREATED).collectLatest { val params = PictureInPictureParams.Builder() - .setAspectRatio(playerViewModel.pictureInPictureRatio.value) + .setAspectRatio(it) .build() setPictureInPictureParams(params) } } } + // Bind PlaybackService to allow background playback and MediaNotification. bindPlaybackService() setContent { @@ -166,6 +162,11 @@ class SimplePlayerActivity : ComponentActivity(), ServiceConnection { } } + override fun onResume() { + super.onResume() + SRGAnalytics.trackPagView(DemoPageView("simple player", levels = listOf("app", "pillarbox"))) + } + override fun onStart() { super.onStart() playerViewModel.player.play() diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowcasesNavigation.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowcasesNavigation.kt index b8ae0a4d6..d5e255a47 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowcasesNavigation.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/ShowcasesNavigation.kt @@ -12,8 +12,8 @@ import ch.srgssr.pillarbox.demo.shared.ui.NavigationRoutes import ch.srgssr.pillarbox.demo.ui.showcases.integrations.ExoPlayerShowcase import ch.srgssr.pillarbox.demo.ui.showcases.layouts.SimpleLayoutShowcase import ch.srgssr.pillarbox.demo.ui.showcases.layouts.StoryLayoutShowcase -import ch.srgssr.pillarbox.demo.ui.showcases.misc.AdaptivePlayerShowcase import ch.srgssr.pillarbox.demo.ui.showcases.misc.MultiPlayerShowcase +import ch.srgssr.pillarbox.demo.ui.showcases.misc.ResizablePlayerShowcase import ch.srgssr.pillarbox.demo.ui.showcases.misc.SmoothSeekingShowcase import ch.srgssr.pillarbox.demo.ui.showcases.misc.StartAtGivenTimeShowcase import ch.srgssr.pillarbox.demo.ui.showcases.misc.TrackingToggleShowcase @@ -33,7 +33,7 @@ fun NavGraphBuilder.showcasesNavGraph(navController: NavController) { SimpleLayoutShowcase() } composable(NavigationRoutes.adaptive, DemoPageView("adaptive player", Levels)) { - AdaptivePlayerShowcase() + ResizablePlayerShowcase() } composable(NavigationRoutes.playerSwap, DemoPageView("multiplayer", Levels)) { MultiPlayerShowcase() diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/integrations/MediaControllerActivity.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/integrations/MediaControllerActivity.kt index 6a6af2410..bacd227a8 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/integrations/MediaControllerActivity.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/integrations/MediaControllerActivity.kt @@ -20,8 +20,8 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle +import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle import androidx.media3.common.Player import ch.srgssr.pillarbox.analytics.SRGAnalytics import ch.srgssr.pillarbox.demo.DemoPageView @@ -43,16 +43,11 @@ class MediaControllerActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.RESUMED) { - SRGAnalytics.trackPagView(DemoPageView("media controller player", levels = listOf("app", "pillarbox"))) - } - } - lifecycleScope.launchWhenCreated { - controllerViewModel.pictureInPictureRatio.collectLatest { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && controllerViewModel.pictureInPictureEnabled.value) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + lifecycleScope.launch { + controllerViewModel.pictureInPictureRatio.flowWithLifecycle(lifecycle, Lifecycle.State.CREATED).collectLatest { val params = PictureInPictureParams.Builder() - .setAspectRatio(controllerViewModel.pictureInPictureRatio.value) + .setAspectRatio(it) .build() setPictureInPictureParams(params) } @@ -111,4 +106,9 @@ class MediaControllerActivity : ComponentActivity() { controllerViewModel.pictureInPictureEnabled.value = isInPictureInPictureMode } } + + override fun onResume() { + super.onResume() + SRGAnalytics.trackPagView(DemoPageView("media controller player", levels = listOf("app", "pillarbox"))) + } } diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/SimpleStory.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/SimpleStory.kt index 23ae136c8..2ce51b54a 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/SimpleStory.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/SimpleStory.kt @@ -4,22 +4,29 @@ */ package ch.srgssr.pillarbox.demo.ui.showcases.layouts +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.PagerDefaults +import androidx.compose.foundation.pager.PagerSnapDistance import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.viewinterop.AndroidView +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.LifecycleStartEffect import androidx.media3.common.C import androidx.media3.common.Player -import androidx.media3.ui.AspectRatioFrameLayout -import androidx.media3.ui.PlayerView import ch.srgssr.pillarbox.demo.shared.data.DemoItem import ch.srgssr.pillarbox.demo.shared.data.Playlist import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.player.PillarboxPlayer +import ch.srgssr.pillarbox.ui.ScaleMode +import ch.srgssr.pillarbox.ui.widget.player.PlayerSurface /** * A sample trying to reproduce story like TikTok. @@ -29,13 +36,19 @@ import ch.srgssr.pillarbox.player.PillarboxPlayer @Composable fun SimpleStory() { val playlist = remember { - Playlist.VideoUrls + Playlist.VideoUrns } val pagerState = rememberPagerState { playlist.items.size } HorizontalPager( modifier = Modifier.fillMaxHeight(), key = { page -> playlist.items[page].uri }, + beyondBoundsPageCount = 1, + flingBehavior = PagerDefaults.flingBehavior( + state = pagerState, + pagerSnapDistance = PagerSnapDistance.atMost(0), + snapAnimationSpec = spring(stiffness = Spring.StiffnessHigh) + ), state = pagerState ) { page -> SimpleStoryPlayer(demoItem = playlist.items[page], isPlaying = pagerState.currentPage == page) @@ -51,29 +64,30 @@ fun SimpleStory() { */ @Composable private fun SimpleStoryPlayer(demoItem: DemoItem, isPlaying: Boolean = false) { - AndroidView( - factory = { context -> - val player = PillarboxPlayer( - context = context, - mediaItemSource = PlayerModule.provideMixedItemSource(context), - loadControl = StoryLoadControl.build() - ).apply { - setMediaItem(demoItem.toMediaItem()) - prepare() - videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING - repeatMode = Player.REPEAT_MODE_ONE - playWhenReady = isPlaying - } - - PlayerView(context).apply { - hideController() - useController = false - resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM - this.player = player - } - }, - onRelease = { - it.player?.release() + val context = LocalContext.current + val player = remember(demoItem) { + PlayerModule.provideDefaultPlayer(context).apply { + setMediaItem(demoItem.toMediaItem()) + videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING + repeatMode = Player.REPEAT_MODE_ONE + } + } + DisposableEffect(player) { + player.prepare() + onDispose { + player.release() } + } + PlayerSurface( + modifier = Modifier.fillMaxSize(), + player = player, + scaleMode = ScaleMode.Crop ) + + LifecycleStartEffect(isPlaying) { + player.playWhenReady = isPlaying + onStopOrDispose { + player.pause() + } + } } diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryLoadControl.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryLoadControl.kt deleted file mode 100644 index b76c80697..000000000 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryLoadControl.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.demo.ui.showcases.layouts - -import androidx.media3.exoplayer.DefaultLoadControl -import androidx.media3.exoplayer.LoadControl - -/** - * Story load control - * - * Build a Custom [LoadControl] to optimize playbabck startup. - * - * Warning bad parameters can lead to OOM pretty quickly. - */ -object StoryLoadControl { - // Minimum Video you want to buffer while Playing - private const val MIN_BUFFER_DURATION = 1000 - - // Max Video you want to buffer during PlayBack - private const val MAX_BUFFER_DURATION = DefaultLoadControl.DEFAULT_MAX_BUFFER_MS - - // Min Video you want to buffer before start Playing it - private const val MIN_PLAYBACK_START_BUFFER = 1000 - - // Min video You want to buffer when user resumes video - private const val MIN_PLAYBACK_RESUME_BUFFER = 1000 - - /** - * Build a new [LoadControl] optimized for Story view - */ - fun build(): LoadControl = DefaultLoadControl.Builder() - .setBufferDurationsMs( - MIN_BUFFER_DURATION, - MAX_BUFFER_DURATION, - MIN_PLAYBACK_START_BUFFER, - MIN_PLAYBACK_RESUME_BUFFER - ) - .build() -} diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryViewModel.kt index 891e19d1e..7fe1047a8 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryViewModel.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/layouts/StoryViewModel.kt @@ -30,19 +30,16 @@ class StoryViewModel(application: Application) : AndroidViewModel(application) { PillarboxPlayer( context = application, mediaItemSource = mediaItemSource, - loadControl = StoryLoadControl.build(), mediaItemTrackerProvider = itemTrackerProvider ), PillarboxPlayer( context = application, mediaItemSource = mediaItemSource, - loadControl = StoryLoadControl.build(), mediaItemTrackerProvider = itemTrackerProvider ), PillarboxPlayer( context = application, mediaItemSource = mediaItemSource, - loadControl = StoryLoadControl.build(), mediaItemTrackerProvider = itemTrackerProvider ) ) diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerShowcase.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerShowcase.kt index eee6284d2..3ff7a431b 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerShowcase.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerShowcase.kt @@ -14,6 +14,7 @@ import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -21,7 +22,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration -import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.LifecycleResumeEffect +import androidx.media3.common.Player +import ch.srgssr.pillarbox.demo.shared.data.DemoItem +import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.demo.ui.player.PlayerView import ch.srgssr.pillarbox.demo.ui.theme.paddings @@ -30,13 +35,40 @@ import ch.srgssr.pillarbox.demo.ui.theme.paddings */ @Composable fun MultiPlayerShowcase() { - val multiPlayerViewModel: MultiPlayerViewModel = viewModel() var swapLeftRight by remember { mutableStateOf(false) } - val playerLeft = multiPlayerViewModel.getPlayerLeft(swapLeftRight) - val playerRight = multiPlayerViewModel.getPlayerRight(swapLeftRight) - + val context = LocalContext.current + val playerOne = remember { + PlayerModule.provideDefaultPlayer(context).apply { + repeatMode = Player.REPEAT_MODE_ONE + setMediaItem(DemoItem.LiveVideo.toMediaItem()) + prepare() + } + } + val playerTwo = remember { + PlayerModule.provideDefaultPlayer(context).apply { + repeatMode = Player.REPEAT_MODE_ONE + setMediaItem(DemoItem.DvrVideo.toMediaItem()) + prepare() + } + } + DisposableEffect(Unit) { + onDispose { + playerOne.release() + playerTwo.release() + } + } + LifecycleResumeEffect(Unit) { + playerOne.play() + playerTwo.play() + onPauseOrDispose { + playerOne.pause() + playerTwo.pause() + } + } + val leftPlayer = if (swapLeftRight) playerTwo else playerOne + val rightPlayer = if (swapLeftRight) playerOne else playerTwo Column(horizontalAlignment = Alignment.CenterHorizontally) { Button(onClick = { swapLeftRight = !swapLeftRight }) { Text(text = "Swap players") @@ -46,16 +78,14 @@ fun MultiPlayerShowcase() { PlayerView( modifier = Modifier .weight(1.0f) - .aspectRatio(AspectRatio) .padding(MaterialTheme.paddings.mini), - player = playerLeft + player = leftPlayer, ) PlayerView( modifier = Modifier .weight(1.0f) - .aspectRatio(AspectRatio) .padding(MaterialTheme.paddings.mini), - player = playerRight + player = rightPlayer ) } } else { @@ -65,14 +95,14 @@ fun MultiPlayerShowcase() { .weight(1.0f) .aspectRatio(AspectRatio) .padding(MaterialTheme.paddings.mini), - player = playerLeft + player = leftPlayer ) PlayerView( modifier = Modifier .weight(1.0f) .aspectRatio(AspectRatio) .padding(MaterialTheme.paddings.mini), - player = playerRight + player = rightPlayer ) } } diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerViewModel.kt deleted file mode 100644 index c902cee3e..000000000 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/MultiPlayerViewModel.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.demo.ui.showcases.misc - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.media3.common.Player -import ch.srgssr.pillarbox.demo.shared.data.DemoItem -import ch.srgssr.pillarbox.demo.shared.di.PlayerModule - -/** - * Multi player view model - * - * Two players playing content endlessly. - * There is no audio focus and audio volume handle for this demo. - */ -class MultiPlayerViewModel(application: Application) : AndroidViewModel(application) { - private val player1 = PlayerModule.provideDefaultPlayer(application) - private val player2 = PlayerModule.provideDefaultPlayer(application) - - init { - /* - * On some devices playing DRM content on multiple players may not work. - * One of the players will receive a PlaybackException with ERROR_CODE_DECODER_INIT_FAILED. - * It may happen on low-end devices like Samsung Galaxy A13, for example. - */ - player1.setMediaItem(DemoItem.LiveVideo.toMediaItem()) - player2.setMediaItem(DemoItem.DvrVideo.toMediaItem()) - preparePlayer(player1) - preparePlayer(player2) - } - - private fun preparePlayer(player: Player) { - player.repeatMode = Player.REPEAT_MODE_ONE - player.prepare() - player.play() - } - - /** - * Get player left - * - * @param playerSwap - */ - fun getPlayerLeft(playerSwap: Boolean): Player { - return if (playerSwap) { - player1 - } else { - player2 - } - } - - /** - * Get player right - * - * @param playerSwap - * @return - */ - fun getPlayerRight(playerSwap: Boolean): Player { - return getPlayerLeft(!playerSwap) - } - - override fun onCleared() { - super.onCleared() - player1.release() - player2.release() - } -} diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/AdaptivePlayerShowcase.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/ResizablePlayerShowcase.kt similarity index 95% rename from pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/AdaptivePlayerShowcase.kt rename to pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/ResizablePlayerShowcase.kt index 4a47d90ae..d620d27df 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/AdaptivePlayerShowcase.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/ResizablePlayerShowcase.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.LifecycleStartEffect import androidx.media3.common.Player import ch.srgssr.pillarbox.demo.shared.data.Playlist import ch.srgssr.pillarbox.demo.shared.di.PlayerModule @@ -37,11 +38,11 @@ import ch.srgssr.pillarbox.ui.ScaleMode import ch.srgssr.pillarbox.ui.widget.player.PlayerSurface /** - * Adaptive player demo + * Resizable player demo * The view allow to resize the player view and changing the scale mode */ @Composable -fun AdaptivePlayerShowcase() { +fun ResizablePlayerShowcase() { val context = LocalContext.current val player = remember { PlayerModule.provideDefaultPlayer(context).apply { @@ -53,11 +54,16 @@ fun AdaptivePlayerShowcase() { AdaptivePlayer(player = player, modifier = Modifier.fillMaxSize()) DisposableEffect(player) { player.prepare() - player.play() onDispose { player.release() } } + LifecycleStartEffect(player) { + player.play() + onStopOrDispose { + player.pause() + } + } } @Composable diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/StartAtGivenTimeShowcase.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/StartAtGivenTimeShowcase.kt index f08a9080a..3834a7dbb 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/StartAtGivenTimeShowcase.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/StartAtGivenTimeShowcase.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.LifecycleResumeEffect import ch.srgssr.pillarbox.demo.shared.data.DemoItem import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.demo.ui.player.PlayerView @@ -21,10 +22,14 @@ fun StartAtGivenTimeShowcase() { val context = LocalContext.current val player = remember { PlayerModule.provideDefaultPlayer(context).apply { - setMediaItem(DemoItem.AppleBasic_16_9_TS_HLS.toMediaItem()) + setMediaItem(DemoItem.AppleBasic_16_9_TS_HLS.toMediaItem(), 10.minutes.inWholeMilliseconds) prepare() - play() - seekTo(10.minutes.inWholeMilliseconds) + } + } + LifecycleResumeEffect(player) { + player.play() + onPauseOrDispose { + player.pause() } } DisposableEffect(player) { diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/UpdatableMediaItemShowcase.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/UpdatableMediaItemShowcase.kt index 6c5c3566c..52f54e3f0 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/UpdatableMediaItemShowcase.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/showcases/misc/UpdatableMediaItemShowcase.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.viewmodel.compose.viewModel import ch.srgssr.pillarbox.ui.extension.currentMediaMetadataAsState import ch.srgssr.pillarbox.ui.widget.player.PlayerSurface @@ -32,4 +33,10 @@ fun UpdatableMediaItemShowcase() { ) } } + LifecycleResumeEffect(player) { + player.play() + onPauseOrDispose { + player.pause() + } + } }