Skip to content

Commit

Permalink
Merge pull request #5993 from Bnyro/master
Browse files Browse the repository at this point in the history
refactor: move some player view related code to OnlinePlayerView.kt
  • Loading branch information
Bnyro authored May 7, 2024
2 parents 5e0c9a5 + df08705 commit cc9a334
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,9 @@ object PlayerHelper {
}
}

/**
* Handle basic [PlayerEvent]'s that can be handled by the player itself without context
*/
fun handlePlayerAction(player: Player, playerEvent: PlayerEvent): Boolean {
return when (playerEvent) {
PlayerEvent.PlayPause -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.PowerManager
import android.text.format.DateUtils
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
Expand All @@ -32,7 +31,6 @@ import androidx.core.os.postDelayed
import androidx.core.view.SoftwareKeyboardControllerCompat
import androidx.core.view.WindowCompat
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
Expand Down Expand Up @@ -102,7 +100,6 @@ import com.github.libretube.ui.models.CommentsViewModel
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.ui.sheets.CommentsSheet
import com.github.libretube.ui.sheets.PlayingQueueSheet
import com.github.libretube.ui.sheets.StatsSheet
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.OnlineTimeFrameReceiver
Expand Down Expand Up @@ -160,9 +157,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
Executors.newCachedThreadPool()
)

// SponsorBlock
private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled

private val handler = Handler(Looper.getMainLooper())

private var seekBarPreviewListener: SeekbarPreviewListener? = null
Expand Down Expand Up @@ -271,7 +265,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}

override fun onEvents(player: Player, events: Player.Events) {
updateDisplayedDuration()
super.onEvents(player, events)

if (events.containsAny(
Expand Down Expand Up @@ -522,7 +515,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
playerBinding.closeImageButton.setOnClickListener {
onManualPlayerClose()
}
playerBinding.autoPlay.isVisible = true

binding.playImageView.setOnClickListener {
exoPlayer.togglePlayPauseState()
Expand All @@ -540,28 +532,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
CommentsSheet().show(childFragmentManager)
}

playerBinding.queueToggle.isVisible = true
playerBinding.queueToggle.setOnClickListener {
PlayingQueueSheet().show(childFragmentManager, null)
}

// FullScreen button trigger
// hide fullscreen button if autorotation enabled
playerBinding.fullscreen.setOnClickListener {
toggleFullscreen()
}

val updateSbImageResource = {
playerBinding.sbToggle.setImageResource(
if (sponsorBlockEnabled) R.drawable.ic_sb_enabled else R.drawable.ic_sb_disabled
)
}
updateSbImageResource()
playerBinding.sbToggle.setOnClickListener {
sponsorBlockEnabled = !sponsorBlockEnabled
updateSbImageResource()
}

// share button
binding.relPlayerShare.setOnClickListener {
if (!this::streams.isInitialized) return@setOnClickListener
Expand Down Expand Up @@ -695,16 +671,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
updateFullscreenOrientation()

commentsViewModel.setCommentSheetExpand(null)
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen_exit)
playerBinding.exoTitle.isVisible = true

updateResolutionOnFullscreenChange(true)

openOrCloseFullscreenDialog(true)

binding.player.updateMarginsByFullscreenMode()

updateFullscreenButtonVisibility()
}

@SuppressLint("SourceLockedOrientationActivity")
Expand All @@ -718,8 +690,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}

viewModel.isFullscreen.value = false
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen)
playerBinding.exoTitle.isInvisible = true

if (!PlayerHelper.autoFullscreenEnabled) {
mainActivity.requestedOrientation = mainActivity.screenOrientationPref
Expand All @@ -729,12 +699,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
updateResolutionOnFullscreenChange(false)

binding.player.updateMarginsByFullscreenMode()

updateFullscreenButtonVisibility()
}

private fun updateFullscreenButtonVisibility() {
playerBinding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
}

