mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 00:10:32 +05:30
refactor: move some player view related code to OnlinePlayerView.kt
This commit is contained in:
parent
9f69770b39
commit
df087054d9
@ -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 {
|
fun handlePlayerAction(player: Player, playerEvent: PlayerEvent): Boolean {
|
||||||
return when (playerEvent) {
|
return when (playerEvent) {
|
||||||
PlayerEvent.PlayPause -> {
|
PlayerEvent.PlayPause -> {
|
||||||
|
@ -14,7 +14,6 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.text.format.DateUtils
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -32,7 +31,6 @@ import androidx.core.os.postDelayed
|
|||||||
import androidx.core.view.SoftwareKeyboardControllerCompat
|
import androidx.core.view.SoftwareKeyboardControllerCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@ -102,7 +100,6 @@ import com.github.libretube.ui.models.CommentsViewModel
|
|||||||
import com.github.libretube.ui.models.PlayerViewModel
|
import com.github.libretube.ui.models.PlayerViewModel
|
||||||
import com.github.libretube.ui.sheets.BaseBottomSheet
|
import com.github.libretube.ui.sheets.BaseBottomSheet
|
||||||
import com.github.libretube.ui.sheets.CommentsSheet
|
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.ui.sheets.StatsSheet
|
||||||
import com.github.libretube.util.NowPlayingNotification
|
import com.github.libretube.util.NowPlayingNotification
|
||||||
import com.github.libretube.util.OnlineTimeFrameReceiver
|
import com.github.libretube.util.OnlineTimeFrameReceiver
|
||||||
@ -160,9 +157,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
Executors.newCachedThreadPool()
|
Executors.newCachedThreadPool()
|
||||||
)
|
)
|
||||||
|
|
||||||
// SponsorBlock
|
|
||||||
private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled
|
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
private var seekBarPreviewListener: SeekbarPreviewListener? = null
|
private var seekBarPreviewListener: SeekbarPreviewListener? = null
|
||||||
@ -271,7 +265,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onEvents(player: Player, events: Player.Events) {
|
override fun onEvents(player: Player, events: Player.Events) {
|
||||||
updateDisplayedDuration()
|
|
||||||
super.onEvents(player, events)
|
super.onEvents(player, events)
|
||||||
|
|
||||||
if (events.containsAny(
|
if (events.containsAny(
|
||||||
@ -522,7 +515,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
playerBinding.closeImageButton.setOnClickListener {
|
playerBinding.closeImageButton.setOnClickListener {
|
||||||
onManualPlayerClose()
|
onManualPlayerClose()
|
||||||
}
|
}
|
||||||
playerBinding.autoPlay.isVisible = true
|
|
||||||
|
|
||||||
binding.playImageView.setOnClickListener {
|
binding.playImageView.setOnClickListener {
|
||||||
exoPlayer.togglePlayPauseState()
|
exoPlayer.togglePlayPauseState()
|
||||||
@ -540,28 +532,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
CommentsSheet().show(childFragmentManager)
|
CommentsSheet().show(childFragmentManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
playerBinding.queueToggle.isVisible = true
|
|
||||||
playerBinding.queueToggle.setOnClickListener {
|
|
||||||
PlayingQueueSheet().show(childFragmentManager, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FullScreen button trigger
|
// FullScreen button trigger
|
||||||
// hide fullscreen button if autorotation enabled
|
// hide fullscreen button if autorotation enabled
|
||||||
playerBinding.fullscreen.setOnClickListener {
|
playerBinding.fullscreen.setOnClickListener {
|
||||||
toggleFullscreen()
|
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
|
// share button
|
||||||
binding.relPlayerShare.setOnClickListener {
|
binding.relPlayerShare.setOnClickListener {
|
||||||
if (!this::streams.isInitialized) return@setOnClickListener
|
if (!this::streams.isInitialized) return@setOnClickListener
|
||||||
@ -695,16 +671,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
updateFullscreenOrientation()
|
updateFullscreenOrientation()
|
||||||
|
|
||||||
commentsViewModel.setCommentSheetExpand(null)
|
commentsViewModel.setCommentSheetExpand(null)
|
||||||
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen_exit)
|
|
||||||
playerBinding.exoTitle.isVisible = true
|
|
||||||
|
|
||||||
updateResolutionOnFullscreenChange(true)
|
updateResolutionOnFullscreenChange(true)
|
||||||
|
|
||||||
openOrCloseFullscreenDialog(true)
|
openOrCloseFullscreenDialog(true)
|
||||||
|
|
||||||
binding.player.updateMarginsByFullscreenMode()
|
binding.player.updateMarginsByFullscreenMode()
|
||||||
|
|
||||||
updateFullscreenButtonVisibility()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
@ -718,8 +690,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewModel.isFullscreen.value = false
|
viewModel.isFullscreen.value = false
|
||||||
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen)
|
|
||||||
playerBinding.exoTitle.isInvisible = true
|
|
||||||
|
|
||||||
if (!PlayerHelper.autoFullscreenEnabled) {
|
if (!PlayerHelper.autoFullscreenEnabled) {
|
||||||
mainActivity.requestedOrientation = mainActivity.screenOrientationPref
|
mainActivity.requestedOrientation = mainActivity.screenOrientationPref
|
||||||
@ -729,12 +699,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
updateResolutionOnFullscreenChange(false)
|
updateResolutionOnFullscreenChange(false)
|
||||||
|
|
||||||
binding.player.updateMarginsByFullscreenMode()
|
binding.player.updateMarginsByFullscreenMode()
|
||||||
|
|
||||||
updateFullscreenButtonVisibility()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateFullscreenButtonVisibility() {
|
|
||||||
playerBinding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -881,7 +845,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
if (!exoPlayer.isPlaying || !PlayerHelper.sponsorBlockEnabled) return
|
if (!exoPlayer.isPlaying || !PlayerHelper.sponsorBlockEnabled) return
|
||||||
|
|
||||||
handler.postDelayed(this::checkForSegments, 100)
|
handler.postDelayed(this::checkForSegments, 100)
|
||||||
if (!sponsorBlockEnabled || viewModel.segments.isEmpty()) return
|
if (!viewModel.sponsorBlockEnabled || viewModel.segments.isEmpty()) return
|
||||||
|
|
||||||
exoPlayer.checkForSegments(
|
exoPlayer.checkForSegments(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
@ -949,7 +913,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
) {
|
) {
|
||||||
setFullscreen()
|
setFullscreen()
|
||||||
}
|
}
|
||||||
updateFullscreenButtonVisibility()
|
|
||||||
|
|
||||||
binding.player.apply {
|
binding.player.apply {
|
||||||
useController = false
|
useController = false
|
||||||
@ -1000,7 +963,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
playerBinding.exoProgress.setSegments(viewModel.segments)
|
playerBinding.exoProgress.setSegments(viewModel.segments)
|
||||||
playerBinding.sbToggle.isVisible = true
|
playerBinding.sbToggle.isVisible = true
|
||||||
updateDisplayedDuration()
|
|
||||||
}
|
}
|
||||||
viewModel.segments.firstOrNull { it.category == PlayerHelper.SPONSOR_HIGHLIGHT_CATEGORY }
|
viewModel.segments.firstOrNull { it.category == PlayerHelper.SPONSOR_HIGHLIGHT_CATEGORY }
|
||||||
?.let {
|
?.let {
|
||||||
@ -1082,8 +1044,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
this.streams.uploader
|
this.streams.uploader
|
||||||
)
|
)
|
||||||
|
|
||||||
syncQueueButtons()
|
|
||||||
|
|
||||||
// seekbar preview setup
|
// seekbar preview setup
|
||||||
playerBinding.seekbarPreview.isGone = true
|
playerBinding.seekbarPreview.isGone = true
|
||||||
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
|
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
|
||||||
@ -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() {
|
private fun updatePlayPauseButton() {
|
||||||
binding.playImageView.setImageResource(PlayerHelper.getPlayPauseActionIcon(exoPlayer))
|
binding.playImageView.setImageResource(PlayerHelper.getPlayPauseActionIcon(exoPlayer))
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ import com.github.libretube.api.obj.Message
|
|||||||
import com.github.libretube.api.obj.Segment
|
import com.github.libretube.api.obj.Segment
|
||||||
import com.github.libretube.api.obj.Streams
|
import com.github.libretube.api.obj.Streams
|
||||||
import com.github.libretube.api.obj.Subtitle
|
import com.github.libretube.api.obj.Subtitle
|
||||||
|
import com.github.libretube.constants.PreferenceKeys
|
||||||
import com.github.libretube.helpers.PlayerHelper
|
import com.github.libretube.helpers.PlayerHelper
|
||||||
|
import com.github.libretube.helpers.PreferenceHelper
|
||||||
import com.github.libretube.util.NowPlayingNotification
|
import com.github.libretube.util.NowPlayingNotification
|
||||||
import com.github.libretube.util.deArrow
|
import com.github.libretube.util.deArrow
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -51,6 +53,7 @@ class PlayerViewModel : ViewModel() {
|
|||||||
val chaptersLiveData = MutableLiveData<List<ChapterSegment>>()
|
val chaptersLiveData = MutableLiveData<List<ChapterSegment>>()
|
||||||
|
|
||||||
val chapters get() = chaptersLiveData.value.orEmpty()
|
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
|
* @return pair of the stream info and the error message if the request was not successful
|
||||||
|
@ -170,20 +170,7 @@ abstract class CustomExoPlayerView(
|
|||||||
player?.addListener(object : Player.Listener {
|
player?.addListener(object : Player.Listener {
|
||||||
override fun onEvents(player: Player, events: Player.Events) {
|
override fun onEvents(player: Player, events: Player.Events) {
|
||||||
super.onEvents(player, events)
|
super.onEvents(player, events)
|
||||||
if (events.containsAny(
|
this@CustomExoPlayerView.onPlaybackEvents(player, events)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -820,6 +807,23 @@ abstract class CustomExoPlayerView(
|
|||||||
return true
|
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
|
open fun minimizeOrExitPlayer() = Unit
|
||||||
|
|
||||||
abstract fun getChapters(): List<ChapterSegment>
|
abstract fun getChapters(): List<ChapterSegment>
|
||||||
|
@ -2,12 +2,15 @@ package com.github.libretube.ui.views
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.format.DateUtils
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.media3.common.C
|
import androidx.media3.common.C
|
||||||
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.exoplayer.trackselection.TrackSelector
|
import androidx.media3.exoplayer.trackselection.TrackSelector
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
@ -24,6 +27,7 @@ import com.github.libretube.ui.dialogs.SubmitDeArrowDialog
|
|||||||
import com.github.libretube.ui.dialogs.SubmitSegmentDialog
|
import com.github.libretube.ui.dialogs.SubmitSegmentDialog
|
||||||
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
||||||
import com.github.libretube.ui.models.PlayerViewModel
|
import com.github.libretube.ui.models.PlayerViewModel
|
||||||
|
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
||||||
import com.github.libretube.util.PlayingQueue
|
import com.github.libretube.util.PlayingQueue
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -154,14 +158,39 @@ class OnlinePlayerView(
|
|||||||
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
|
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
|
||||||
WindowHelper.toggleFullscreen(activity.window, isFullscreen)
|
WindowHelper.toggleFullscreen(activity.window, isFullscreen)
|
||||||
updateTopBarMargin()
|
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.isChecked = PlayerHelper.autoPlayEnabled
|
||||||
|
|
||||||
binding.autoPlay.setOnCheckedChangeListener { _, isChecked ->
|
binding.autoPlay.setOnCheckedChangeListener { _, isChecked ->
|
||||||
PlayerHelper.autoPlayEnabled = 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.isVisible = PreferenceHelper.getBoolean(PreferenceKeys.CONTRIBUTE_TO_SB, false)
|
||||||
binding.sbSubmit.setOnClickListener {
|
binding.sbSubmit.setOnClickListener {
|
||||||
val submitSegmentDialog = SubmitSegmentDialog()
|
val submitSegmentDialog = SubmitSegmentDialog()
|
||||||
@ -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 getWindow(): Window = currentWindow ?: activity.window
|
||||||
|
|
||||||
override fun hideController() {
|
override fun hideController() {
|
||||||
@ -219,4 +280,9 @@ class OnlinePlayerView(
|
|||||||
override fun getChapters(): List<ChapterSegment> {
|
override fun getChapters(): List<ChapterSegment> {
|
||||||
return playerViewModel?.chapters.orEmpty()
|
return playerViewModel?.chapters.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPlaybackEvents(player: Player, events: Player.Events) {
|
||||||
|
super.onPlaybackEvents(player, events)
|
||||||
|
updateDisplayedDuration()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user