11package com.github.libretube.helpers
22
3+ import android.annotation.SuppressLint
34import android.app.NotificationManager
45import android.content.Context
56import android.content.Intent
6- import android.os.Handler
7- import android.os.Looper
87import android.os.Process
9- import androidx.annotation.OptIn
108import androidx.core.content.getSystemService
119import androidx.core.os.bundleOf
12- import androidx.core.os.postDelayed
1310import androidx.fragment.app.commitNow
1411import androidx.fragment.app.replace
15- import androidx.media3.common.util.UnstableApi
1612import com.github.libretube.NavDirections
1713import com.github.libretube.R
1814import com.github.libretube.constants.IntentData
@@ -29,8 +25,6 @@ import com.github.libretube.ui.views.SingleViewTouchableMotionLayout
2925import com.github.libretube.util.PlayingQueue
3026
3127object NavigationHelper {
32- private val handler = Handler (Looper .getMainLooper())
33-
3428 fun navigateChannel (context : Context , channelUrlOrId : String? ) {
3529 if (channelUrlOrId == null ) return
3630
@@ -52,6 +46,7 @@ object NavigationHelper {
5246 * Navigate to the given video using the other provided parameters as well
5347 * If the audio only mode is enabled, play it in the background, else as a normal video
5448 */
49+ @SuppressLint(" UnsafeOptInUsageError" )
5550 fun navigateVideo (
5651 context : Context ,
5752 videoUrlOrId : String? ,
@@ -60,22 +55,27 @@ object NavigationHelper {
6055 keepQueue : Boolean = false,
6156 timestamp : Long = 0,
6257 alreadyStarted : Boolean = false,
63- forceVideo : Boolean = false
58+ forceVideo : Boolean = false,
59+ audioOnlyPlayerRequested : Boolean = false,
6460 ) {
6561 if (videoUrlOrId == null ) return
6662
67- if (PreferenceHelper .getBoolean(PreferenceKeys .AUDIO_ONLY_MODE , false ) && ! forceVideo) {
68- navigateAudio(context, videoUrlOrId.toID(), playlistId, channelId, keepQueue, timestamp)
69- return
70- }
71-
63+ // attempt to attach to the current media session first by using the corresponding
64+ // video/audio player instance
7265 val activity = ContextHelper .unwrapActivity<MainActivity >(context)
7366 val attachedToRunningPlayer = activity.runOnPlayerFragment {
7467 try {
7568 this .playNextVideo(videoUrlOrId.toID())
76- // maximize player
77- this .binding.playerMotionLayout.transitionToStart()
7869 PlayingQueue .clear()
70+
71+ if (audioOnlyPlayerRequested) {
72+ // switch to audio only player
73+ this .switchToAudioMode()
74+ } else {
75+ // maximize player
76+ this .binding.playerMotionLayout.transitionToStart()
77+ }
78+
7979 true
8080 } catch (e: Exception ) {
8181 this .onDestroy()
@@ -84,45 +84,46 @@ object NavigationHelper {
8484 }
8585 if (attachedToRunningPlayer) return
8686
87- val playerData =
88- PlayerData (videoUrlOrId.toID(), playlistId, channelId, keepQueue, timestamp)
89- val bundle = bundleOf(
90- IntentData .playerData to playerData,
91- IntentData .alreadyStarted to alreadyStarted
92- )
93- activity.supportFragmentManager.commitNow {
94- replace<PlayerFragment >(R .id.container, args = bundle)
95- }
96- }
87+ val attachedToRunningAudioPlayer = activity.runOnAudioPlayerFragment {
88+ this .playNextVideo(videoUrlOrId.toID())
89+ PlayingQueue .clear()
90+
91+ if (! audioOnlyPlayerRequested) {
92+ // switch to video only player
93+ this .switchToVideoMode()
94+ } else {
95+ // maximize player
96+ this .binding.playerMotionLayout.transitionToStart()
97+ }
9798
98- @OptIn(UnstableApi ::class )
99- fun navigateAudio (
100- context : Context ,
101- videoId : String ,
102- playlistId : String? = null,
103- channelId : String? = null,
104- keepQueue : Boolean = false,
105- timestamp : Long = 0,
106- minimizeByDefault : Boolean = false
107- ) {
108- val activity = ContextHelper .unwrapActivity<MainActivity >(context)
109- val attachedToRunningPlayer = activity.runOnAudioPlayerFragment {
110- this .playNextVideo(videoId)
11199 true
112100 }
113- if (attachedToRunningPlayer) return
114-
115- BackgroundHelper .playOnBackground(
116- context,
117- videoId,
118- timestamp,
119- playlistId,
120- channelId,
121- keepQueue
122- )
101+ if (attachedToRunningAudioPlayer) return
102+
103+ val audioOnlyMode = PreferenceHelper .getBoolean(PreferenceKeys .AUDIO_ONLY_MODE , false )
104+ if (audioOnlyPlayerRequested || (audioOnlyMode && ! forceVideo)) {
105+ // in contrast to the video player, the audio player doesn't start a media service on
106+ // its own!
107+ BackgroundHelper .playOnBackground(
108+ context,
109+ videoUrlOrId.toID(),
110+ timestamp,
111+ playlistId,
112+ channelId,
113+ keepQueue
114+ )
123115
124- handler.postDelayed(500 ) {
125- openAudioPlayerFragment(context, minimizeByDefault = minimizeByDefault)
116+ openAudioPlayerFragment(context, minimizeByDefault = true )
117+ } else {
118+ openVideoPlayerFragment(
119+ context,
120+ videoUrlOrId.toID(),
121+ playlistId,
122+ channelId,
123+ keepQueue,
124+ timestamp,
125+ alreadyStarted
126+ )
126127 }
127128 }
128129
@@ -153,6 +154,31 @@ object NavigationHelper {
153154 }
154155 }
155156
157+ /* *
158+ * Starts the video player fragment for an already existing med
159+ */
160+ fun openVideoPlayerFragment (
161+ context : Context ,
162+ videoId : String ,
163+ playlistId : String? = null,
164+ channelId : String? = null,
165+ keepQueue : Boolean = false,
166+ timestamp : Long = 0,
167+ alreadyStarted : Boolean = false
168+ ) {
169+ val activity = ContextHelper .unwrapActivity<BaseActivity >(context)
170+
171+ val playerData =
172+ PlayerData (videoId, playlistId, channelId, keepQueue, timestamp)
173+ val bundle = bundleOf(
174+ IntentData .playerData to playerData,
175+ IntentData .alreadyStarted to alreadyStarted
176+ )
177+ activity.supportFragmentManager.commitNow {
178+ replace<PlayerFragment >(R .id.container, args = bundle)
179+ }
180+ }
181+
156182 /* *
157183 * Open a large, zoomable image preview
158184 */
0 commit comments