diff --git a/app/src/main/java/com/vitorpamplona/amethyst/VideoCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/VideoCache.kt index 4d01c8301..bd785161b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/VideoCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/VideoCache.kt @@ -18,7 +18,7 @@ object VideoCache { lateinit var cacheDataSourceFactory: CacheDataSource.Factory - fun get(context: Context): CacheDataSource.Factory { + fun init(context: Context) { if (!this::simpleCache.isInitialized) { exoDatabaseProvider = StandaloneDatabaseProvider(context) @@ -35,7 +35,9 @@ object VideoCache { ) .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR) } + } + fun get(): CacheDataSource.Factory { return cacheDataSourceFactory } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 49823b3e4..e60c431fc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -19,6 +19,7 @@ import coil.decode.ImageDecoderDecoder import coil.decode.SvgDecoder import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.ServiceManager +import com.vitorpamplona.amethyst.VideoCache import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.navigation.Route @@ -54,6 +55,9 @@ class MainActivity : FragmentActivity() { null } + // Initializes video cache. + VideoCache.init(this.applicationContext) + Coil.setImageLoader { ImageLoader.Builder(this).components { if (SDK_INT >= 28) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt index ea18cd3b5..ab67d171d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/VideoView.kt @@ -6,9 +6,13 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.viewinterop.AndroidView +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver import com.google.android.exoplayer2.C import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem @@ -21,44 +25,54 @@ import com.vitorpamplona.amethyst.VideoCache @Composable fun VideoView(videoUri: String, onDialog: ((Boolean) -> Unit)? = null) { val context = LocalContext.current + val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current) - val exoPlayer = remember { + val exoPlayer = remember(videoUri) { ExoPlayer.Builder(context).build().apply { repeatMode = Player.REPEAT_MODE_ALL videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING setMediaSource( - ProgressiveMediaSource.Factory(VideoCache.get(context.applicationContext)).createMediaSource(MediaItem.fromUri(videoUri)) + ProgressiveMediaSource.Factory(VideoCache.get()).createMediaSource(MediaItem.fromUri(videoUri)) ) prepare() } } - val playerView = remember { - StyledPlayerView(context).apply { - player = exoPlayer - layoutParams = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) - resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH - onDialog?.let { innerOnDialog -> - setFullscreenButtonClickListener { - innerOnDialog(it) + DisposableEffect( + AndroidView( + modifier = Modifier.fillMaxWidth(), + factory = { + StyledPlayerView(context).apply { + player = exoPlayer + layoutParams = FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH + onDialog?.let { innerOnDialog -> + setFullscreenButtonClickListener { + exoPlayer.pause() + innerOnDialog(it) + } + } } } + ) + ) { + val observer = LifecycleEventObserver { _, event -> + when (event) { + Lifecycle.Event.ON_PAUSE -> { + exoPlayer.pause() + } + else -> {} + } } - } + val lifecycle = lifecycleOwner.value.lifecycle + lifecycle.addObserver(observer) - DisposableEffect(exoPlayer) { onDispose { exoPlayer.release() + lifecycle.removeObserver(observer) } } - - AndroidView( - modifier = Modifier.fillMaxWidth(), - factory = { - playerView - } - ) }