diff --git a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt
index 1c4086466..cbe237d9c 100644
--- a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt
+++ b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt
@@ -93,6 +93,7 @@ object PreferenceKeys {
* Background mode
*/
const val BACKGROUND_PLAYBACK_SPEED = "background_playback_speed"
+ const val AUDIO_ONLY_MODE = "audio_only_mode"
/**
* Notifications
diff --git a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt
index 7925076d5..7ad013a21 100644
--- a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt
+++ b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt
@@ -10,6 +10,7 @@ import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
+import android.util.Log
import android.widget.Toast
import androidx.core.app.ServiceCompat
import com.fasterxml.jackson.databind.ObjectMapper
@@ -24,6 +25,7 @@ import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHolder.Companion.Database
import com.github.libretube.db.obj.WatchPosition
+import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.awaitQuery
import com.github.libretube.extensions.query
import com.github.libretube.extensions.toID
@@ -127,7 +129,7 @@ class BackgroundMode : Service() {
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
try {
- // clear the playing queue
+ // reset the playing queue listeners
PlayingQueue.resetToDefaults()
// get the intent arguments
@@ -145,6 +147,7 @@ class BackgroundMode : Service() {
if (PlayerHelper.watchPositionsEnabled) updateWatchPosition()
} catch (e: Exception) {
+ Log.e(TAG(), e.toString())
onDestroy()
}
return super.onStartCommand(intent, flags, startId)
@@ -177,23 +180,23 @@ class BackgroundMode : Service() {
RetrofitInstance.api.getStreams(videoId)
}.getOrNull() ?: return@launch
+ // clear the queue if it shouldn't be kept explicitly
+ if (!keepQueue) PlayingQueue.clear()
+
+ if (PlayingQueue.isEmpty()) updateQueue()
+
// save the current stream to the queue
streams?.toStreamItem(videoId)?.let {
PlayingQueue.updateCurrent(it)
}
- // add the playlist video to the queue
- if (PlayingQueue.isEmpty() && !keepQueue) updateQueue()
-
handler.post {
playAudio(seekToPosition)
}
}
}
- private fun playAudio(
- seekToPosition: Long
- ) {
+ private fun playAudio(seekToPosition: Long) {
initializePlayer()
setMediaItem()
diff --git a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt
index 069a51f36..93ef77c57 100644
--- a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt
+++ b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt
@@ -41,6 +41,7 @@ import com.github.libretube.ui.models.SearchViewModel
import com.github.libretube.ui.models.SubscriptionsViewModel
import com.github.libretube.ui.tools.BreakReminder
import com.github.libretube.util.NavBarHelper
+import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.NetworkHelper
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.ThemeHelper
@@ -58,6 +59,8 @@ class MainActivity : BaseActivity() {
lateinit var searchView: SearchView
private lateinit var searchItem: MenuItem
+ private val handler = Handler(Looper.getMainLooper())
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -381,7 +384,7 @@ class MainActivity : BaseActivity() {
}
if (intent?.getBooleanExtra(IntentData.openAudioPlayer, false) == true) {
- navController.navigate(R.id.audioPlayerFragment)
+ NavigationHelper.startAudioPlayer(this)
return
}
@@ -404,7 +407,11 @@ class MainActivity : BaseActivity() {
)
}
intent?.getStringExtra(IntentData.videoId)?.let {
- loadVideo(it, intent?.getLongExtra(IntentData.timeStamp, 0L))
+ NavigationHelper.navigateVideo(
+ context = this,
+ videoId = it,
+ timeStamp = intent?.getLongExtra(IntentData.timeStamp, 0L)
+ )
}
when (intent?.getStringExtra("fragmentToOpen")) {
@@ -419,32 +426,6 @@ class MainActivity : BaseActivity() {
}
}
- private fun loadVideo(videoId: String, timeStamp: Long?) {
- val bundle = Bundle()
-
- bundle.putString(IntentData.videoId, videoId)
- if (timeStamp != null) bundle.putLong(IntentData.timeStamp, timeStamp)
-
- val frag = PlayerFragment()
- frag.arguments = bundle
-
- supportFragmentManager.beginTransaction()
- .remove(PlayerFragment())
- .commit()
- supportFragmentManager.beginTransaction()
- .replace(R.id.container, frag)
- .commitNow()
- Handler(Looper.getMainLooper()).postDelayed({
- supportFragmentManager.fragments.forEach { fragment ->
- (fragment as? PlayerFragment)
- ?.binding?.playerMotionLayout?.apply {
- transitionToEnd()
- transitionToStart()
- }
- }
- }, 300)
- }
-
private fun minimizePlayer() {
binding.mainMotionLayout.transitionToEnd()
supportFragmentManager.fragments.forEach { fragment ->
diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt
index ce3a94c3a..fe73fc124 100644
--- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt
+++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt
@@ -86,6 +86,7 @@ import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.DashHelper
import com.github.libretube.util.DataSaverMode
import com.github.libretube.util.ImageHelper
+import com.github.libretube.util.NavigationHelper
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.PlayerHelper
import com.github.libretube.util.PlayingQueue
@@ -349,7 +350,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
BackgroundHelper.stopBackgroundPlay(requireContext())
}
playerBinding.closeImageButton.setOnClickListener {
- killFragment()
+ killPlayerFragment()
}
playerBinding.autoPlay.visibility = View.VISIBLE
@@ -476,8 +477,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
true
)
handler.postDelayed({
- (activity as MainActivity).navController.navigate(R.id.audioPlayerFragment)
- killFragment()
+ NavigationHelper.startAudioPlayer(requireContext())
+ killPlayerFragment()
}, 500)
}
@@ -1530,7 +1531,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
return exoPlayer.isPlaying && !backgroundModeRunning
}
- private fun killFragment() {
+ private fun killPlayerFragment() {
viewModel.isFullscreen.value = false
binding.playerMotionLayout.transitionToEnd()
val mainActivity = activity as MainActivity
diff --git a/app/src/main/java/com/github/libretube/util/NavigationHelper.kt b/app/src/main/java/com/github/libretube/util/NavigationHelper.kt
index 6d55680ea..d4742b92c 100644
--- a/app/src/main/java/com/github/libretube/util/NavigationHelper.kt
+++ b/app/src/main/java/com/github/libretube/util/NavigationHelper.kt
@@ -6,10 +6,13 @@ import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import com.github.libretube.R
import com.github.libretube.constants.IntentData
+import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.toID
import com.github.libretube.ui.activities.MainActivity
@@ -17,6 +20,8 @@ import com.github.libretube.ui.fragments.PlayerFragment
import com.github.libretube.ui.views.SingleViewTouchableMotionLayout
object NavigationHelper {
+ private val handler = Handler(Looper.getMainLooper())
+
fun navigateChannel(
context: Context,
channelId: String?
@@ -45,20 +50,35 @@ object NavigationHelper {
return correctContext as MainActivity
}
+ /**
+ * Navigate to the given video using the other provided parameters as well
+ * If the audio only mode is enabled, play it in the background, else as a normal video
+ */
fun navigateVideo(
context: Context,
videoId: String?,
playlistId: String? = null,
channelId: String? = null,
- keepQueue: Boolean = false
+ keepQueue: Boolean = false,
+ timeStamp: Long? = null
) {
if (videoId == null) return
+ if (PreferenceHelper.getBoolean(PreferenceKeys.AUDIO_ONLY_MODE, false)) {
+ BackgroundHelper.stopBackgroundPlay(context)
+ BackgroundHelper.playOnBackground(context, videoId.toID(), timeStamp, playlistId, channelId, keepQueue)
+ handler.postDelayed({
+ startAudioPlayer(context)
+ }, 500)
+ return
+ }
+
val bundle = Bundle().apply {
putString(IntentData.videoId, videoId.toID())
putString(IntentData.playlistId, playlistId)
putString(IntentData.channelId, channelId)
putBoolean(IntentData.keepQueue, keepQueue)
+ timeStamp?.let { putLong(IntentData.timeStamp, it) }
}
val activity = context as AppCompatActivity
@@ -89,6 +109,14 @@ object NavigationHelper {
activity.navController.navigate(R.id.playlistFragment, bundle)
}
+ /**
+ * Start the audio player fragment
+ */
+ fun startAudioPlayer(context: Context) {
+ val activity = unwrap(context)
+ activity.navController.navigate(R.id.audioPlayerFragment)
+ }
+
/**
* Needed due to different MainActivity Aliases because of the app icons
*/
diff --git a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt
index 174891393..995f45bfd 100644
--- a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt
+++ b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt
@@ -25,6 +25,8 @@ object PlayingQueue {
private val onTrackChangedListeners: MutableList<(StreamItem) -> Unit> = mutableListOf()
var repeatQueue: Boolean = false
+ fun clear() = queue.clear()
+
fun add(vararg streamItem: StreamItem) {
streamItem.forEach {
if (currentStream != it) {
@@ -72,7 +74,7 @@ object PlayingQueue {
it.invoke(streamItem)
}
}
- if (!contains(streamItem)) queue.add(streamItem)
+ if (!contains(streamItem)) queue.add(0, streamItem)
}
fun isNotEmpty() = queue.isNotEmpty()
@@ -190,6 +192,5 @@ object PlayingQueue {
repeatQueue = false
onQueueTapListener = {}
onTrackChangedListeners.clear()
- queue.clear()
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7da95f877..9c8c18b4e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -431,6 +431,8 @@
Alternative PiP controls
Show audio only and skip controls in PiP instead of forward and rewind
Audio player
+ Audio only mode
+ Turn LibreTube into a music player.
Download Service
diff --git a/app/src/main/res/xml/general_settings.xml b/app/src/main/res/xml/general_settings.xml
index 423f831c8..67b585be7 100644
--- a/app/src/main/res/xml/general_settings.xml
+++ b/app/src/main/res/xml/general_settings.xml
@@ -23,6 +23,13 @@
+
+