/**
Expand Down Expand Up @@ -881,7 +845,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
if (!exoPlayer.isPlaying || !PlayerHelper.sponsorBlockEnabled) return

handler.postDelayed(this::checkForSegments, 100)
if (!sponsorBlockEnabled || viewModel.segments.isEmpty()) return
if (!viewModel.sponsorBlockEnabled || viewModel.segments.isEmpty()) return

exoPlayer.checkForSegments(
requireContext(),
Expand Down Expand Up @@ -949,7 +913,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
) {
setFullscreen()
}
updateFullscreenButtonVisibility()

binding.player.apply {
useController = false
Expand Down Expand Up @@ -1000,7 +963,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
withContext(Dispatchers.Main) {
playerBinding.exoProgress.setSegments(viewModel.segments)
playerBinding.sbToggle.isVisible = true
updateDisplayedDuration()
}
viewModel.segments.firstOrNull { it.category == PlayerHelper.SPONSOR_HIGHLIGHT_CATEGORY }
?.let {
Expand Down Expand Up @@ -1082,8 +1044,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
this.streams.uploader
)

syncQueueButtons()

// seekbar preview setup
playerBinding.seekbarPreview.isGone = true
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
Expand Down Expand Up @@ -1137,39 +1097,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}
}

/**
* Update the displayed duration of the video
*/
private fun updateDisplayedDuration() {
if (!this::streams.isInitialized || streams.livestream || _binding == null) return

val duration = exoPlayer.duration / 1000
if (duration < 0) return

val durationWithoutSegments = duration - viewModel.segments.sumOf {
val (start, end) = it.segmentStartAndEnd
end.toDouble() - start.toDouble()
}.toLong()
val durationString = DateUtils.formatElapsedTime(duration)

playerBinding.duration.text = if (durationWithoutSegments < duration) {
"$durationString (${DateUtils.formatElapsedTime(durationWithoutSegments)})"
} else {
durationString
}
}

private fun syncQueueButtons() {
if (!PlayerHelper.skipButtonsEnabled) return

// toggle the visibility of next and prev buttons based on queue and whether the player view is locked
val isPlayerLocked = binding.player.isPlayerLocked
playerBinding.skipPrev.isInvisible = !PlayingQueue.hasPrev() || isPlayerLocked
playerBinding.skipNext.isInvisible = !PlayingQueue.hasNext() || isPlayerLocked

handler.postDelayed(this::syncQueueButtons, 100)
}

