seperate playerView logic

This commit is contained in:
Bnyro 2022-09-09 10:51:56 +02:00
parent c3ad60f19c
commit 37dcef7fce
3 changed files with 325 additions and 290 deletions

View File

@ -46,8 +46,6 @@ import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.constants.PreferenceRanges
import com.github.libretube.databinding.DialogSliderBinding
import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.databinding.FragmentPlayerBinding
@ -61,10 +59,8 @@ import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.await
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.setSliderRangeAndValue
import com.github.libretube.extensions.toID
import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.interfaces.PlayerViewInterface
import com.github.libretube.models.PlayerViewModel
import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.Segment
@ -77,7 +73,6 @@ import com.github.libretube.util.ImageHelper
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.PlayerHelper
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.views.PlayerOptionsBottomSheet
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.ExoPlayer
@ -92,13 +87,11 @@ import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.MergingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.CaptionStyleCompat
import com.google.android.exoplayer2.ui.StyledPlayerView
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.google.android.exoplayer2.util.RepeatModeUtil
import com.google.android.exoplayer2.video.VideoSize
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
@ -153,7 +146,6 @@ class PlayerFragment : BaseFragment() {
* for the player view
*/
private lateinit var exoPlayerView: StyledPlayerView
private var isPlayerLocked: Boolean = false
private var subtitle = mutableListOf<SubtitleConfiguration>()
/**
@ -161,7 +153,6 @@ class PlayerFragment : BaseFragment() {
*/
private var token = ""
private var relatedStreamsEnabled = true
private var autoplayEnabled = false
private var autoRotationEnabled = true
private var playbackSpeed = "1F"
private var pausePlayerOnScreenOffEnabled = false
@ -169,7 +160,6 @@ class PlayerFragment : BaseFragment() {
private var watchHistoryEnabled = true
private var watchPositionsEnabled = true
private var useSystemCaptionStyle = true
private var seekIncrement = 5L
private var videoFormatPreference = "webm"
private var defRes = ""
private var bufferingGoal = 50000
@ -178,7 +168,6 @@ class PlayerFragment : BaseFragment() {
private var sponsorBlockNotifications = true
private var skipButtonsEnabled = false
private var pipEnabled = true
private var resizeModePref = "fit"
/**
* for autoplay
@ -245,7 +234,7 @@ class PlayerFragment : BaseFragment() {
* somehow the bottom bar is invisible on low screen resolutions, this fixes it
*/
private fun showBottomBar() {
if (this::playerBinding.isInitialized && !isPlayerLocked) {
if (this::playerBinding.isInitialized && !binding.player.isPlayerLocked) {
playerBinding.exoBottomBar.visibility = View.VISIBLE
}
Handler(Looper.getMainLooper()).postDelayed(this::showBottomBar, 100)
@ -260,11 +249,7 @@ class PlayerFragment : BaseFragment() {
false
)
// save whether related streams and autoplay are enabled
autoplayEnabled = PreferenceHelper.getBoolean(
PreferenceKeys.AUTO_PLAY,
false
)
// save whether related streams are enabled
relatedStreamsEnabled = PreferenceHelper.getBoolean(
PreferenceKeys.RELATED_STREAMS,
true
@ -300,11 +285,6 @@ class PlayerFragment : BaseFragment() {
true
)
seekIncrement = PreferenceHelper.getString(
PreferenceKeys.SEEK_INCREMENT,
"5"
).toLong() * 1000
videoFormatPreference = PreferenceHelper.getString(
PreferenceKeys.PLAYER_VIDEO_FORMAT,
"webm"
@ -348,11 +328,6 @@ class PlayerFragment : BaseFragment() {
PreferenceKeys.PICTURE_IN_PICTURE,
true
)
resizeModePref = PreferenceHelper.getString(
PreferenceKeys.PLAYER_RESIZE_MODE,
"fit"
)
}
@SuppressLint("ClickableViewAccessibility")
@ -424,25 +399,7 @@ class PlayerFragment : BaseFragment() {
}
}
private val playerOptionsInterface = object : PlayerOptionsInterface {
override fun onAutoplayClicked() {
// autoplay options dialog
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.player_autoplay)
.setItems(
arrayOf(
context?.getString(R.string.enabled),
context?.getString(R.string.disabled)
)
) { _, index ->
when (index) {
0 -> autoplayEnabled = true
1 -> autoplayEnabled = false
}
}
.show()
}
private val playerViewInterface = object : PlayerViewInterface {
override fun onCaptionClicked() {
if (!this@PlayerFragment::streams.isInitialized ||
streams.subtitles == null ||
@ -515,62 +472,6 @@ class PlayerFragment : BaseFragment() {
}
.show()
}
override fun onPlaybackSpeedClicked() {
val playbackSpeedBinding = DialogSliderBinding.inflate(layoutInflater)
playbackSpeedBinding.slider.setSliderRangeAndValue(
PreferenceRanges.playbackSpeed
)
playbackSpeedBinding.slider.value = exoPlayer.playbackParameters.speed
// change playback speed dialog
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.change_playback_speed)
.setView(playbackSpeedBinding.root)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.okay) { _, _ ->
exoPlayer.setPlaybackSpeed(
playbackSpeedBinding.slider.value
)
}
.show()
}
override fun onResizeModeClicked() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModeNames = context?.resources?.getStringArray(R.array.resizeMode)
val aspectRatioModes = arrayOf(
AspectRatioFrameLayout.RESIZE_MODE_FIT,
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
AspectRatioFrameLayout.RESIZE_MODE_FILL
)
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.aspect_ratio)
.setItems(aspectRatioModeNames) { _, index ->
exoPlayerView.resizeMode = aspectRatioModes[index]
}
.show()
}
override fun onRepeatModeClicked() {
val repeatModeNames = arrayOf(
context?.getString(R.string.repeat_mode_none),
context?.getString(R.string.repeat_mode_current)
)
val repeatModes = arrayOf(
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
)
// repeat mode options dialog
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.repeat_mode)
.setItems(repeatModeNames) { _, index ->
exoPlayer.repeatMode = repeatModes[index]
}
.show()
}
}
// actions that don't depend on video information
@ -591,55 +492,6 @@ class PlayerFragment : BaseFragment() {
.remove(this)
.commit()
}
// show the advanced player options
playerBinding.toggleOptions.setOnClickListener {
val bottomSheetFragment = PlayerOptionsBottomSheet().apply {
setOnClickListeners(playerOptionsInterface)
// set the auto play mode
currentAutoplayMode = if (autoplayEnabled) {
context.getString(R.string.enabled)
} else {
context.getString(R.string.disabled)
}
// set the current caption language
currentCaptions =
if (trackSelector.parameters.preferredTextLanguages.isNotEmpty()) {
trackSelector.parameters.preferredTextLanguages[0]
} else {
context.getString(R.string.none)
}
// set the playback speed
currentPlaybackSpeed = "${
exoPlayer.playbackParameters.speed.toString()
.replace(".0", "")
}x"
// set the quality text
val isAdaptive = exoPlayer.videoFormat?.codecs != null
val quality = exoPlayer.videoSize.height
if (quality != 0) {
currentQuality =
if (isAdaptive) {
"${context.getString(R.string.hls)}${quality}p"
} else {
"${quality}p"
}
}
// set the repeat mode
currentRepeatMode =
if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
context.getString(R.string.repeat_mode_none)
} else {
context.getString(R.string.repeat_mode_current)
}
// set the aspect ratio mode
currentResizeMode = when (exoPlayerView.resizeMode) {
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context.getString(R.string.resize_mode_fit)
AspectRatioFrameLayout.RESIZE_MODE_FILL -> context.getString(R.string.resize_mode_fill)
else -> context.getString(R.string.resize_mode_zoom)
}
}
bottomSheetFragment.show(childFragmentManager, null)
}
binding.playImageView.setOnClickListener {
if (!exoPlayer.isPlaying) {
@ -677,22 +529,6 @@ class PlayerFragment : BaseFragment() {
}
}
// lock and unlock the player
playerBinding.lockPlayer.setOnClickListener {
// change the locked/unlocked icon
if (!isPlayerLocked) {
playerBinding.lockPlayer.setImageResource(R.drawable.ic_locked)
} else {
playerBinding.lockPlayer.setImageResource(R.drawable.ic_unlocked)
}
// show/hide all the controls
lockPlayer(isPlayerLocked)
// change locked status
isPlayerLocked = !isPlayerLocked
}
// set default playback speed
exoPlayer.setPlaybackSpeed(playbackSpeed.toFloat())
@ -919,7 +755,7 @@ class PlayerFragment : BaseFragment() {
// show comments if related streams disabled
if (!relatedStreamsEnabled) toggleComments()
// prepare for autoplay
if (autoplayEnabled) setNextStream()
if (binding.player.autoplayEnabled) setNextStream()
// add the video to the watch history
if (watchHistoryEnabled) DatabaseHelper.addToWatchHistory(videoId!!, streams)
@ -1023,11 +859,6 @@ class PlayerFragment : BaseFragment() {
controllerHideOnTouch = true
useController = false
player = exoPlayer
resizeMode = when (resizeModePref) {
"fill" -> AspectRatioFrameLayout.RESIZE_MODE_FILL
"zoom" -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
}
}
if (useSystemCaptionStyle) {
@ -1049,6 +880,14 @@ class PlayerFragment : BaseFragment() {
@SuppressLint("SetTextI18n")
private fun initializePlayerView(response: Streams) {
// initialize the player view actions
binding.player.initialize(
childFragmentManager,
playerViewInterface,
doubleTapOverlayBinding,
trackSelector
)
binding.apply {
playerViewsInfo.text =
context?.getString(R.string.views, response.views.formatShort()) +
@ -1073,8 +912,6 @@ class PlayerFragment : BaseFragment() {
playerBinding.exoTitle.text = response.title
enableDoubleTapToSeek()
// init the chapters recyclerview
if (response.chapters != null) {
chapters = response.chapters
@ -1120,11 +957,11 @@ class PlayerFragment : BaseFragment() {
playbackState == Player.STATE_ENDED &&
nextStreamId != null &&
!transitioning &&
autoplayEnabled
binding.player.autoplayEnabled
) {
transitioning = true
// check whether autoplay is enabled
if (autoplayEnabled) playNextVideo()
if (binding.player.autoplayEnabled) playNextVideo()
}
if (playbackState == Player.STATE_READY) {
@ -1250,83 +1087,6 @@ class PlayerFragment : BaseFragment() {
}
}
private fun enableDoubleTapToSeek() {
// set seek increment text
val seekIncrementText = (seekIncrement / 1000).toString()
doubleTapOverlayBinding.rewindTV.text = seekIncrementText
doubleTapOverlayBinding.forwardTV.text = seekIncrementText
binding.player.setOnDoubleTapListener(
object : DoubleTapInterface {
override fun onEvent(x: Float) {
val width = exoPlayerView.width
when {
width * 0.5 > x -> rewind()
width * 0.5 < x -> forward()
}
}
}
)
}
private fun rewind() {
exoPlayer.seekTo(exoPlayer.currentPosition - seekIncrement)
// show the rewind button
doubleTapOverlayBinding.rewindBTN.apply {
visibility = View.VISIBLE
// clear previous animation
animate().rotation(0F).setDuration(0).start()
// start new animation
animate()
.rotation(-30F)
.setDuration(100)
.withEndAction {
// reset the animation when finished
animate().rotation(0F).setDuration(100).start()
}
.start()
removeCallbacks(hideRewindButtonRunnable)
// start callback to hide the button
postDelayed(hideRewindButtonRunnable, 700)
}
}
private fun forward() {
exoPlayer.seekTo(exoPlayer.currentPosition + seekIncrement)
// show the forward button
doubleTapOverlayBinding.forwardBTN.apply {
visibility = View.VISIBLE
// clear previous animation
animate().rotation(0F).setDuration(0).start()
// start new animation
animate()
.rotation(30F)
.setDuration(100)
.withEndAction {
// reset the animation when finished
animate().rotation(0F).setDuration(100).start()
}
.start()
// start callback to hide the button
removeCallbacks(hideForwardButtonRunnable)
postDelayed(hideForwardButtonRunnable, 700)
}
}
private val hideForwardButtonRunnable = Runnable {
doubleTapOverlayBinding.forwardBTN.apply {
visibility = View.GONE
}
}
private val hideRewindButtonRunnable = Runnable {
doubleTapOverlayBinding.rewindBTN.apply {
visibility = View.GONE
}
}
private fun initializeChapters() {
if (chapters.isEmpty()) {
binding.chaptersRecView.visibility = View.GONE
@ -1533,7 +1293,7 @@ class PlayerFragment : BaseFragment() {
// handles the audio focus
val audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MOVIE)
.setContentType(C.AUDIO_CONTENT_TYPE_MOVIE)
.build()
// handles the duration of media to retain in the buffer prior to the current playback position (for fast backward seeking)
@ -1570,34 +1330,6 @@ class PlayerFragment : BaseFragment() {
nowPlayingNotification.updatePlayerNotification(streams)
}
// lock the player
private fun lockPlayer(isLocked: Boolean) {
// isLocked is the current (old) state of the player lock
val visibility = if (isLocked) View.VISIBLE else View.GONE
playerBinding.exoTopBarRight.visibility = visibility
playerBinding.exoCenterControls.visibility = visibility
playerBinding.exoBottomBar.visibility = visibility
playerBinding.closeImageButton.visibility = visibility
playerBinding.exoTitle.visibility =
if (isLocked &&
viewModel.isFullscreen.value == true
) {
View.VISIBLE
} else {
View.INVISIBLE
}
// disable double tap to seek when the player is locked
if (isLocked) {
// enable fast forward and rewind by double tapping
enableDoubleTapToSeek()
} else {
// disable fast forward and rewind by double tapping
binding.player.setOnDoubleTapListener(null)
}
}
private fun isSubscribed() {
fun run() {
val channelId = streams.uploaderUrl!!.toID()

View File

@ -0,0 +1,7 @@
package com.github.libretube.interfaces
interface PlayerViewInterface {
fun onCaptionClicked()
fun onQualityClicked()
}

View File

@ -3,12 +3,28 @@ package com.github.libretube.views
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import androidx.fragment.app.FragmentManager
import com.github.libretube.R
import com.github.libretube.activities.MainActivity
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.constants.PreferenceRanges
import com.github.libretube.databinding.DialogSliderBinding
import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.extensions.setSliderRangeAndValue
import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.interfaces.PlayerViewInterface
import com.github.libretube.util.DoubleTapListener
import com.github.libretube.util.PreferenceHelper
import com.google.android.exoplayer2.trackselection.TrackSelector
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.StyledPlayerView
import com.google.android.exoplayer2.util.RepeatModeUtil
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@SuppressLint("ClickableViewAccessibility")
internal class CustomExoPlayerView(
@ -16,17 +32,36 @@ internal class CustomExoPlayerView(
attributeSet: AttributeSet? = null
) : StyledPlayerView(context, attributeSet) {
val binding: ExoStyledPlayerControlViewBinding = ExoStyledPlayerControlViewBinding.bind(this)
private var doubleTapOverlayBinding: DoubleTapOverlayBinding? = null
private var doubleTapListener: DoubleTapInterface? = null
private var playerViewInterface: PlayerViewInterface? = null
private lateinit var childFragmentManager: FragmentManager
private lateinit var trackSelector: TrackSelector
// the x-position of where the user clicked
private var xPos = 0F
fun setOnDoubleTapListener(
eventListener: DoubleTapInterface?
) {
doubleTapListener = eventListener
}
var isPlayerLocked: Boolean = false
/**
* Preferences
*/
var autoplayEnabled = PreferenceHelper.getBoolean(
PreferenceKeys.AUTO_PLAY,
false
)
private val seekIncrement = PreferenceHelper.getString(
PreferenceKeys.SEEK_INCREMENT,
"5"
).toLong() * 1000
private var resizeModePref = PreferenceHelper.getString(
PreferenceKeys.PLAYER_RESIZE_MODE,
"fit"
)
private fun toggleController() {
if (isControllerFullyVisible) hideController() else showController()
@ -42,9 +77,44 @@ internal class CustomExoPlayerView(
}
}
init {
fun initialize(
childFragmentManager: FragmentManager,
playerViewInterface: PlayerViewInterface,
doubleTapOverlayBinding: DoubleTapOverlayBinding,
trackSelector: TrackSelector
) {
this.childFragmentManager = childFragmentManager
this.playerViewInterface = playerViewInterface
this.doubleTapOverlayBinding = doubleTapOverlayBinding
this.trackSelector = trackSelector
// set the double click listener for rewind/forward
setOnClickListener(doubleTouchListener)
enableDoubleTapToSeek()
initializeAdvancedOptions()
// locking the player
binding.lockPlayer.setOnClickListener {
// change the locked/unlocked icon
binding.lockPlayer.setImageResource(
if (!isPlayerLocked) R.drawable.ic_locked
else R.drawable.ic_unlocked
)
// show/hide all the controls
lockPlayer(isPlayerLocked)
// change locked status
isPlayerLocked = !isPlayerLocked
}
resizeMode = when (resizeModePref) {
"fill" -> AspectRatioFrameLayout.RESIZE_MODE_FILL
"zoom" -> AspectRatioFrameLayout.RESIZE_MODE_ZOOM
else -> AspectRatioFrameLayout.RESIZE_MODE_FIT
}
}
override fun hideController() {
@ -59,4 +129,230 @@ internal class CustomExoPlayerView(
doubleTouchListener.onClick(this)
return false
}
private fun initializeAdvancedOptions() {
binding.toggleOptions.setOnClickListener {
val bottomSheetFragment = PlayerOptionsBottomSheet().apply {
setOnClickListeners(playerOptionsInterface)
// set the auto play mode
currentAutoplayMode = if (autoplayEnabled) {
context?.getString(R.string.enabled)
} else {
context?.getString(R.string.disabled)
}
// set the current caption language
currentCaptions =
if (trackSelector.parameters.preferredTextLanguages.isNotEmpty()) {
trackSelector.parameters.preferredTextLanguages[0]
} else {
context?.getString(R.string.none)
}
// set the playback speed
currentPlaybackSpeed = "${
player?.playbackParameters?.speed.toString()
.replace(".0", "")
}x"
// set the quality text
val quality = player?.videoSize?.height
if (quality != 0) {
currentQuality = "${quality}p"
}
// set the repeat mode
currentRepeatMode =
if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
context?.getString(R.string.repeat_mode_none)
} else {
context?.getString(R.string.repeat_mode_current)
}
// set the aspect ratio mode
currentResizeMode = when (resizeMode) {
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context?.getString(R.string.resize_mode_fit)
AspectRatioFrameLayout.RESIZE_MODE_FILL -> context?.getString(R.string.resize_mode_fill)
else -> context?.getString(R.string.resize_mode_zoom)
}
}
bottomSheetFragment.show(childFragmentManager, null)
}
}
// lock the player
private fun lockPlayer(isLocked: Boolean) {
// isLocked is the current (old) state of the player lock
val visibility = if (isLocked) View.VISIBLE else View.GONE
binding.exoTopBarRight.visibility = visibility
binding.exoCenterControls.visibility = visibility
binding.exoBottomBar.visibility = visibility
binding.closeImageButton.visibility = visibility
// disable double tap to seek when the player is locked
if (isLocked) {
// enable fast forward and rewind by double tapping
enableDoubleTapToSeek()
} else {
// disable fast forward and rewind by double tapping
doubleTapListener = null
}
}
private fun enableDoubleTapToSeek() {
// set seek increment text
val seekIncrementText = (seekIncrement / 1000).toString()
doubleTapOverlayBinding?.rewindTV?.text = seekIncrementText
doubleTapOverlayBinding?.forwardTV?.text = seekIncrementText
doubleTapListener =
object : DoubleTapInterface {
override fun onEvent(x: Float) {
when {
width * 0.5 > x -> rewind()
width * 0.5 < x -> forward()
}
}
}
}
private fun rewind() {
player?.seekTo((player?.currentPosition ?: 0L) - seekIncrement)
// show the rewind button
doubleTapOverlayBinding?.rewindBTN.apply {
visibility = View.VISIBLE
// clear previous animation
animate().rotation(0F).setDuration(0).start()
// start new animation
animate()
.rotation(-30F)
.setDuration(100)
.withEndAction {
// reset the animation when finished
animate().rotation(0F).setDuration(100).start()
}
.start()
removeCallbacks(hideRewindButtonRunnable)
// start callback to hide the button
postDelayed(hideRewindButtonRunnable, 700)
}
}
private fun forward() {
player?.seekTo(player!!.currentPosition + seekIncrement)
// show the forward button
doubleTapOverlayBinding?.forwardBTN.apply {
visibility = View.VISIBLE
// clear previous animation
animate().rotation(0F).setDuration(0).start()
// start new animation
animate()
.rotation(30F)
.setDuration(100)
.withEndAction {
// reset the animation when finished
animate().rotation(0F).setDuration(100).start()
}
.start()
// start callback to hide the button
removeCallbacks(hideForwardButtonRunnable)
postDelayed(hideForwardButtonRunnable, 700)
}
}
private val hideForwardButtonRunnable = Runnable {
doubleTapOverlayBinding?.forwardBTN.apply {
visibility = View.GONE
}
}
private val hideRewindButtonRunnable = Runnable {
doubleTapOverlayBinding?.rewindBTN.apply {
visibility = View.GONE
}
}
private val playerOptionsInterface = object : PlayerOptionsInterface {
override fun onAutoplayClicked() {
// autoplay options dialog
MaterialAlertDialogBuilder(context)
.setTitle(R.string.player_autoplay)
.setItems(
arrayOf(
context.getString(R.string.enabled),
context.getString(R.string.disabled)
)
) { _, index ->
when (index) {
0 -> autoplayEnabled = true
1 -> autoplayEnabled = false
}
}
.show()
}
override fun onCaptionClicked() {
playerViewInterface?.onCaptionClicked()
}
override fun onQualityClicked() {
playerViewInterface?.onQualityClicked()
}
override fun onPlaybackSpeedClicked() {
val playbackSpeedBinding = DialogSliderBinding.inflate(
LayoutInflater.from(context)
)
playbackSpeedBinding.slider.setSliderRangeAndValue(
PreferenceRanges.playbackSpeed
)
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
// change playback speed dialog
MaterialAlertDialogBuilder(context)
.setTitle(R.string.change_playback_speed)
.setView(playbackSpeedBinding.root)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.okay) { _, _ ->
player?.setPlaybackSpeed(
playbackSpeedBinding.slider.value
)
}
.show()
}
override fun onResizeModeClicked() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode)
val aspectRatioModes = arrayOf(
AspectRatioFrameLayout.RESIZE_MODE_FIT,
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
AspectRatioFrameLayout.RESIZE_MODE_FILL
)
MaterialAlertDialogBuilder(context)
.setTitle(R.string.aspect_ratio)
.setItems(aspectRatioModeNames) { _, index ->
resizeMode = aspectRatioModes[index]
}
.show()
}
override fun onRepeatModeClicked() {
val repeatModeNames = arrayOf(
context.getString(R.string.repeat_mode_none),
context.getString(R.string.repeat_mode_current)
)
val repeatModes = arrayOf(
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
)
// repeat mode options dialog
MaterialAlertDialogBuilder(context)
.setTitle(R.string.repeat_mode)
.setItems(repeatModeNames) { _, index ->
player?.repeatMode = repeatModes[index]
}
.show()
}
}
}