Handle sending progress update
This commit is contained in:
parent
f32e6a370e
commit
464a6dc8ca
3 changed files with 105 additions and 52 deletions
|
@ -6,8 +6,8 @@ import androidx.media3.common.util.UnstableApi
|
|||
import androidx.media3.session.*
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.services.playback.library.MediaItemProvider
|
||||
import com.simplemobiletools.musicplayer.services.playback.player.PlayerListener
|
||||
import com.simplemobiletools.musicplayer.services.playback.player.SimplePlayer
|
||||
import com.simplemobiletools.musicplayer.services.playback.player.getPlayerListener
|
||||
import com.simplemobiletools.musicplayer.services.playback.player.initializeSessionAndPlayer
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
|
@ -18,6 +18,8 @@ class PlaybackService : MediaLibraryService() {
|
|||
|
||||
internal lateinit var mediaItemProvider: MediaItemProvider
|
||||
|
||||
internal var listener: PlayerListener? = null
|
||||
|
||||
internal var currentRoot = ""
|
||||
|
||||
override fun onCreate() {
|
||||
|
@ -30,7 +32,7 @@ class PlaybackService : MediaLibraryService() {
|
|||
|
||||
private fun releaseMediaSession() {
|
||||
mediaSession.release()
|
||||
player.removeListener(getPlayerListener())
|
||||
player.removeListener(listener!!)
|
||||
player.release()
|
||||
}
|
||||
|
||||
|
@ -42,6 +44,7 @@ class PlaybackService : MediaLibraryService() {
|
|||
}
|
||||
|
||||
fun stopService() {
|
||||
player.pause()
|
||||
player.stop()
|
||||
releaseMediaSession()
|
||||
stopSelf()
|
||||
|
|
|
@ -5,58 +5,32 @@ package com.simplemobiletools.musicplayer.services.playback.player
|
|||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.media3.common.AudioAttributes
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.session.MediaLibraryService
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.MainActivity
|
||||
import com.simplemobiletools.musicplayer.services.playback.PlaybackService
|
||||
import com.simplemobiletools.musicplayer.services.playback.getCustomLayout
|
||||
import com.simplemobiletools.musicplayer.services.playback.getMediaSessionCallback
|
||||
|
||||
private const val SEEK_INCREMENT_MS = 10000L
|
||||
|
||||
private var playerListener: Player.Listener? = null
|
||||
|
||||
internal fun PlaybackService.getPlayerListener(): Player.Listener {
|
||||
if (playerListener == null) {
|
||||
playerListener = object : Player.Listener {
|
||||
override fun onEvents(player: Player, events: Player.Events) {
|
||||
if (events.containsAny(
|
||||
Player.EVENT_POSITION_DISCONTINUITY,
|
||||
Player.EVENT_MEDIA_ITEM_TRANSITION,
|
||||
Player.EVENT_PLAY_WHEN_READY_CHANGED,
|
||||
Player.EVENT_TRACKS_CHANGED,
|
||||
Player.EVENT_TIMELINE_CHANGED,
|
||||
Player.EVENT_IS_PLAYING_CHANGED
|
||||
)
|
||||
) {
|
||||
val currentMediaId = player.currentMediaItem?.mediaId
|
||||
if (currentMediaId != null && currentRoot.isNotEmpty()) {
|
||||
mediaItemProvider.saveRecentItemsWithStartPosition(
|
||||
mediaId = currentMediaId,
|
||||
startPosition = player.currentPosition,
|
||||
rootId = currentRoot
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayerError(error: PlaybackException) = toast(R.string.unknown_error_occurred, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
|
||||
return playerListener!!
|
||||
}
|
||||
private const val SEEK_INTERVAL_MS = 10000L
|
||||
|
||||
internal fun PlaybackService.initializeSessionAndPlayer(handleAudioFocus: Boolean, handleAudioBecomingNoisy: Boolean, skipSilence: Boolean) {
|
||||
player = SimplePlayer(
|
||||
player = initializePlayer(handleAudioFocus, handleAudioBecomingNoisy, skipSilence)
|
||||
listener = PlayerListener(context = this)
|
||||
player.addListener(listener!!)
|
||||
|
||||
mediaSession = MediaLibraryService.MediaLibrarySession.Builder(this, player, getMediaSessionCallback())
|
||||
.setSessionActivity(getSessionActivityIntent())
|
||||
.build()
|
||||
|
||||
mediaSession.setCustomLayout(getCustomLayout())
|
||||
}
|
||||
|
||||
private fun Context.initializePlayer(handleAudioFocus: Boolean, handleAudioBecomingNoisy: Boolean, skipSilence: Boolean): SimplePlayer {
|
||||
return SimplePlayer(
|
||||
ExoPlayer.Builder(this)
|
||||
.setWakeMode(C.WAKE_MODE_LOCAL)
|
||||
.setHandleAudioBecomingNoisy(handleAudioBecomingNoisy)
|
||||
|
@ -68,18 +42,10 @@ internal fun PlaybackService.initializeSessionAndPlayer(handleAudioFocus: Boolea
|
|||
handleAudioFocus
|
||||
)
|
||||
.setSkipSilenceEnabled(skipSilence)
|
||||
.setSeekBackIncrementMs(SEEK_INCREMENT_MS)
|
||||
.setSeekForwardIncrementMs(SEEK_INCREMENT_MS)
|
||||
.setSeekBackIncrementMs(SEEK_INTERVAL_MS)
|
||||
.setSeekForwardIncrementMs(SEEK_INTERVAL_MS)
|
||||
.build()
|
||||
)
|
||||
|
||||
player.addListener(getPlayerListener())
|
||||
|
||||
mediaSession = MediaLibraryService.MediaLibrarySession.Builder(this, player, getMediaSessionCallback())
|
||||
.setSessionActivity(getSessionActivityIntent())
|
||||
.build()
|
||||
|
||||
mediaSession.setCustomLayout(getCustomLayout())
|
||||
}
|
||||
|
||||
private fun Context.getSessionActivityIntent(): PendingIntent {
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package com.simplemobiletools.musicplayer.services.playback.player
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.widget.Toast
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.services.playback.PlaybackService
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.DurationUnit
|
||||
|
||||
@UnstableApi
|
||||
class PlayerListener(private val context: PlaybackService) : Player.Listener {
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val updateIntervalMillis = 800L
|
||||
|
||||
override fun onPlayerError(error: PlaybackException) = context.toast(R.string.unknown_error_occurred, Toast.LENGTH_LONG)
|
||||
|
||||
override fun onEvents(player: Player, events: Player.Events) {
|
||||
if (
|
||||
events.containsAny(
|
||||
Player.EVENT_POSITION_DISCONTINUITY,
|
||||
Player.EVENT_MEDIA_ITEM_TRANSITION,
|
||||
Player.EVENT_PLAY_WHEN_READY_CHANGED,
|
||||
Player.EVENT_TRACKS_CHANGED,
|
||||
Player.EVENT_TIMELINE_CHANGED,
|
||||
Player.EVENT_IS_PLAYING_CHANGED,
|
||||
Player.EVENT_PLAYBACK_STATE_CHANGED,
|
||||
Player.EVENT_MEDIA_METADATA_CHANGED
|
||||
)
|
||||
) {
|
||||
val currentMediaId = player.currentMediaItem?.mediaId
|
||||
if (currentMediaId != null && context.currentRoot.isNotEmpty()) {
|
||||
context.mediaItemProvider.saveRecentItemsWithStartPosition(
|
||||
mediaId = currentMediaId,
|
||||
startPosition = player.currentPosition,
|
||||
rootId = context.currentRoot
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
if (isPlaying) {
|
||||
schedulePositionUpdate()
|
||||
} else {
|
||||
cancelPositionUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPositionDiscontinuity(oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int) {
|
||||
if (context.player.isPlaying) {
|
||||
schedulePositionUpdate()
|
||||
} else {
|
||||
cancelPositionUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun schedulePositionUpdate() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
handler.postDelayed(updateIntervalMillis) {
|
||||
updatePosition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelPositionUpdate() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
|
||||
private fun updatePosition() {
|
||||
val currentPosition = context.player.currentPosition
|
||||
if (currentPosition >= 0) {
|
||||
val progress = currentPosition.seconds.toInt(DurationUnit.SECONDS)
|
||||
EventBus.getDefault().post(Events.ProgressUpdated(progress))
|
||||
schedulePositionUpdate()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue