Merge pull request #2651 from Bnyro/master

Option for background and skip controls in PiP
This commit is contained in:
Bnyro 2023-01-09 17:38:36 +01:00 committed by GitHub
commit 70912428dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 22 deletions

View File

@ -87,6 +87,7 @@ object PreferenceKeys {
const val CAPTIONS_SIZE = "captions_size" const val CAPTIONS_SIZE = "captions_size"
const val DOUBLE_TAP_TO_SEEK = "double_tap_seek" const val DOUBLE_TAP_TO_SEEK = "double_tap_seek"
const val PAUSE_ON_QUIT = "pause_on_quit" const val PAUSE_ON_QUIT = "pause_on_quit"
const val ALTERNATIVE_PIP_CONTROLS = "alternative_pip_controls"
/** /**
* Background mode * Background mode

View File

@ -6,7 +6,8 @@ enum class PlayerEvent(val value: Int) {
Forward(2), Forward(2),
Rewind(3), Rewind(3),
Next(5), Next(5),
Prev(6); Prev(6),
Background(7);
companion object { companion object {
fun fromInt(value: Int) = PlayerEvent.values().first { it.value == value } fun fromInt(value: Int) = PlayerEvent.values().first { it.value == value }

View File

@ -28,6 +28,7 @@ import androidx.annotation.RequiresApi
import androidx.constraintlayout.motion.widget.MotionLayout import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.os.postDelayed
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
@ -181,6 +182,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())
/**
* Receiver for all actions in the PiP mode
*/
private val broadcastReceiver = object : BroadcastReceiver() { private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
val action = intent?.getIntExtra(PlayerHelper.CONTROL_TYPE, 0) ?: return val action = intent?.getIntExtra(PlayerHelper.CONTROL_TYPE, 0) ?: return
@ -197,6 +201,16 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
PlayerEvent.Rewind -> { PlayerEvent.Rewind -> {
exoPlayer.seekTo(exoPlayer.currentPosition - PlayerHelper.seekIncrement) exoPlayer.seekTo(exoPlayer.currentPosition - PlayerHelper.seekIncrement)
} }
PlayerEvent.Next -> {
playNextVideo()
}
PlayerEvent.Background -> {
playOnBackground()
// wait some time in order for the service to get started properly
handler.postDelayed({
activity?.finish()
}, 500)
}
else -> { else -> {
} }
} }
@ -447,13 +461,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
exoPlayer.pause() exoPlayer.pause()
// start the background mode // start the background mode
BackgroundHelper.playOnBackground( playOnBackground()
requireContext(),
videoId!!,
exoPlayer.currentPosition,
playlistId,
channelId
)
} }
binding.relatedRecView.layoutManager = VideosAdapter.getLayout(requireContext()) binding.relatedRecView.layoutManager = VideosAdapter.getLayout(requireContext())
@ -465,6 +473,16 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
) )
} }
private fun playOnBackground() {
BackgroundHelper.playOnBackground(
requireContext(),
videoId!!,
exoPlayer.currentPosition,
playlistId,
channelId
)
}
private fun setFullscreen() { private fun setFullscreen() {
with(binding.playerMotionLayout) { with(binding.playerMotionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, -1) getConstraintSet(R.id.start).constrainHeight(R.id.player, -1)
@ -1497,7 +1515,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
fun getPipParams(): PictureInPictureParams = PictureInPictureParams.Builder() fun getPipParams(): PictureInPictureParams = PictureInPictureParams.Builder()
.setActions(PlayerHelper.getPIPModeActions(requireActivity(), exoPlayer.isPlaying)) .setActions(PlayerHelper.getPiPModeActions(requireActivity(), exoPlayer.isPlaying))
.apply { .apply {
if (SDK_INT >= Build.VERSION_CODES.S) { if (SDK_INT >= Build.VERSION_CODES.S) {
setAutoEnterEnabled(true) setAutoEnterEnabled(true)

View File

@ -332,6 +332,12 @@ object PlayerHelper {
false false
) )
val alternativePiPControls: Boolean
get() = PreferenceHelper.getBoolean(
PreferenceKeys.ALTERNATIVE_PIP_CONTROLS,
false
)
fun getDefaultResolution(context: Context): String { fun getDefaultResolution(context: Context): String {
return if (NetworkHelper.isNetworkMobile(context)) { return if (NetworkHelper.isNetworkMobile(context)) {
PreferenceHelper.getString( PreferenceHelper.getString(
@ -384,16 +390,28 @@ object PlayerHelper {
) )
} }
/**
* Create controls to use in the PiP window
*/
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
fun getPIPModeActions(activity: Activity, isPlaying: Boolean): ArrayList<RemoteAction> { fun getPiPModeActions(activity: Activity, isPlaying: Boolean, isOfflinePlayer: Boolean = false): ArrayList<RemoteAction> {
val actions: ArrayList<RemoteAction> = ArrayList() val actions: ArrayList<RemoteAction> = ArrayList()
actions.add( actions.add(
getRemoteAction( if (!isOfflinePlayer && alternativePiPControls) {
activity, getRemoteAction(
R.drawable.ic_rewind, activity,
R.string.rewind, R.drawable.ic_headphones,
PlayerEvent.Rewind R.string.background_mode,
) PlayerEvent.Background
)
} else {
getRemoteAction(
activity,
R.drawable.ic_rewind,
R.string.rewind,
PlayerEvent.Rewind
)
}
) )
actions.add( actions.add(
@ -406,12 +424,21 @@ object PlayerHelper {
) )
actions.add( actions.add(
getRemoteAction( if (!isOfflinePlayer && alternativePiPControls) {
activity, getRemoteAction(
R.drawable.ic_forward, activity,
R.string.forward, R.drawable.ic_next,
PlayerEvent.Forward R.string.play_next,
) PlayerEvent.Next
)
} else {
getRemoteAction(
activity,
R.drawable.ic_forward,
R.string.forward,
PlayerEvent.Forward
)
}
) )
return actions return actions
} }

View File

@ -428,6 +428,8 @@
<string name="rewind">Rewind</string> <string name="rewind">Rewind</string>
<string name="forward">Forward</string> <string name="forward">Forward</string>
<string name="pause">Pause</string> <string name="pause">Pause</string>
<string name="alternative_pip_controls">Alternative PiP controls</string>
<string name="alternative_pip_controls_summary">Show audio only and skip controls in PiP instead of forward and rewind</string>
<!-- Notification channel strings --> <!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string> <string name="download_channel_name">Download Service</string>

View File

@ -38,6 +38,13 @@
app:key="picture_in_picture" app:key="picture_in_picture"
app:title="@string/picture_in_picture" /> app:title="@string/picture_in_picture" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:icon="@drawable/ic_headphones"
app:key="alternative_pip_controls"
app:title="@string/alternative_pip_controls"
android:summary="@string/alternative_pip_controls_summary"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:icon="@drawable/ic_pause_filled" android:icon="@drawable/ic_pause_filled"