mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 07:50:31 +05:30
commit
0357b736a2
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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 ->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -431,6 +431,8 @@
|
||||
<string name="alternative_pip_controls">Alternative PiP controls</string>
|
||||
<string name="alternative_pip_controls_summary">Show audio only and skip controls in PiP instead of forward and rewind</string>
|
||||
<string name="audio_player">Audio player</string>
|
||||
<string name="audio_only_mode">Audio only mode</string>
|
||||
<string name="audio_only_mode_summary">Turn LibreTube into a music player.</string>
|
||||
|
||||
<!-- Notification channel strings -->
|
||||
<string name="download_channel_name">Download Service</string>
|
||||
|
@ -23,6 +23,13 @@
|
||||
|
||||
<PreferenceCategory app:title="@string/customization">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_headphones"
|
||||
android:summary="@string/audio_only_mode_summary"
|
||||
android:title="@string/audio_only_mode"
|
||||
app:key="audio_only_mode" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_screen_rotation"
|
||||
|
Loading…
x
Reference in New Issue
Block a user