Skip to content

Commit

Permalink
Remember last position before release and seek to it later
Browse files Browse the repository at this point in the history
  • Loading branch information
fengdai committed May 27, 2022
1 parent ae75482 commit e383725
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ fun BasicContent(

var controllerType by rememberSaveable { mutableStateOf(ControllerType.Simple) }

var rememberedMediaItemIdAndPosition: Pair<String, Long>? by remember { mutableStateOf(null) }
val player by rememberManagedExoPlayer { context ->
setMediaSourceFactory(ProgressiveMediaSource.Factory(DefaultDataSource.Factory(context)))
}
Expand All @@ -90,10 +91,13 @@ fun BasicContent(
onDispose {}
}

val mediaItem = remember(url) { MediaItem.fromUri(url) }
val mediaItem = remember(url) { MediaItem.Builder().setMediaId(url).setUri(url).build() }
DisposableEffect(mediaItem, player) {
player?.run {
setMediaItem(mediaItem)
rememberedMediaItemIdAndPosition?.let { (id, position) ->
if (id == mediaItem.mediaId) seekTo(position)
}?.also { rememberedMediaItemIdAndPosition = null }
prepare()
}
onDispose {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.Timeline

@Composable
fun rememberManagedExoPlayer(
block: (ExoPlayer.Builder.(Context) -> Unit)? = null
lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
buildBlock: (ExoPlayer.Builder.(Context) -> Unit)? = null
): State<ExoPlayer?> {
val currentContext = LocalContext.current
val exoPlayerManager = remember { ExoPlayerManager(currentContext, block) }

val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val exoPlayerManager = remember(buildBlock) {
ExoPlayerManager(currentContext, buildBlock)
}
DisposableEffect(lifecycle) {
val observer = LifecycleEventObserver { _, event ->
when {
event == Lifecycle.Event.ON_START && Build.VERSION.SDK_INT > 23 -> exoPlayerManager.initialize()
Expand All @@ -26,12 +29,11 @@ fun rememberManagedExoPlayer(
event == Lifecycle.Event.ON_STOP && Build.VERSION.SDK_INT > 23 -> exoPlayerManager.release()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
lifecycle.removeObserver(observer)
}
}

return exoPlayerManager.player
}

Expand All @@ -41,16 +43,34 @@ internal class ExoPlayerManager(
private val buildBlock: (ExoPlayer.Builder.(Context) -> Unit)? = null
) : RememberObserver {
var player = mutableStateOf<ExoPlayer?>(null)
private var rememberedMediaItemIdAndPosition: Pair<String, Long>? = null

internal fun initialize() {
if (player.value != null) return
val builder = ExoPlayer.Builder(context)
buildBlock?.invoke(builder, context)
player.value = builder.build()
player.value = builder.build().also { player ->
player.addListener(object : Player.Listener {
override fun onTimelineChanged(timeline: Timeline, reason: Int) {
// recover the remembered position if media id matched
rememberedMediaItemIdAndPosition
?.let { (id, position) ->
if (id == player.currentMediaItem?.mediaId) player.seekTo(position)
}
?.also { rememberedMediaItemIdAndPosition = null }
}
})
}
}

internal fun release() {
player.value?.release()
player.value?.let { player ->
// remember the current position before release
player.currentMediaItem?.let { mediaItem ->
rememberedMediaItemIdAndPosition = mediaItem.mediaId to player.currentPosition
}
player.release()
}
player.value = null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavHostController
import com.github.fengdai.compose.media.*
import com.github.fengdai.compose.media.Media
import com.github.fengdai.compose.media.MediaState
import com.github.fengdai.compose.media.rememberMediaState
import com.github.fengdai.compose.media.rememberPlayerState
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.ProgressiveMediaSource
Expand All @@ -38,7 +41,10 @@ fun FullscreenToggle(navController: NavHostController) {
val player by rememberManagedExoPlayer { context ->
setMediaSourceFactory(ProgressiveMediaSource.Factory(DefaultDataSource.Factory(context)))
}
SideEffect { player?.playWhenReady = true }
DisposableEffect(player) {
player?.playWhenReady = true
onDispose {}
}

val mediaItem = remember { MediaItem.fromUri(Urls[0]) }
LaunchedEffect(mediaItem, player) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ fun InsideListContent(
val player by rememberManagedExoPlayer { context ->
setMediaSourceFactory(ProgressiveMediaSource.Factory(DefaultDataSource.Factory(context)))
}
SideEffect { player?.playWhenReady = true }
DisposableEffect(player) {
player?.playWhenReady = true
onDispose {}
}

val listState = rememberLazyListState()
val focusedIndex by remember(listState) {
Expand Down

0 comments on commit e383725

Please sign in to comment.