refactor player options

This commit is contained in:
Bnyro 2022-09-10 16:32:40 +02:00
parent 915795eaf0
commit 1d5d254457
8 changed files with 127 additions and 303 deletions

View File

@ -60,7 +60,7 @@ import com.github.libretube.extensions.await
import com.github.libretube.extensions.formatShort import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.hideKeyboard import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.models.PlayerViewModel import com.github.libretube.models.PlayerViewModel
import com.github.libretube.obj.ChapterSegment import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.Segment import com.github.libretube.obj.Segment
@ -399,7 +399,7 @@ class PlayerFragment : BaseFragment() {
} }
} }
private val onlinePlayerOptionsInterface = object : OnlinePlayerOptionsInterface { private val onlinePlayerOptionsInterface = object : PlayerOptionsInterface {
override fun onCaptionClicked() { override fun onCaptionClicked() {
if (!this@PlayerFragment::streams.isInitialized || if (!this@PlayerFragment::streams.isInitialized ||
streams.subtitles == null || streams.subtitles == null ||

View File

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

View File

@ -1,11 +1,7 @@
package com.github.libretube.interfaces package com.github.libretube.interfaces
interface PlayerOptionsInterface { interface PlayerOptionsInterface {
fun onAutoplayClicked() fun onCaptionClicked()
fun onPlaybackSpeedClicked() fun onQualityClicked()
fun onResizeModeClicked()
fun onRepeatModeClicked()
} }

View File

@ -18,8 +18,8 @@ import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.extensions.setSliderRangeAndValue import com.github.libretube.extensions.setSliderRangeAndValue
import com.github.libretube.interfaces.DoubleTapInterface import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface
import com.github.libretube.interfaces.PlayerOptionsInterface import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.obj.BottomSheetItem
import com.github.libretube.util.DoubleTapListener import com.github.libretube.util.DoubleTapListener
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.exoplayer2.trackselection.TrackSelector import com.google.android.exoplayer2.trackselection.TrackSelector
@ -40,7 +40,7 @@ internal class CustomExoPlayerView(
* Objects from the parent fragment * Objects from the parent fragment
*/ */
private var doubleTapListener: DoubleTapInterface? = null private var doubleTapListener: DoubleTapInterface? = null
private var onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface? = null private var playerOptionsInterface: PlayerOptionsInterface? = null
private lateinit var childFragmentManager: FragmentManager private lateinit var childFragmentManager: FragmentManager
private var trackSelector: TrackSelector? = null private var trackSelector: TrackSelector? = null
@ -85,12 +85,12 @@ internal class CustomExoPlayerView(
fun initialize( fun initialize(
childFragmentManager: FragmentManager, childFragmentManager: FragmentManager,
playerViewInterface: OnlinePlayerOptionsInterface?, playerViewInterface: PlayerOptionsInterface?,
doubleTapOverlayBinding: DoubleTapOverlayBinding, doubleTapOverlayBinding: DoubleTapOverlayBinding,
trackSelector: TrackSelector? trackSelector: TrackSelector?
) { ) {
this.childFragmentManager = childFragmentManager this.childFragmentManager = childFragmentManager
this.onlinePlayerOptionsInterface = playerViewInterface this.playerOptionsInterface = playerViewInterface
this.doubleTapOverlayBinding = doubleTapOverlayBinding this.doubleTapOverlayBinding = doubleTapOverlayBinding
this.trackSelector = trackSelector this.trackSelector = trackSelector
@ -141,46 +141,59 @@ internal class CustomExoPlayerView(
private fun initializeAdvancedOptions() { private fun initializeAdvancedOptions() {
binding.toggleOptions.setOnClickListener { binding.toggleOptions.setOnClickListener {
val bottomSheetFragment = PlayerOptionsBottomSheet().apply { val bottomSheetFragment = BottomSheet().apply {
setOnClickListeners( val items = listOf(
playerOptionsInterface, BottomSheetItem(
onlinePlayerOptionsInterface context?.getString(R.string.player_autoplay) + if (autoplayEnabled) {
context?.getString(R.string.enabled)
} else {
context?.getString(R.string.disabled)
},
R.drawable.ic_play
),
BottomSheetItem(
context?.getString(R.string.playback_speed) + "${
player?.playbackParameters?.speed.toString()
.replace(".0", "")
}x",
R.drawable.ic_speed
),
BottomSheetItem(
context?.getString(R.string.repeat_mode) + if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
context?.getString(R.string.repeat_mode_none)
} else {
context?.getString(R.string.repeat_mode_current)
},
R.drawable.ic_repeat
),
BottomSheetItem(
context?.getString(R.string.player_resize_mode) + 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)
},
R.drawable.ic_aspect_ratio
),
BottomSheetItem(
context?.getString(R.string.quality) + "${player?.videoSize?.height}p",
R.drawable.ic_hd
),
BottomSheetItem(
context?.getString(R.string.captions) + if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) {
trackSelector!!.parameters.preferredTextLanguages[0]
} else context?.getString(R.string.none),
R.drawable.ic_caption
)
) )
// set the auto play mode setItems(items) { index ->
currentAutoplayMode = if (autoplayEnabled) { when (index) {
context?.getString(R.string.enabled) 0 -> onAutoplayClicked()
} else { 1 -> onPlaybackSpeedClicked()
context?.getString(R.string.disabled) 2 -> onRepeatModeClicked()
} 3 -> onResizeModeClicked()
// set the current caption language 4 -> playerOptionsInterface?.onQualityClicked()
currentCaptions = 5 -> playerOptionsInterface?.onQualityClicked()
if (trackSelector != null && 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) bottomSheetFragment.show(childFragmentManager, null)
@ -282,81 +295,79 @@ internal class CustomExoPlayerView(
} }
} }
private val playerOptionsInterface = object : PlayerOptionsInterface { fun onAutoplayClicked() {
override fun onAutoplayClicked() { // autoplay options dialog
// autoplay options dialog MaterialAlertDialogBuilder(context)
MaterialAlertDialogBuilder(context) .setTitle(R.string.player_autoplay)
.setTitle(R.string.player_autoplay) .setItems(
.setItems( arrayOf(
arrayOf( context.getString(R.string.enabled),
context.getString(R.string.enabled), context.getString(R.string.disabled)
context.getString(R.string.disabled) )
) ) { _, index ->
) { _, index -> when (index) {
when (index) { 0 -> autoplayEnabled = true
0 -> autoplayEnabled = true 1 -> autoplayEnabled = false
1 -> autoplayEnabled = false
}
} }
.show() }
} .show()
}
override fun onPlaybackSpeedClicked() { fun onPlaybackSpeedClicked() {
val playbackSpeedBinding = DialogSliderBinding.inflate( val playbackSpeedBinding = DialogSliderBinding.inflate(
LayoutInflater.from(context) LayoutInflater.from(context)
) )
playbackSpeedBinding.slider.setSliderRangeAndValue( playbackSpeedBinding.slider.setSliderRangeAndValue(
PreferenceRanges.playbackSpeed PreferenceRanges.playbackSpeed
) )
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
// change playback speed dialog // change playback speed dialog
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.change_playback_speed) .setTitle(R.string.change_playback_speed)
.setView(playbackSpeedBinding.root) .setView(playbackSpeedBinding.root)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.okay) { _, _ -> .setPositiveButton(R.string.okay) { _, _ ->
player?.setPlaybackSpeed( player?.setPlaybackSpeed(
playbackSpeedBinding.slider.value playbackSpeedBinding.slider.value
) )
} }
.show() .show()
} }
override fun onResizeModeClicked() { fun onResizeModeClicked() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen // switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode) val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode)
val aspectRatioModes = arrayOf( val aspectRatioModes = arrayOf(
AspectRatioFrameLayout.RESIZE_MODE_FIT, AspectRatioFrameLayout.RESIZE_MODE_FIT,
AspectRatioFrameLayout.RESIZE_MODE_ZOOM, AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
AspectRatioFrameLayout.RESIZE_MODE_FILL AspectRatioFrameLayout.RESIZE_MODE_FILL
) )
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.aspect_ratio) .setTitle(R.string.aspect_ratio)
.setItems(aspectRatioModeNames) { _, index -> .setItems(aspectRatioModeNames) { _, index ->
resizeMode = aspectRatioModes[index] resizeMode = aspectRatioModes[index]
} }
.show() .show()
} }
override fun onRepeatModeClicked() { fun onRepeatModeClicked() {
val repeatModeNames = arrayOf( val repeatModeNames = arrayOf(
context.getString(R.string.repeat_mode_none), context.getString(R.string.repeat_mode_none),
context.getString(R.string.repeat_mode_current) context.getString(R.string.repeat_mode_current)
) )
val repeatModes = arrayOf( val repeatModes = arrayOf(
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL, RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
) )
// repeat mode options dialog // repeat mode options dialog
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.repeat_mode) .setTitle(R.string.repeat_mode)
.setItems(repeatModeNames) { _, index -> .setItems(repeatModeNames) { _, index ->
player?.repeatMode = repeatModes[index] player?.repeatMode = repeatModes[index]
} }
.show() .show()
}
} }
} }

View File

@ -1,118 +0,0 @@
package com.github.libretube.views
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.github.libretube.databinding.PlayerOptionsBottomSheetBinding
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* Bottom Sheet including all the player options
*/
class PlayerOptionsBottomSheet : BottomSheetDialogFragment() {
lateinit var binding: PlayerOptionsBottomSheetBinding
private lateinit var playerOptionsInterface: PlayerOptionsInterface
private var onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface? = null
/**
* current values
*/
var currentPlaybackSpeed: String? = null
var currentAutoplayMode: String? = null
var currentRepeatMode: String? = null
var currentQuality: String? = null
var currentResizeMode: String? = null
var currentCaptions: String? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// expand the bottom sheet on creation
dialog!!.setOnShowListener { dialog ->
val d = dialog as BottomSheetDialog
val bottomSheetInternal =
d.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)!!
BottomSheetBehavior.from(bottomSheetInternal).state =
BottomSheetBehavior.STATE_EXPANDED
}
binding = PlayerOptionsBottomSheetBinding.inflate(layoutInflater, container, false)
return binding.root
}
fun setOnClickListeners(
playerOptionsInterface: PlayerOptionsInterface,
onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface?
) {
this.playerOptionsInterface = playerOptionsInterface
this.onlinePlayerOptionsInterface = onlinePlayerOptionsInterface
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (onlinePlayerOptionsInterface == null) {
binding.captions.visibility = View.GONE
binding.quality.visibility = View.GONE
}
/**
* update the text if a value is selected
*/
binding.autoplay.updateText(currentAutoplayMode)
binding.captions.updateText(currentCaptions)
binding.playbackSpeed.updateText(currentPlaybackSpeed)
binding.quality.updateText(currentQuality)
binding.repeatMode.updateText(currentRepeatMode)
binding.resizeMode.updateText(currentResizeMode)
binding.resizeMode.setOnClickListener {
playerOptionsInterface.onResizeModeClicked()
this.dismiss()
}
binding.quality.setOnClickListener {
onlinePlayerOptionsInterface?.onQualityClicked()
this.dismiss()
}
binding.playbackSpeed.setOnClickListener {
playerOptionsInterface.onPlaybackSpeedClicked()
this.dismiss()
}
binding.captions.setOnClickListener {
onlinePlayerOptionsInterface?.onCaptionClicked()
this.dismiss()
}
binding.autoplay.setOnClickListener {
playerOptionsInterface.onAutoplayClicked()
this.dismiss()
}
binding.repeatMode.setOnClickListener {
playerOptionsInterface.onRepeatModeClicked()
this.dismiss()
}
}
private fun TextView.updateText(currentValue: String?) {
if (currentValue == null) return
this.text = "${this.text} ($currentValue)"
}
}

View File

@ -18,6 +18,7 @@
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="16sp"
tools:text="Option" /> tools:text="Option" />
</LinearLayout> </LinearLayout>

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="7dp"
android:paddingVertical="10dp">
<TextView
android:id="@+id/quality"
style="@style/BottomSheetItem"
android:text="@string/quality"
app:drawableStartCompat="@drawable/ic_hd" />
<TextView
android:id="@+id/playbackSpeed"
style="@style/BottomSheetItem"
android:text="@string/playback_speed"
app:drawableStartCompat="@drawable/ic_speed" />
<TextView
android:id="@+id/captions"
style="@style/BottomSheetItem"
android:text="@string/captions"
app:drawableStartCompat="@drawable/ic_caption" />
<TextView
android:id="@+id/autoplay"
style="@style/BottomSheetItem"
android:text="@string/player_autoplay"
app:drawableStartCompat="@drawable/ic_play" />
<TextView
android:id="@+id/repeatMode"
style="@style/BottomSheetItem"
android:text="@string/repeat_mode"
app:drawableStartCompat="@drawable/ic_repeat" />
<TextView
android:id="@+id/resizeMode"
style="@style/BottomSheetItem"
android:text="@string/player_resize_mode"
app:drawableStartCompat="@drawable/ic_aspect_ratio" />
</LinearLayout>

View File

@ -151,19 +151,6 @@
</style> </style>
<style name="BottomSheetItem">
<item name="android:textSize">16sp</item>
<item name="android:drawablePadding">20dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">10dp</item>
<item name="android:layout_marginTop">2dp</item>
<item name="android:layout_marginBottom">2dp</item>
<item name="background">?attr/selectableItemBackground</item>
</style>
<style name="ItemRow"> <style name="ItemRow">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>