Improvements in BackgroundMode

Now the class is a singleton, with this, we avoid to instantiate
every time a new ExoPlayer whenever we select a new video to play
in background.

Fixes the "When you select another video to run in background,
stops the previous one".
This commit is contained in:
Relwi 2022-05-19 22:13:42 +02:00
parent b35bb93234
commit 87430dc21e
No known key found for this signature in database
GPG Key ID: 3316DC3D260D0163
2 changed files with 31 additions and 26 deletions

View File

@ -9,10 +9,8 @@ import kotlinx.coroutines.runBlocking
/** /**
* Loads the selected video audio in background mode with a notification area. * Loads the selected video audio in background mode with a notification area.
*
* Needs the [c], necessarily to build the [ExoPlayer] player, and [videoId] to get the video data.
*/ */
class BackgroundMode(private val c: Context, private val videoId: String) { class BackgroundMode {
/** /**
* The response that gets when called the Api. * The response that gets when called the Api.
*/ */
@ -23,40 +21,37 @@ class BackgroundMode(private val c: Context, private val videoId: String) {
*/ */
private var player: ExoPlayer? = null private var player: ExoPlayer? = null
private var playWhenReadyPlayer = true private var playWhenReadyPlayer = true
private var currentItem = 0
private var playbackPosition = 0L
/** /**
* Initializes the [player] player with the [MediaItem]. * Initializes the [player] player with the [MediaItem].
*/ */
private fun initializePlayer() { private fun initializePlayer(c: Context) {
player = ExoPlayer.Builder(c) if (player == null) player = ExoPlayer.Builder(c).build()
.build() setMediaItem()
.also { exoPlayer ->
response?.let {
val mediaItem = MediaItem.fromUri(response!!.hls!!)
exoPlayer.setMediaItem(mediaItem)
}
}
} }
/** /**
* Releases the [player]. * Releases the [player].
*/ */
private fun releasePlayer() { private fun releasePlayer() {
player?.let { exoPlayer -> player?.release()
playbackPosition = exoPlayer.currentPosition
currentItem = exoPlayer.currentMediaItemIndex
playWhenReadyPlayer = exoPlayer.playWhenReady
exoPlayer.release()
}
player = null player = null
} }
/**
* Sets the [MediaItem] with the [response] into the [player].
*/
private fun setMediaItem() {
response?.let {
val mediaItem = MediaItem.fromUri(response!!.hls!!)
player?.setMediaItem(mediaItem)
}
}
/** /**
* Gets the video data and prepares the [player]. * Gets the video data and prepares the [player].
*/ */
fun playOnBackgroundMode() { fun playOnBackgroundMode(c: Context, videoId: String) {
runBlocking { runBlocking {
val job = launch { val job = launch {
response = RetrofitInstance.api.getStreams(videoId) response = RetrofitInstance.api.getStreams(videoId)
@ -64,13 +59,24 @@ class BackgroundMode(private val c: Context, private val videoId: String) {
// Wait until the job is done, to load correctly later in the player // Wait until the job is done, to load correctly later in the player
job.join() job.join()
initializePlayer() initializePlayer(c)
player?.apply { player?.apply {
playWhenReady = playWhenReadyPlayer playWhenReady = playWhenReadyPlayer
seekTo(currentItem, playbackPosition)
prepare() prepare()
} }
} }
} }
/**
* Creates a singleton of this class, to not create a new [player] every time.
*/
companion object {
private var INSTANCE: BackgroundMode? = null
fun getInstance(): BackgroundMode {
if (INSTANCE == null) INSTANCE = BackgroundMode()
return INSTANCE!!
}
}
} }

View File

@ -9,8 +9,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
/** /**
* Dialog with different options for a selected video. * Dialog with different options for a selected video.
* *
* @param videoId * Needs the [videoId] to load the content from the right video.
* The video id.
*/ */
class VideoOptionsDialog(private val videoId: String) : DialogFragment() { class VideoOptionsDialog(private val videoId: String) : DialogFragment() {
/** /**
@ -38,7 +37,7 @@ class VideoOptionsDialog(private val videoId: String) : DialogFragment() {
when (which) { when (which) {
// This for example will be the "Background mode" option // This for example will be the "Background mode" option
0 -> { 0 -> {
BackgroundMode(requireContext(), videoId).playOnBackgroundMode() BackgroundMode.getInstance().playOnBackgroundMode(requireContext(), videoId)
} }
else -> { else -> {
dialog.dismiss() dialog.dismiss()