mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 16:00:31 +05:30
PiP: Forward and Rewind actions
This commit is contained in:
parent
99182b34af
commit
07dc1a80b8
14
app/src/main/java/com/github/libretube/enums/PlayerEvent.kt
Normal file
14
app/src/main/java/com/github/libretube/enums/PlayerEvent.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package com.github.libretube.enums
|
||||
|
||||
enum class PlayerEvent(val value: Int) {
|
||||
Pause(0),
|
||||
Play(1),
|
||||
Forward(2),
|
||||
Rewind(3),
|
||||
Next(5),
|
||||
Prev(6);
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int) = PlayerEvent.values().first { it.value == value }
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@ package com.github.libretube.ui.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.PictureInPictureParams
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.media.session.PlaybackState
|
||||
@ -50,6 +52,7 @@ import com.github.libretube.databinding.PlayerGestureControlsViewBinding
|
||||
import com.github.libretube.db.DatabaseHelper
|
||||
import com.github.libretube.db.DatabaseHolder.Companion.Database
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.enums.PlayerEvent
|
||||
import com.github.libretube.enums.ShareObjectType
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
@ -107,15 +110,15 @@ import com.google.android.exoplayer2.ui.StyledPlayerView
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSource
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.abs
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.chromium.net.CronetEngine
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.abs
|
||||
|
||||
class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
|
||||
@ -178,6 +181,28 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
private val broadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val action = intent?.getIntExtra(PlayerHelper.CONTROL_TYPE, 0) ?: return
|
||||
when (PlayerEvent.fromInt(action)) {
|
||||
PlayerEvent.Play -> {
|
||||
exoPlayer.play()
|
||||
}
|
||||
PlayerEvent.Pause -> {
|
||||
exoPlayer.pause()
|
||||
}
|
||||
PlayerEvent.Forward -> {
|
||||
exoPlayer.seekTo(exoPlayer.currentPosition + PlayerHelper.seekIncrement)
|
||||
}
|
||||
PlayerEvent.Rewind -> {
|
||||
exoPlayer.seekTo(exoPlayer.currentPosition - PlayerHelper.seekIncrement)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
@ -186,6 +211,12 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
channelId = it.getString(IntentData.channelId)
|
||||
keepQueue = it.getBoolean(IntentData.keepQueue, false)
|
||||
}
|
||||
|
||||
// broadcast receiver for PiP actions
|
||||
context?.registerReceiver(
|
||||
broadcastReceiver,
|
||||
IntentFilter(PlayerHelper.getIntentActon(requireContext()))
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
@ -529,6 +560,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
// disable the auto PiP mode for SDK >= 32
|
||||
disableAutoPiP()
|
||||
|
||||
// unregister the receiver for player actions
|
||||
context?.unregisterReceiver(broadcastReceiver)
|
||||
|
||||
saveWatchPosition()
|
||||
|
||||
// clear the playing queue and release the player
|
||||
@ -794,7 +828,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
private fun localizedDate(date: String?): String? {
|
||||
return if (SDK_INT >= Build.VERSION_CODES.N) {
|
||||
TextUtils.localizeDate(date, resources.configuration.locales[0])
|
||||
} else TextUtils.localizeDate(date)
|
||||
} else {
|
||||
TextUtils.localizeDate(date)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLiveVideo() {
|
||||
@ -855,10 +891,11 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
// Listener for play and pause icon change
|
||||
exoPlayer.addListener(object : Player.Listener {
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
if (usePiP()) activity?.setPictureInPictureParams(getPipParams())
|
||||
|
||||
if (isPlaying) {
|
||||
// Stop [BackgroundMode] service if it is running.
|
||||
BackgroundHelper.stopBackgroundPlay(requireContext())
|
||||
if (usePiP()) activity?.setPictureInPictureParams(getPipParams())
|
||||
} else {
|
||||
disableAutoPiP()
|
||||
}
|
||||
@ -1169,8 +1206,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
|
||||
for (vid in videoStreams) {
|
||||
if (resolutions.any {
|
||||
it.resolution == vid.quality.qualityToInt()
|
||||
} || vid.url == null
|
||||
it.resolution == vid.quality.qualityToInt()
|
||||
} || vid.url == null
|
||||
) {
|
||||
continue
|
||||
}
|
||||
@ -1460,7 +1497,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getPipParams(): PictureInPictureParams = PictureInPictureParams.Builder()
|
||||
.setActions(emptyList())
|
||||
.setActions(PlayerHelper.getPIPModeActions(requireActivity(), exoPlayer.isPlaying))
|
||||
.apply {
|
||||
if (SDK_INT >= Build.VERSION_CODES.S) {
|
||||
setAutoEnterEnabled(true)
|
||||
|
@ -1,16 +1,29 @@
|
||||
package com.github.libretube.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.RemoteAction
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.view.accessibility.CaptioningManager
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.obj.PipedStream
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.enums.AudioQuality
|
||||
import com.github.libretube.enums.PlayerEvent
|
||||
import com.google.android.exoplayer2.ui.CaptionStyleCompat
|
||||
import com.google.android.exoplayer2.video.VideoSize
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object PlayerHelper {
|
||||
private const val ACTION_MEDIA_CONTROL = "media_control"
|
||||
const val CONTROL_TYPE = "control_type"
|
||||
|
||||
/**
|
||||
* Get the audio source following the users preferences
|
||||
*/
|
||||
@ -43,7 +56,7 @@ object PlayerHelper {
|
||||
/**
|
||||
* Get the best or worst bitrate from a list of audio streams
|
||||
* @param audios list of the audio streams
|
||||
* @param getLeast whether the least bitrate should be returned
|
||||
* @param quality Whether to use the best or worst quality available
|
||||
* @return Url of the audio source
|
||||
*/
|
||||
private fun getBitRate(audios: List<PipedStream>, quality: AudioQuality): String {
|
||||
@ -332,4 +345,74 @@ object PlayerHelper {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getIntentActon(context: Context): String {
|
||||
return context.packageName + "." + ACTION_MEDIA_CONTROL
|
||||
}
|
||||
|
||||
private fun getPendingIntent(activity: Activity, code: Int): PendingIntent {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent(getIntentActon(activity)).putExtra(CONTROL_TYPE, code),
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
} else {
|
||||
PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent(getIntentActon(activity)).putExtra(CONTROL_TYPE, code),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun getRemoteAction(
|
||||
activity: Activity,
|
||||
id: Int,
|
||||
@StringRes title: Int,
|
||||
event: PlayerEvent
|
||||
): RemoteAction {
|
||||
val text = activity.getString(title)
|
||||
return RemoteAction(
|
||||
Icon.createWithResource(activity, id),
|
||||
text,
|
||||
text,
|
||||
getPendingIntent(activity, event.value)
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getPIPModeActions(activity: Activity, isPlaying: Boolean): ArrayList<RemoteAction> {
|
||||
val actions: ArrayList<RemoteAction> = ArrayList()
|
||||
actions.add(
|
||||
getRemoteAction(
|
||||
activity,
|
||||
R.drawable.ic_rewind,
|
||||
R.string.rewind,
|
||||
PlayerEvent.Rewind
|
||||
)
|
||||
)
|
||||
|
||||
actions.add(
|
||||
getRemoteAction(
|
||||
activity,
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play,
|
||||
R.string.pause,
|
||||
if (isPlaying) PlayerEvent.Pause else PlayerEvent.Play
|
||||
)
|
||||
)
|
||||
|
||||
actions.add(
|
||||
getRemoteAction(
|
||||
activity,
|
||||
R.drawable.ic_forward,
|
||||
R.string.forward,
|
||||
PlayerEvent.Forward
|
||||
)
|
||||
)
|
||||
return actions
|
||||
}
|
||||
}
|
||||
|
@ -425,6 +425,9 @@
|
||||
<string name="shuffle">Shuffle</string>
|
||||
<string name="add_to_bookmarks">Add to bookmarks</string>
|
||||
<string name="remove_bookmark">Remove bookmark</string>
|
||||
<string name="rewind">Rewind</string>
|
||||
<string name="forward">Forward</string>
|
||||
<string name="pause">Pause</string>
|
||||
|
||||
<!-- Notification channel strings -->
|
||||
<string name="download_channel_name">Download Service</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user