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