diff --git a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt index d717a6fdc..c260a902f 100644 --- a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt @@ -41,11 +41,11 @@ import com.github.libretube.enums.SbSkipOptions import com.github.libretube.extensions.updateParameters import com.github.libretube.obj.VideoStats import com.github.libretube.util.TextUtils +import kotlinx.coroutines.runBlocking import java.util.Locale import java.util.concurrent.Executors import kotlin.math.absoluteValue import kotlin.math.roundToInt -import kotlinx.coroutines.runBlocking object PlayerHelper { private const val ACTION_MEDIA_CONTROL = "media_control" @@ -334,11 +334,11 @@ object PlayerHelper { fun shouldPlayNextVideo(isPlaylist: Boolean = false): Boolean { return autoPlayEnabled || ( - isPlaylist && PreferenceHelper.getBoolean( - PreferenceKeys.AUTOPLAY_PLAYLISTS, - false - ) - ) + isPlaylist && PreferenceHelper.getBoolean( + PreferenceKeys.AUTOPLAY_PLAYLISTS, + false + ) + ) } private val handleAudioFocus @@ -552,9 +552,9 @@ object PlayerHelper { if (currentPosition in segmentStart until segmentEnd) { if (sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC || ( - sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE && - !segment.skipped - ) + sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE && + !segment.skipped + ) ) { if (sponsorBlockNotifications) { runCatching { @@ -566,9 +566,9 @@ object PlayerHelper { segment.skipped = true } else if (sponsorBlockConfig[segment.category] == SbSkipOptions.MANUAL || ( - sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE && - segment.skipped - ) + sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE && + segment.skipped + ) ) { return segment } @@ -598,7 +598,8 @@ object PlayerHelper { val chapter = chapters[index] // remove the video highlight if it's already longer ago than [ChapterSegment.HIGHLIGHT_LENGTH], // otherwise the SponsorBlock highlight would be shown from its starting point to the end - val isWithinMaxHighlightDuration = (currentPositionSeconds - chapter.start) < ChapterSegment.HIGHLIGHT_LENGTH + val isWithinMaxHighlightDuration = + (currentPositionSeconds - chapter.start) < ChapterSegment.HIGHLIGHT_LENGTH chapter.highlightDrawable == null || isWithinMaxHighlightDuration } } @@ -752,9 +753,9 @@ object PlayerHelper { */ fun haveAudioTrackRoleFlagSet(@C.RoleFlags roleFlags: Int): Boolean { return isFlagSet(roleFlags, C.ROLE_FLAG_DESCRIBES_VIDEO) || - isFlagSet(roleFlags, C.ROLE_FLAG_DUB) || - isFlagSet(roleFlags, C.ROLE_FLAG_MAIN) || - isFlagSet(roleFlags, C.ROLE_FLAG_ALTERNATE) + isFlagSet(roleFlags, C.ROLE_FLAG_DUB) || + isFlagSet(roleFlags, C.ROLE_FLAG_MAIN) || + isFlagSet(roleFlags, C.ROLE_FLAG_ALTERNATE) } @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) @@ -771,4 +772,10 @@ object PlayerHelper { "${player.videoFormat?.width}x${player.videoFormat?.height} ${player.videoFormat?.frameRate?.toInt()}fps" return VideoStats(videoId, videoInfo, videoQuality, audioInfo) } + + fun getPlayPauseActionIcon(player: Player) = when { + player.isPlaying -> R.drawable.ic_pause + player.playbackState == Player.STATE_ENDED -> R.drawable.ic_restart + else -> R.drawable.ic_play + } } diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index af8ae2199..ad4fafde5 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -100,16 +100,18 @@ class OnlinePlayerService : LifecycleService() { /** * Listener for passing playback state changes to the AudioPlayerFragment */ - var onIsPlayingChanged: ((isPlaying: Boolean) -> Unit)? = null + var onStateOrPlayingChanged: ((isPlaying: Boolean) -> Unit)? = null var onNewVideo: ((streams: Streams, videoId: String) -> Unit)? = null private val playerListener = object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { super.onIsPlayingChanged(isPlaying) - onIsPlayingChanged?.invoke(isPlaying) + onStateOrPlayingChanged?.invoke(isPlaying) } override fun onPlaybackStateChanged(state: Int) { + onStateOrPlayingChanged?.invoke(player?.isPlaying ?: false) + when (state) { Player.STATE_ENDED -> { if (PlayerHelper.shouldPlayNextVideo(playlistId != null) && !isTransitioning) playNextVideo() @@ -411,12 +413,4 @@ class OnlinePlayerService : LifecycleService() { fun getDuration() = player?.duration fun seekToPosition(position: Long) = player?.seekTo(position) - - fun pause() { - player?.pause() - } - - fun play() { - player?.play() - } } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt index d171e0222..128543b05 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt @@ -30,6 +30,7 @@ import com.github.libretube.databinding.FragmentAudioPlayerBinding import com.github.libretube.extensions.normalize import com.github.libretube.extensions.seekBy import com.github.libretube.extensions.toID +import com.github.libretube.extensions.togglePlayPauseState import com.github.libretube.helpers.AudioHelper import com.github.libretube.helpers.BackgroundHelper import com.github.libretube.helpers.ImageHelper @@ -188,11 +189,11 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { binding.thumbnail.setOnTouchListener(listener) binding.playPause.setOnClickListener { - if (isPaused) playerService?.play() else playerService?.pause() + playerService?.player?.togglePlayPauseState() } binding.miniPlayerPause.setOnClickListener { - if (isPaused) playerService?.play() else playerService?.pause() + playerService?.player?.togglePlayPauseState() } binding.showMore.setOnClickListener { @@ -207,7 +208,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { bar.progress = audioHelper.getVolumeWithScale(bar.max) } - if (!PlayerHelper.playAutomatically) updatePlayPauseButton(false) + if (!PlayerHelper.playAutomatically) updatePlayPauseButton() } private fun killFragment() { @@ -347,16 +348,18 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { handler.postDelayed(this::updateSeekBar, 200) } - private fun updatePlayPauseButton(isPlaying: Boolean) { - val iconResource = if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play - binding.playPause.setIconResource(iconResource) - binding.miniPlayerPause.setImageResource(iconResource) + private fun updatePlayPauseButton() { + playerService?.player?.let { + val iconRes = PlayerHelper.getPlayPauseActionIcon(it) + binding.playPause.setIconResource(iconRes) + binding.miniPlayerPause.setImageResource(iconRes) + } } private fun handleServiceConnection() { viewModel.player = playerService?.player - playerService?.onIsPlayingChanged = { isPlaying -> - updatePlayPauseButton(isPlaying) + playerService?.onStateOrPlayingChanged = { isPlaying -> + updatePlayPauseButton() isPaused = !isPlaying } playerService?.onNewVideo = { streams, videoId -> @@ -373,7 +376,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { override fun onDestroy() { // unregister all listeners and the connected [playerService] - playerService?.onIsPlayingChanged = null + playerService?.onStateOrPlayingChanged = null runCatching { activity?.unbindService(connection) } @@ -384,7 +387,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions { } override fun onSingleTap() { - if (isPaused) playerService?.play() else playerService?.pause() + playerService?.player?.togglePlayPauseState() } override fun onLongTap() { diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 08f99adbf..a4dbcb251 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -1160,13 +1160,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { } private fun updatePlayPauseButton() { - binding.playImageView.setImageResource( - when { - exoPlayer.isPlaying -> R.drawable.ic_pause - exoPlayer.playbackState == Player.STATE_ENDED -> R.drawable.ic_restart - else -> R.drawable.ic_play - } - ) + binding.playImageView.setImageResource(PlayerHelper.getPlayPauseActionIcon(exoPlayer)) } private suspend fun initializeHighlight(highlight: Segment) { diff --git a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt index 24f3bf591..c951fe229 100644 --- a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt +++ b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt @@ -168,7 +168,7 @@ open class CustomExoPlayerView( Player.EVENT_PLAY_WHEN_READY_CHANGED ) ) { - updatePlayPauseButton() + binding.playPauseBTN.setImageResource(PlayerHelper.getPlayPauseActionIcon(player)) // keep screen on if the video is playing keepScreenOn = player.isPlaying == true @@ -226,16 +226,6 @@ open class CustomExoPlayerView( open fun onPlayerEvent(player: Player, playerEvents: Player.Events) = Unit - private fun updatePlayPauseButton() { - binding.playPauseBTN.setImageResource( - when { - player?.isPlaying == true -> R.drawable.ic_pause - player?.playbackState == Player.STATE_ENDED -> R.drawable.ic_restart - else -> R.drawable.ic_play - } - ) - } - private fun updateDisplayedDurationType(showTimeLeft: Boolean? = null) { var shouldShowTimeLeft = showTimeLeft ?: PreferenceHelper .getBoolean(PreferenceKeys.SHOW_TIME_LEFT, false)