Drop androidx.media3

This commit is contained in:
vfsfitvnm
2022-06-25 16:04:52 +02:00
parent 524bea60d9
commit 7e6b5747a2
24 changed files with 626 additions and 666 deletions

View File

@@ -0,0 +1,23 @@
package it.vfsfitvnm.vimusic.utils
import android.app.Activity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
inline fun <reified T> Context.intent(): Intent =
Intent(this@Context, T::class.java)
inline fun <reified T: BroadcastReceiver> Context.broadCastPendingIntent(
requestCode: Int = 0,
flags: Int = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0,
): PendingIntent =
PendingIntent.getBroadcast(this, requestCode, intent<T>(), flags)
inline fun <reified T: Activity> Context.activityPendingIntent(
requestCode: Int = 0,
flags: Int = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0,
): PendingIntent =
PendingIntent.getActivity(this, requestCode, intent<T>(), flags)

View File

@@ -1,24 +0,0 @@
package it.vfsfitvnm.vimusic.utils
import android.os.Bundle
import androidx.media3.session.MediaController
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionResult
import com.google.common.util.concurrent.MoreExecutors
import kotlinx.coroutines.guava.await
suspend fun MediaController.send(command: SessionCommand, args: Bundle = Bundle.EMPTY): SessionResult {
return sendCustomCommand(command, args).await()
}
fun MediaController.command(command: SessionCommand, args: Bundle = Bundle.EMPTY, listener: ((SessionResult) -> Unit)? = null) {
val future = sendCustomCommand(command, args)
listener?.let {
future.addListener({ it(future.get()) }, MoreExecutors.directExecutor())
}
}
fun MediaController.syncCommand(command: SessionCommand, args: Bundle = Bundle.EMPTY): SessionResult {
return sendCustomCommand(command, args).get()
}

View File

@@ -6,10 +6,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.media3.common.*
import androidx.media3.session.MediaController
import kotlin.math.absoluteValue
open class PlayerState(val mediaController: MediaController) : Player.Listener {
open class PlayerState(val mediaController: Player) : Player.Listener {
private val handler = Handler(Looper.getMainLooper())
var currentPosition by mutableStateOf(mediaController.currentPosition)
@@ -52,7 +51,6 @@ open class PlayerState(val mediaController: MediaController) : Player.Listener {
init {
handler.post(object : Runnable {
override fun run() {
duration = mediaController.duration
currentPosition = mediaController.currentPosition
handler.postDelayed(this, 500)
}
@@ -64,6 +62,7 @@ open class PlayerState(val mediaController: MediaController) : Player.Listener {
}
override fun onPlaybackStateChanged(playbackState: Int) {
duration = mediaController.duration
this.playbackState = playbackState
}

View File

@@ -0,0 +1,43 @@
package it.vfsfitvnm.vimusic.utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
interface TimerJob {
val millisLeft: StateFlow<Long?>
fun cancel()
}
fun CoroutineScope.timer(delayMillis: Long, onCompletion: () -> Unit): TimerJob {
val millisLeft = MutableStateFlow<Long?>(delayMillis)
val job = launch {
while (isActive && millisLeft.value != null) {
delay(1000)
millisLeft.emit(millisLeft.value?.minus(1000)?.takeIf { it > 0 })
}
}
val disposableHandle = job.invokeOnCompletion {
if (it == null) {
onCompletion()
}
}
return object : TimerJob {
override val millisLeft: StateFlow<Long?>
get() = millisLeft.asStateFlow()
override fun cancel() {
millisLeft.value = null
disposableHandle.dispose()
job.cancel()
}
}
}

View File

@@ -2,15 +2,13 @@ package it.vfsfitvnm.vimusic.utils
import androidx.compose.runtime.*
import androidx.media3.common.MediaItem
import androidx.media3.session.MediaController
import com.google.common.util.concurrent.ListenableFuture
import androidx.media3.common.Player
import it.vfsfitvnm.youtubemusic.Outcome
import it.vfsfitvnm.youtubemusic.YouTube
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.withContext
class YoutubePlayer(mediaController: MediaController) : PlayerState(mediaController) {
class YoutubePlayer(mediaController: Player) : PlayerState(mediaController) {
data class Radio(
private val videoId: String? = null,
private val playlistId: String? = null,
@@ -45,22 +43,13 @@ class YoutubePlayer(mediaController: MediaController) : PlayerState(mediaControl
}
}
val LocalYoutubePlayer = compositionLocalOf<YoutubePlayer?> { null }
@Composable
fun rememberYoutubePlayer(
mediaControllerFuture: ListenableFuture<MediaController>
player: Player?
): YoutubePlayer? {
val mediaController by produceState<MediaController?>(initialValue = null) {
value = mediaControllerFuture.await()
}
val playerState = remember(mediaController) {
YoutubePlayer(mediaController ?: return@remember null).also {
// TODO: should we remove the listener later on?
mediaController?.addListener(it)
return remember(player) {
YoutubePlayer(player ?: return@remember null).also {
player.addListener(it)
}
}
return playerState
}

View File

@@ -144,6 +144,8 @@ val SongWithInfo.asMediaItem: MediaItem
.build()
)
.setMediaId(song.id)
.setUri(song.id)
.setCustomCacheKey(song.id)
.build()
fun YouTube.PlaylistOrAlbum.Item.toMediaItem(
@@ -172,6 +174,8 @@ fun YouTube.PlaylistOrAlbum.Item.toMediaItem(
.build()
)
.setMediaId(info.endpoint?.videoId ?: return null)
.setUri(info.endpoint?.videoId ?: return null)
.setCustomCacheKey(info.endpoint?.videoId ?: return null)
.build()
}