Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pip controls for offline player #5923

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/src/main/java/com/github/libretube/enums/PlayerEvent.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.github.libretube.enums

enum class PlayerEvent {
Pause,
Play,
PlayPause,
Forward,
Rewind,
Next,
Expand Down
28 changes: 11 additions & 17 deletions app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.github.libretube.helpers

import android.app.Activity
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
Expand Down Expand Up @@ -397,30 +396,25 @@
}
}

fun getIntentAction(context: Context): String {
fun getIntentActionName(context: Context): String {
return context.packageName + "." + ACTION_MEDIA_CONTROL
}

private fun getPendingIntent(activity: Activity, event: PlayerEvent): PendingIntent {
val intent = Intent(getIntentAction(activity))
.setPackage(activity.packageName)
.putExtra(CONTROL_TYPE, event)
return PendingIntentCompat.getBroadcast(activity, event.ordinal, intent, 0, false)!!
}

private fun getRemoteAction(
activity: Activity,
id: Int,
@StringRes title: Int,
event: PlayerEvent
): RemoteActionCompat {
val intent = Intent(getIntentActionName(activity))

Check failure on line 409 in app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt:409:22: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
.setPackage(activity.packageName)
.putExtra(CONTROL_TYPE, event)
val pendingIntent = PendingIntentCompat.getBroadcast(activity, event.ordinal, intent, 0, false)!!

val text = activity.getString(title)
return RemoteActionCompat(
IconCompat.createWithResource(activity, id),
text,
text,
getPendingIntent(activity, event)
)
val icon = IconCompat.createWithResource(activity, id)

return RemoteActionCompat(icon, text, text, pendingIntent)
}

/**
Expand All @@ -444,8 +438,8 @@
val playPauseAction = getRemoteAction(
activity,
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play,
R.string.pause,
if (isPlaying) PlayerEvent.Pause else PlayerEvent.Play
if (isPlaying) R.string.resume else R.string.pause,
PlayerEvent.PlayPause

Check failure on line 442 in app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt:442:34: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)

val skipNextAction = getRemoteAction(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.github.libretube.ui.activities

import android.content.BroadcastReceiver

Check failure on line 3 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Imports must be ordered in lexicographic order without any empty lines in-between with "java", "javax", "kotlin" and aliases in the end Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:3:1: error: Imports must be ordered in lexicographic order without any empty lines in-between with "java", "javax", "kotlin" and aliases in the end (standard:import-ordering)
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ActivityInfo
import android.media.session.PlaybackState
import android.content.res.Configuration
import android.net.Uri
import android.os.Bundle
import android.text.format.DateUtils
import android.view.KeyEvent
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
Expand All @@ -30,7 +35,11 @@
import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.db.obj.DownloadChapter
import com.github.libretube.enums.FileType
import com.github.libretube.enums.PlayerEvent
import com.github.libretube.extensions.seekBy
import com.github.libretube.extensions.serializableExtra
import com.github.libretube.extensions.toAndroidUri
import com.github.libretube.extensions.togglePlayPauseState
import com.github.libretube.extensions.updateParameters
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.WindowHelper
Expand Down Expand Up @@ -74,6 +83,10 @@
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)

if (PlayerHelper.pipEnabled) {
PictureInPictureCompat.setPictureInPictureParams(this@OfflinePlayerActivity, pipParams)
}

// Start or pause watch position timer
if (isPlaying) {
watchPositionTimer.resume()
Expand All @@ -97,6 +110,32 @@
}
}

private val playerActionReceiver = object : BroadcastReceiver() {

Check failure on line 113 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:113:40: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
override fun onReceive(context: Context, intent: Intent) {

Check failure on line 114 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Newline expected after opening parenthesis Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:114:32: error: Newline expected after opening parenthesis (standard:function-signature)

Check failure on line 114 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Parameter should start on a newline Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:114:50: error: Parameter should start on a newline (standard:function-signature)

Check failure on line 114 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Newline expected before closing parenthesis Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:114:64: error: Newline expected before closing parenthesis (standard:function-signature)
when (intent.serializableExtra<PlayerEvent>(PlayerHelper.CONTROL_TYPE) ?: return) {
PlayerEvent.PlayPause -> {
player.togglePlayPauseState()
}

PlayerEvent.Forward -> {
player.seekBy(PlayerHelper.seekIncrement)
}

PlayerEvent.Rewind -> {
player.seekBy(-PlayerHelper.seekIncrement)
}

else -> Unit
}
}
}

private val pipParams get() = PictureInPictureParamsCompat.Builder()

Check failure on line 133 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:133:35: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
.setActions(PlayerHelper.getPiPModeActions(this, player.isPlaying))
.setAutoEnterEnabled(PlayerHelper.pipEnabled && player.isPlaying)
.setAspectRatio(player.videoSize)
.build()

override fun onCreate(savedInstanceState: Bundle?) {
WindowHelper.toggleFullscreen(window, true)

Expand All @@ -116,6 +155,17 @@
player.videoSize.width,
player.videoSize.height
)

ContextCompat.registerReceiver(
this,
playerActionReceiver,
IntentFilter(PlayerHelper.getIntentActionName(this)),
ContextCompat.RECEIVER_NOT_EXPORTED

Check failure on line 163 in app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt:163:48: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)

if (PlayerHelper.pipEnabled) {
PictureInPictureCompat.setPictureInPictureParams(this, pipParams)
}
}

private fun initializePlayer() {
Expand Down Expand Up @@ -248,6 +298,10 @@
override fun onPause() {
playerViewModel.isFullscreen.value = false
super.onPause()

if (PlayerHelper.pauseOnQuit) {
player.pause()
}
}

override fun onDestroy() {
Expand All @@ -257,22 +311,30 @@
player.release()
watchPositionTimer.destroy()

unregisterReceiver(playerActionReceiver)

super.onDestroy()
}

override fun onUserLeaveHint() {
if (PlayerHelper.pipEnabled && player.playbackState != PlaybackState.STATE_PAUSED) {
PictureInPictureCompat.enterPictureInPictureMode(
this,
PictureInPictureParamsCompat.Builder()
.setAspectRatio(player.videoSize)
.build()
)
if (PlayerHelper.pipEnabled && player.isPlaying) {
PictureInPictureCompat.enterPictureInPictureMode(this, pipParams)
}

super.onUserLeaveHint()
}

override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, configuration: Configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode)

if (isInPictureInPictureMode) {
playerView.hideController()
playerView.useController = false
} else {
playerView.useController = true
}
}

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
if (binding.player.onKeyBoardAction(keyCode)) {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
/**
* Receiver for all actions in the PiP mode
*/
private val broadcastReceiver = object : BroadcastReceiver() {
private val playerActionReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.serializableExtra<PlayerEvent>(PlayerHelper.CONTROL_TYPE) ?: return) {
PlayerEvent.Play -> {
exoPlayer.play()
}

PlayerEvent.Pause -> {
exoPlayer.pause()
PlayerEvent.PlayPause -> {
exoPlayer.togglePlayPauseState()
}

PlayerEvent.Forward -> {
Expand Down Expand Up @@ -370,8 +366,8 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
// broadcast receiver for PiP actions
ContextCompat.registerReceiver(
requireContext(),
broadcastReceiver,
IntentFilter(PlayerHelper.getIntentAction(requireContext())),
playerActionReceiver,
IntentFilter(PlayerHelper.getIntentActionName(requireContext())),
ContextCompat.RECEIVER_NOT_EXPORTED
)

Expand Down Expand Up @@ -833,7 +829,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {

runCatching {
// unregister the receiver for player actions
context?.unregisterReceiver(broadcastReceiver)
context?.unregisterReceiver(playerActionReceiver)
}

_binding = null
Expand Down
Loading