private fun updatePlayPauseButton() {
binding.playImageView.setImageResource(PlayerHelper.getPlayPauseActionIcon(exoPlayer))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import com.github.libretube.api.obj.Message
import com.github.libretube.api.obj.Segment
import com.github.libretube.api.obj.Streams
import com.github.libretube.api.obj.Subtitle
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.deArrow
import java.io.IOException
Expand Down Expand Up @@ -51,6 +53,7 @@ class PlayerViewModel : ViewModel() {
val chaptersLiveData = MutableLiveData<List<ChapterSegment>>()

val chapters get() = chaptersLiveData.value.orEmpty()
var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled

/**
* @return pair of the stream info and the error message if the request was not successful
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,7 @@ abstract class CustomExoPlayerView(
player?.addListener(object : Player.Listener {
override fun onEvents(player: Player, events: Player.Events) {
super.onEvents(player, events)
if (events.containsAny(
Player.EVENT_PLAYBACK_STATE_CHANGED,
Player.EVENT_IS_PLAYING_CHANGED,
Player.EVENT_PLAY_WHEN_READY_CHANGED
)
) {
binding.playPauseBTN.setImageResource(
PlayerHelper.getPlayPauseActionIcon(player)
)

// keep screen on if the video is playing
keepScreenOn = player.isPlaying == true
onPlayerEvent(player, events)
}
this@CustomExoPlayerView.onPlaybackEvents(player, events)
}
})

Expand Down Expand Up @@ -820,6 +807,23 @@ abstract class CustomExoPlayerView(
return true
}

open fun onPlaybackEvents(player: Player, events: Player.Events) {
if (events.containsAny(
Player.EVENT_PLAYBACK_STATE_CHANGED,
Player.EVENT_IS_PLAYING_CHANGED,
Player.EVENT_PLAY_WHEN_READY_CHANGED
)
) {
binding.playPauseBTN.setImageResource(
PlayerHelper.getPlayPauseActionIcon(player)
)

// keep screen on if the video is playing
keepScreenOn = player.isPlaying == true
onPlayerEvent(player, events)
}
}

open fun minimizeOrExitPlayer() = Unit

abstract fun getChapters(): List<ChapterSegment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package com.github.libretube.ui.views

import android.content.Context
import android.os.Bundle
import android.text.format.DateUtils
import android.util.AttributeSet
import android.view.Window
import androidx.core.os.bundleOf
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.media3.common.C
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.trackselection.TrackSelector
import com.github.libretube.R
Expand All @@ -24,6 +27,7 @@ import com.github.libretube.ui.dialogs.SubmitDeArrowDialog
import com.github.libretube.ui.dialogs.SubmitSegmentDialog
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.PlayingQueueSheet
import com.github.libretube.util.PlayingQueue

@UnstableApi
Expand Down Expand Up @@ -154,14 +158,39 @@ class OnlinePlayerView(
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
WindowHelper.toggleFullscreen(activity.window, isFullscreen)
updateTopBarMargin()

binding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
val fullscreenDrawable = if (isFullscreen) R.drawable.ic_fullscreen_exit else R.drawable.ic_fullscreen
binding.fullscreen.setImageResource(fullscreenDrawable)

binding.exoTitle.isInvisible = !isFullscreen
}

binding.autoPlay.isVisible = true
binding.autoPlay.isChecked = PlayerHelper.autoPlayEnabled

binding.autoPlay.setOnCheckedChangeListener { _, isChecked ->
PlayerHelper.autoPlayEnabled = isChecked
}

binding.queueToggle.isVisible = true
binding.queueToggle.setOnClickListener {
PlayingQueueSheet().show(activity.supportFragmentManager, null)
}

val updateSbImageResource = {
binding.sbToggle.setImageResource(
if (playerViewModel.sponsorBlockEnabled) R.drawable.ic_sb_enabled else R.drawable.ic_sb_disabled
)
}
updateSbImageResource()
binding.sbToggle.setOnClickListener {
playerViewModel.sponsorBlockEnabled = !playerViewModel.sponsorBlockEnabled
updateSbImageResource()
}

syncQueueButtons()

binding.sbSubmit.isVisible = PreferenceHelper.getBoolean(PreferenceKeys.CONTRIBUTE_TO_SB, false)
binding.sbSubmit.setOnClickListener {
val submitSegmentDialog = SubmitSegmentDialog()
Expand Down Expand Up @@ -189,6 +218,38 @@ class OnlinePlayerView(
)
}

private fun syncQueueButtons() {
if (!PlayerHelper.skipButtonsEnabled) return

// toggle the visibility of next and prev buttons based on queue and whether the player view is locked
binding.skipPrev.isInvisible = !PlayingQueue.hasPrev() || isPlayerLocked
binding.skipNext.isInvisible = !PlayingQueue.hasNext() || isPlayerLocked

handler.postDelayed(this::syncQueueButtons, 100)
}

/**
* Update the displayed duration of the video
*/
private fun updateDisplayedDuration() {
if (isLive) return

val duration = player?.duration?.div(1000) ?: return
if (duration < 0) return

val durationWithoutSegments = duration - playerViewModel?.segments.orEmpty().sumOf {
val (start, end) = it.segmentStartAndEnd
end.toDouble() - start.toDouble()
}.toLong()
val durationString = DateUtils.formatElapsedTime(duration)

binding.duration.text = if (durationWithoutSegments < duration) {
"$durationString (${DateUtils.formatElapsedTime(durationWithoutSegments)})"
} else {
durationString
}
}

override fun getWindow(): Window = currentWindow ?: activity.window

override fun hideController() {
Expand Down Expand Up @@ -219,4 +280,9 @@ class OnlinePlayerView(
override fun getChapters(): List<ChapterSegment> {
return playerViewModel?.chapters.orEmpty()
}

override fun onPlaybackEvents(player: Player, events: Player.Events) {
super.onPlaybackEvents(player, events)
updateDisplayedDuration()
}
}

0 comments on commit cc9a334

Please sign in to comment.