Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,7 @@ class OfflinePlayerActivity : BaseActivity() {
playNextVideo(PlayingQueue.getNext() ?: return@setOnClickListener)
}

binding.player.initialize(
binding.doubleTapOverlay.binding,
binding.playerGestureControlsView.binding,
chaptersViewModel
)
binding.player.initialize(chaptersViewModel)
}

private suspend fun loadPlayerData() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
private var _binding: FragmentPlayerBinding? = null
val binding get() = _binding!!

private val playerBinding get() = binding.player.binding
private val doubleTapOverlayBinding get() = binding.doubleTapOverlay.binding
private val playerGestureControlsViewBinding get() = binding.playerGestureControlsView.binding
private val playerControlsBinding get() = binding.player.binding
private val playerBackgroundBinding get() = binding.player.backgroundBinding

private val commonPlayerViewModel: CommonPlayerViewModel by activityViewModels()
private val viewModel: PlayerViewModel by viewModels()
Expand Down Expand Up @@ -275,7 +274,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {

// check if video has ended, next video is available and autoplay is enabled/the video is part of a played playlist.
if (playbackState == Player.STATE_ENDED) {
binding.sbSkipBtn.isGone = true
playerBackgroundBinding.sbSkipBtn.isGone = true
if (PlayerHelper.isAutoPlayEnabled(playlistId != null) && autoPlayCountdownEnabled) {
showAutoPlayCountdown()
} else {
Expand Down Expand Up @@ -326,7 +325,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {

mediaMetadata.extras?.getString(IntentData.videoId)?.let {
videoId = it
_binding?.autoplayCountdown?.cancelAndHideCountdown()
if (_binding != null) playerBackgroundBinding.autoplayCountdown.cancelAndHideCountdown()

// fix: if the fragment is recreated, play the current video, and not the initial one
arguments?.run {
Expand Down Expand Up @@ -432,8 +431,8 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {

viewModel.segments.observe(viewLifecycleOwner) { segments ->
binding.descriptionLayout.setSegments(segments)
playerBinding.exoProgress.setSegments(segments)
playerBinding.sbToggle.isVisible = segments.isNotEmpty()
playerControlsBinding.exoProgress.setSegments(segments)
playerControlsBinding.sbToggle.isVisible = segments.isNotEmpty()
segments.firstOrNull { it.category == PlayerHelper.SPONSOR_HIGHLIGHT_CATEGORY }
?.let {
lifecycleScope.launch(Dispatchers.IO) { initializeHighlight(it) }
Expand Down Expand Up @@ -508,6 +507,8 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
// if the player is minimized, the fragment behind the player should handle the event
onBackPressedCallback.isEnabled = isMiniPlayerVisible != true
}

toggleVideoInfoVisibility(false)
}

private fun attachToPlayerService(playerData: PlayerData, startNewSession: Boolean) {
Expand Down Expand Up @@ -596,7 +597,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
updateCurrentSubtitle(null)
disableController()
commonPlayerViewModel.setSheetExpand(null)
binding.sbSkipBtn.isGone = true
playerBackgroundBinding.sbSkipBtn.isGone = true
if (NavBarHelper.hasTabs()) {
mainMotionLayout.progress = 1F
}
Expand Down Expand Up @@ -644,7 +645,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
binding.closeImageView.setOnClickListener {
killPlayerFragment()
}
playerBinding.closeImageButton.setOnClickListener {
playerControlsBinding.closeImageButton.setOnClickListener {
killPlayerFragment()
}

Expand Down Expand Up @@ -672,7 +673,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {

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

Expand Down Expand Up @@ -739,11 +740,11 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
}.show(childFragmentManager, AddToPlaylistDialog::class.java.name)
}

playerBinding.skipPrev.setOnClickListener {
playerControlsBinding.skipPrev.setOnClickListener {
PlayingQueue.getPrev()?.let { prev -> playNextVideo(prev) }
}

playerBinding.skipNext.setOnClickListener {
playerControlsBinding.skipNext.setOnClickListener {
PlayingQueue.getNext()?.let { next -> playNextVideo(next) }
}

Expand Down Expand Up @@ -1040,27 +1041,27 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
SbSkipOptions.MANUAL
) || autoSkipTemporarilyDisabled
) {
binding.sbSkipBtn.isVisible = true
binding.sbSkipBtn.setOnClickListener {
playerBackgroundBinding.sbSkipBtn.isVisible = true
playerBackgroundBinding.sbSkipBtn.setOnClickListener {
playerController.seekTo((segment.segmentStartAndEnd.second * 1000f).toLong())
segment.skipped = true
}
}
} else {
binding.sbSkipBtn.isGone = true
playerBackgroundBinding.sbSkipBtn.isGone = true
}
}

private fun setPlayerDefaults() {
// reset the player view
playerBinding.exoProgress.clearSegments()
playerBinding.sbToggle.isGone = true
playerControlsBinding.exoProgress.clearSegments()
playerControlsBinding.sbToggle.isGone = true

// reset the comments to become reloaded later
commentsViewModel.reset()

// hide the button to skip SponsorBlock segments manually
binding.sbSkipBtn.isGone = true
playerBackgroundBinding.sbSkipBtn.isGone = true

// use the video's default audio track when starting playback
playerController.sendCustomCommand(
Expand Down Expand Up @@ -1104,7 +1105,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
binding.descriptionLayout.isInvisible = !show
binding.relatedRecView.isInvisible = !show
binding.playerChannel.isInvisible = !show
binding.videoTransitionProgress.isVisible = !show
playerBackgroundBinding.videoTransitionProgress.isVisible = !show
}

@SuppressLint("SetTextI18n")
Expand All @@ -1125,11 +1126,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
}

// initialize the player view actions
binding.player.initialize(
doubleTapOverlayBinding,
playerGestureControlsViewBinding,
chaptersViewModel
)
binding.player.initialize(chaptersViewModel)
binding.player.initPlayerOptions(
viewModel,
commonPlayerViewModel,
Expand Down Expand Up @@ -1163,7 +1160,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
player.isLive = streams.isLive
relPlayerDownload.isVisible = !streams.isLive
}
playerBinding.exoTitle.text = streams.title
playerControlsBinding.exoTitle.text = streams.title

// init the chapters recyclerview
chaptersViewModel.chaptersLiveData.postValue(streams.chapters)
Expand All @@ -1186,25 +1183,25 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
)

// seekbar preview setup
playerBinding.seekbarPreview.isGone = true
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
playerControlsBinding.seekbarPreview.isGone = true
seekBarPreviewListener?.let { playerControlsBinding.exoProgress.removeListener(it) }
seekBarPreviewListener = createSeekbarPreviewListener().also {
playerBinding.exoProgress.addSeekBarListener(it)
playerControlsBinding.exoProgress.addSeekBarListener(it)
}
}

private fun showAutoPlayCountdown() {
if (!PlayingQueue.hasNext()) return

disableController()
binding.autoplayCountdown.setHideSelfListener {
playerBackgroundBinding.autoplayCountdown.setHideSelfListener {
// could fail if the video already got closed before
runCatching {
binding.autoplayCountdown.isGone = true
playerBackgroundBinding.autoplayCountdown.isGone = true
binding.player.useController = true
}
}
binding.autoplayCountdown.startCountdown {
playerBackgroundBinding.autoplayCountdown.startCountdown {
PlayingQueue.getNext()?.let { playNextVideo(it) }
}
}
Expand Down Expand Up @@ -1507,7 +1504,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
private fun createSeekbarPreviewListener(): SeekbarPreviewListener {
return SeekbarPreviewListener(
OnlineTimeFrameReceiver(requireContext(), streams.previewFrames),
playerBinding,
playerControlsBinding,
streams.duration * 1000
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import android.text.format.DateUtils
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.Window
import android.widget.FrameLayout
import android.widget.ImageView
Expand Down Expand Up @@ -40,6 +39,7 @@ import androidx.media3.ui.TimeBar
import com.github.libretube.R
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.CustomExoPlayerViewTemplateBinding
import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.databinding.PlayerGestureControlsViewBinding
Expand Down Expand Up @@ -80,16 +80,18 @@ abstract class CustomExoPlayerView(
) : PlayerView(context, attributeSet), PlayerOptions, PlayerGestureOptions {
@Suppress("LeakingThis")
val binding = ExoStyledPlayerControlViewBinding.bind(this)
val backgroundBinding = CustomExoPlayerViewTemplateBinding.bind(this)

/**
* Objects for player tap and swipe gesture
*/
private lateinit var gestureViewBinding: PlayerGestureControlsViewBinding
private val gestureViewBinding: PlayerGestureControlsViewBinding get() = backgroundBinding.playerGestureControlsView.binding
private val doubleTapOverlayBinding: DoubleTapOverlayBinding get() = backgroundBinding.doubleTapOverlay.binding

private lateinit var playerGestureController: PlayerGestureController
private lateinit var brightnessHelper: BrightnessHelper
private lateinit var audioHelper: AudioHelper
private lateinit var chaptersViewModel: ChaptersViewModel
private var doubleTapOverlayBinding: DoubleTapOverlayBinding? = null
private var chaptersBottomSheet: ChaptersBottomSheet? = null
private var scrubbingTimeBar = false

Expand Down Expand Up @@ -132,13 +134,7 @@ abstract class CustomExoPlayerView(
if (isControllerFullyVisible) hideController() else showController()
}

fun initialize(
doubleTapOverlayBinding: DoubleTapOverlayBinding,
playerGestureControlsViewBinding: PlayerGestureControlsViewBinding,
chaptersViewModel: ChaptersViewModel
) {
this.doubleTapOverlayBinding = doubleTapOverlayBinding
this.gestureViewBinding = playerGestureControlsViewBinding
fun initialize(chaptersViewModel: ChaptersViewModel) {
this.chaptersViewModel = chaptersViewModel
this.playerGestureController = PlayerGestureController(context as BaseActivity, this)
this.brightnessHelper = BrightnessHelper(context as Activity)
Expand Down Expand Up @@ -367,6 +363,10 @@ abstract class CustomExoPlayerView(
// remove the callback to hide the controller
cancelHideControllerTask()
super.hideController()
backgroundBinding.exoControlsBackground.animate()
.alpha(0f)
.setDuration(500)
.start()
}

override fun showController() {
Expand All @@ -375,6 +375,10 @@ abstract class CustomExoPlayerView(
// automatically hide the controller after 2 seconds
enqueueHideControllerTask()
super.showController()
backgroundBinding.exoControlsBackground.animate()
.alpha(1f)
.setDuration(200)
.start()
}

fun showControllerPermanently() {
Expand All @@ -388,12 +392,12 @@ abstract class CustomExoPlayerView(
private fun initRewindAndForward() {
val seekIncrementText = (PlayerHelper.seekIncrement / 1000).toString()
listOf(
doubleTapOverlayBinding?.rewindTV,
doubleTapOverlayBinding?.forwardTV,
doubleTapOverlayBinding.rewindTV,
doubleTapOverlayBinding.forwardTV,
binding.forwardTV,
binding.rewindTV
).forEach {
it?.text = seekIncrementText
it.text = seekIncrementText
}
binding.forwardBTN.setOnClickListener {
player?.seekBy(PlayerHelper.seekIncrement)
Expand Down Expand Up @@ -475,7 +479,7 @@ abstract class CustomExoPlayerView(
}

// hide the dimming background overlay if locked
binding.exoControlsBackground.setBackgroundColor(
backgroundBinding.exoControlsBackground.setBackgroundColor(
if (isLocked) {
ContextCompat.getColor(
context,
Expand All @@ -494,7 +498,7 @@ abstract class CustomExoPlayerView(
player?.seekBy(-PlayerHelper.seekIncrement)

// show the rewind button
doubleTapOverlayBinding?.apply {
doubleTapOverlayBinding.apply {
animateSeeking(rewindBTN, rewindIV, rewindTV, true)

// start callback to hide the button
Expand All @@ -509,7 +513,7 @@ abstract class CustomExoPlayerView(
player?.seekBy(PlayerHelper.seekIncrement)

// show the forward button
doubleTapOverlayBinding?.apply {
doubleTapOverlayBinding.apply {
animateSeeking(forwardBTN, forwardIV, forwardTV, false)

// start callback to hide the button
Expand Down Expand Up @@ -604,7 +608,7 @@ abstract class CustomExoPlayerView(
private fun updateVolume(distance: Float) {
val bar = gestureViewBinding.volumeProgressBar
gestureViewBinding.volumeControlView.apply {
if (visibility == View.GONE) {
if (isGone) {
isVisible = true
// Volume could be changed using other mediums, sync progress
// bar with new value.
Expand Down
Loading
Loading