feat(service): add ExoPlayer controller and MediaSessionService
This commit is contained in:
63
app/src/main/java/com/radiola/service/PlayerController.kt
Normal file
63
app/src/main/java/com/radiola/service/PlayerController.kt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package com.radiola.service
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.media3.common.AudioAttributes
|
||||||
|
import androidx.media3.common.C
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class PlayerController @Inject constructor(
|
||||||
|
@ApplicationContext context: Context
|
||||||
|
) {
|
||||||
|
private val _isPlaying = MutableStateFlow(false)
|
||||||
|
val isPlaying: StateFlow<Boolean> = _isPlaying
|
||||||
|
|
||||||
|
private val _currentStationPrefix = MutableStateFlow<String?>(null)
|
||||||
|
val currentStationPrefix: StateFlow<String?> = _currentStationPrefix
|
||||||
|
|
||||||
|
val exoPlayer: ExoPlayer = ExoPlayer.Builder(context)
|
||||||
|
.setAudioAttributes(
|
||||||
|
AudioAttributes.Builder()
|
||||||
|
.setUsage(C.USAGE_MEDIA)
|
||||||
|
.setContentType(C.AUDIO_CONTENT_TYPE_MUSIC)
|
||||||
|
.build(),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
.setHandleAudioBecomingNoisy(true)
|
||||||
|
.build()
|
||||||
|
.apply {
|
||||||
|
addListener(object : Player.Listener {
|
||||||
|
override fun onIsPlayingChanged(playing: Boolean) {
|
||||||
|
_isPlaying.value = playing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun play(url: String, stationPrefix: String) {
|
||||||
|
val mediaItem = MediaItem.fromUri(url)
|
||||||
|
exoPlayer.setMediaItem(mediaItem)
|
||||||
|
exoPlayer.prepare()
|
||||||
|
exoPlayer.play()
|
||||||
|
_currentStationPrefix.value = stationPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pause() {
|
||||||
|
exoPlayer.pause()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
exoPlayer.stop()
|
||||||
|
_currentStationPrefix.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun release() {
|
||||||
|
exoPlayer.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
51
app/src/main/java/com/radiola/service/PlayerService.kt
Normal file
51
app/src/main/java/com/radiola/service/PlayerService.kt
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package com.radiola.service
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.media3.common.util.UnstableApi
|
||||||
|
import androidx.media3.session.MediaSession
|
||||||
|
import androidx.media3.session.MediaSessionService
|
||||||
|
import com.radiola.MainActivity
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
@UnstableApi
|
||||||
|
class PlayerService : MediaSessionService() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var playerController: PlayerController
|
||||||
|
|
||||||
|
private var mediaSession: MediaSession? = null
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
mediaSession = MediaSession.Builder(this, playerController.exoPlayer)
|
||||||
|
.setSessionActivity(
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
Intent(this, MainActivity::class.java),
|
||||||
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = mediaSession
|
||||||
|
|
||||||
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||||
|
if (!playerController.isPlaying.value) {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
mediaSession?.run {
|
||||||
|
player.release()
|
||||||
|
release()
|
||||||
|
}
|
||||||
|
mediaSession = null
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user