fix: properly open current video from media notification

This commit is contained in:
Bnyro 2025-04-01 09:55:32 +02:00
parent a0a6694017
commit dd84281bf9
No known key found for this signature in database
5 changed files with 39 additions and 22 deletions

View File

@ -41,6 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@UnstableApi
abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySession.Callback {
@ -116,7 +117,9 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
START_SERVICE_ACTION -> {
CoroutineScope(Dispatchers.IO).launch {
onServiceCreated(args)
notificationProvider?.intentActivity = getIntentActivity()
withContext(Dispatchers.Main) {
updateNotification()
}
if (::videoId.isInitialized) startPlayback()
}
@ -185,6 +188,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
trackSelector?.updateParameters {
setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, isAudioOnlyPlayer)
}
updateNotification()
}
}
}
@ -239,9 +243,24 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
}
}
/**
* Trigger a notification update with an updated PendingIntent.
*/
private fun updateNotification() {
val notificationIntent = Intent(this, getIntentActivity()).apply {
putExtra(IntentData.maximizePlayer, true)
putExtra(IntentData.offlinePlayer, isOfflinePlayer)
putExtra(IntentData.audioOnly, isAudioOnlyPlayer)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
notificationProvider?.notificationIntent = notificationIntent
mediaLibrarySession?.let {
onUpdateNotification(it, true)
}
}
abstract val isOfflinePlayer: Boolean
abstract var isAudioOnlyPlayer: Boolean
open val maximizePlayer: Boolean = true
var isAudioOnlyPlayer: Boolean = false
val watchPositionsEnabled get() =
(PlayerHelper.watchPositionsAudio && isAudioOnlyPlayer) || (PlayerHelper.watchPositionsVideo && !isAudioOnlyPlayer)
@ -252,10 +271,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
override fun onCreate() {
super.onCreate()
notificationProvider = NowPlayingNotification(
this,
offlinePlayer = isOfflinePlayer,
)
notificationProvider = NowPlayingNotification(this)
setMediaNotificationProvider(notificationProvider!!)
createPlayerAndMediaSession()

View File

@ -26,6 +26,7 @@ import com.github.libretube.extensions.updateParameters
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.ui.activities.MainActivity
import com.github.libretube.ui.activities.NoInternetActivity
import com.github.libretube.ui.activities.OfflinePlayerActivity
import com.github.libretube.ui.fragments.DownloadTab
import com.github.libretube.util.PlayingQueue
import kotlinx.coroutines.CoroutineScope
@ -41,7 +42,6 @@ import kotlin.io.path.exists
@OptIn(UnstableApi::class)
open class OfflinePlayerService : AbstractPlayerService() {
override val isOfflinePlayer: Boolean = true
override var isAudioOnlyPlayer: Boolean = true
private var noInternetService: Boolean = false
private var downloadWithItems: DownloadWithItems? = null
@ -94,7 +94,11 @@ open class OfflinePlayerService : AbstractPlayerService() {
}
override fun getIntentActivity(): Class<*> {
return if (noInternetService) NoInternetActivity::class.java else MainActivity::class.java
return when {
!noInternetService && isAudioOnlyPlayer -> MainActivity::class.java
noInternetService && isAudioOnlyPlayer -> NoInternetActivity::class.java
else -> OfflinePlayerActivity::class.java
}
}
/**

View File

@ -48,7 +48,6 @@ import java.io.IOException
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
open class OnlinePlayerService : AbstractPlayerService() {
override val isOfflinePlayer: Boolean = false
override var isAudioOnlyPlayer: Boolean = false
// PlaylistId/ChannelId for autoplay
private var playlistId: String? = null

View File

@ -434,9 +434,13 @@ class MainActivity : BaseActivity() {
}
if (intent?.getBooleanExtra(IntentData.maximizePlayer, false) == true) {
// attempt to open the current player fragment first before creating a new one
// TODO: handle this differently
if (runOnPlayerFragment { binding.playerMotionLayout.transitionToStart(); true }) return
// attempt to open the current video player fragment
if (intent?.getBooleanExtra(IntentData.audioOnly, false) == false) {
runOnPlayerFragment { binding.playerMotionLayout.transitionToStart(); true }
return
}
// if it's an audio only session, attempt to maximize the audio player or create a new one
if (runOnAudioPlayerFragment { binding.playerMotionLayout.transitionToStart(); true }) return
val offlinePlayer = intent!!.getBooleanExtra(IntentData.offlinePlayer, false)

View File

@ -21,10 +21,8 @@ import com.google.common.collect.ImmutableList
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
class NowPlayingNotification(
private val context: Context,
private val offlinePlayer: Boolean = false
var notificationIntent: Intent = Intent(),
): MediaNotification.Provider {
var intentActivity: Class<*> = MainActivity::class.java
private val nProvider = DefaultMediaNotificationProvider.Builder(context)
.setNotificationId(NotificationId.PLAYER_PLAYBACK.id)
.setChannelId(PLAYER_CHANNEL_NAME)
@ -36,14 +34,10 @@ class NowPlayingNotification(
// it doesn't start a completely new MainActivity because the MainActivity's launchMode
// is set to "singleTop" in the AndroidManifest (important!!!)
// that's the only way to launch back into the previous activity (e.g. the player view)
val intent = Intent(context, intentActivity).apply {
putExtra(IntentData.maximizePlayer, true)
putExtra(IntentData.offlinePlayer, offlinePlayer)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
return PendingIntentCompat
.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, false)
.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT, false)
}
/**