mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
Add PlayerData class.
This commit is contained in:
parent
829ec7eb57
commit
5bb4f303b0
@ -2,14 +2,12 @@ package com.github.libretube.constants
|
||||
|
||||
object IntentData {
|
||||
const val downloadData = "downloadData"
|
||||
const val playerData = "playerData"
|
||||
const val videoId = "videoId"
|
||||
const val channelId = "channelId"
|
||||
const val channelName = "channelName"
|
||||
const val playlistId = "playlistId"
|
||||
const val timeStamp = "timeStamp"
|
||||
const val position = "position"
|
||||
const val fileName = "fileName"
|
||||
const val keepQueue = "keepQueue"
|
||||
const val playlistType = "playlistType"
|
||||
const val downloading = "downloading"
|
||||
const val openAudioPlayer = "openAudioPlayer"
|
||||
|
@ -0,0 +1,9 @@
|
||||
package com.github.libretube.extensions
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import androidx.core.os.BundleCompat
|
||||
|
||||
inline fun <reified T : Parcelable> Bundle.parcelable(key: String?): T? {
|
||||
return BundleCompat.getParcelable(this, key, T::class.java)
|
||||
}
|
@ -7,8 +7,8 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.fragment.app.commit
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.parcelable.PlayerData
|
||||
import com.github.libretube.services.OnlinePlayerService
|
||||
import com.github.libretube.ui.activities.MainActivity
|
||||
import com.github.libretube.ui.fragments.PlayerFragment
|
||||
|
||||
/**
|
||||
@ -23,10 +23,10 @@ object BackgroundHelper {
|
||||
fun playOnBackground(
|
||||
context: Context,
|
||||
videoId: String,
|
||||
position: Long? = null,
|
||||
position: Long = 0,
|
||||
playlistId: String? = null,
|
||||
channelId: String? = null,
|
||||
keepQueue: Boolean? = null,
|
||||
keepQueue: Boolean = false,
|
||||
keepVideoPlayerAlive: Boolean = false,
|
||||
) {
|
||||
// close the previous video player if open
|
||||
@ -38,12 +38,9 @@ object BackgroundHelper {
|
||||
}
|
||||
|
||||
// create an intent for the background mode service
|
||||
val playerData = PlayerData(videoId, playlistId, channelId, keepQueue, position)
|
||||
val intent = Intent(context, OnlinePlayerService::class.java)
|
||||
.putExtra(IntentData.videoId, videoId)
|
||||
.putExtra(IntentData.playlistId, playlistId)
|
||||
.putExtra(IntentData.channelId, channelId)
|
||||
.putExtra(IntentData.position, position)
|
||||
.putExtra(IntentData.keepQueue, keepQueue)
|
||||
.putExtra(IntentData.playerData, playerData)
|
||||
|
||||
// start the background mode as foreground service
|
||||
ContextCompat.startForegroundService(context, intent)
|
||||
|
@ -16,6 +16,7 @@ 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.parcelable.PlayerData
|
||||
import com.github.libretube.ui.fragments.AudioPlayerFragment
|
||||
import com.github.libretube.ui.fragments.PlayerFragment
|
||||
import com.github.libretube.ui.views.SingleViewTouchableMotionLayout
|
||||
@ -53,7 +54,7 @@ object NavigationHelper {
|
||||
playlistId: String? = null,
|
||||
channelId: String? = null,
|
||||
keepQueue: Boolean = false,
|
||||
timeStamp: Long? = null,
|
||||
timestamp: Long = 0,
|
||||
forceVideo: Boolean = false,
|
||||
) {
|
||||
if (videoId == null) return
|
||||
@ -63,7 +64,7 @@ object NavigationHelper {
|
||||
BackgroundHelper.playOnBackground(
|
||||
context,
|
||||
videoId.toID(),
|
||||
timeStamp,
|
||||
timestamp,
|
||||
playlistId,
|
||||
channelId,
|
||||
keepQueue,
|
||||
@ -74,13 +75,8 @@ object NavigationHelper {
|
||||
return
|
||||
}
|
||||
|
||||
val bundle = bundleOf(
|
||||
IntentData.videoId to videoId.toID(),
|
||||
IntentData.playlistId to playlistId,
|
||||
IntentData.channelId to channelId,
|
||||
IntentData.keepQueue to keepQueue,
|
||||
IntentData.timeStamp to timeStamp,
|
||||
)
|
||||
val playerData = PlayerData(videoId.toID(), playlistId, channelId, keepQueue, timestamp)
|
||||
val bundle = bundleOf(IntentData.playerData to playerData)
|
||||
|
||||
val activity = ContextHelper.unwrapActivity(context)
|
||||
activity.supportFragmentManager.commitNow {
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.github.libretube.parcelable
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class PlayerData(
|
||||
val videoId: String,
|
||||
val playlistId: String? = null,
|
||||
val channelId: String? = null,
|
||||
val keepQueue: Boolean = false,
|
||||
val timestamp: Long = 0
|
||||
) : Parcelable
|
@ -6,7 +6,6 @@ import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
@ -28,7 +27,7 @@ import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
|
||||
import com.github.libretube.db.DatabaseHolder.Database
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.parcelableExtra
|
||||
import com.github.libretube.extensions.setMetadata
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.helpers.PlayerHelper
|
||||
@ -36,6 +35,7 @@ import com.github.libretube.helpers.PlayerHelper.checkForSegments
|
||||
import com.github.libretube.helpers.PlayerHelper.loadPlaybackParams
|
||||
import com.github.libretube.helpers.ProxyHelper
|
||||
import com.github.libretube.obj.PlayerNotificationData
|
||||
import com.github.libretube.parcelable.PlayerData
|
||||
import com.github.libretube.util.NowPlayingNotification
|
||||
import com.github.libretube.util.PlayingQueue
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -117,27 +117,24 @@ class OnlinePlayerService : LifecycleService() {
|
||||
* Initializes the [player] with the [MediaItem].
|
||||
*/
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
try {
|
||||
// reset the playing queue listeners
|
||||
PlayingQueue.resetToDefaults()
|
||||
// reset the playing queue listeners
|
||||
PlayingQueue.resetToDefaults()
|
||||
|
||||
intent?.parcelableExtra<PlayerData>(IntentData.playerData)?.let { playerData ->
|
||||
// get the intent arguments
|
||||
videoId = intent?.getStringExtra(IntentData.videoId)!!
|
||||
playlistId = intent.getStringExtra(IntentData.playlistId)
|
||||
val position = intent.getLongExtra(IntentData.position, 0L)
|
||||
val keepQueue = intent.getBooleanExtra(IntentData.keepQueue, false)
|
||||
videoId = playerData.videoId
|
||||
playlistId = playerData.playlistId
|
||||
|
||||
// play the audio in the background
|
||||
loadAudio(videoId, position, keepQueue)
|
||||
loadAudio(playerData)
|
||||
|
||||
PlayingQueue.setOnQueueTapListener { streamItem ->
|
||||
streamItem.url?.toID()?.let { playNextVideo(it) }
|
||||
}
|
||||
|
||||
if (PlayerHelper.watchPositionsAudio) updateWatchPosition()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
onDestroy()
|
||||
if (PlayerHelper.watchPositionsAudio) {
|
||||
updateWatchPosition()
|
||||
}
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
@ -158,15 +155,10 @@ class OnlinePlayerService : LifecycleService() {
|
||||
|
||||
/**
|
||||
* Gets the video data and prepares the [player].
|
||||
* @param videoId The id of the video to play
|
||||
* @param seekToPosition The position of the video to seek to
|
||||
* @param keepQueue Whether to keep the queue or clear it instead
|
||||
*/
|
||||
private fun loadAudio(
|
||||
videoId: String,
|
||||
seekToPosition: Long = 0,
|
||||
keepQueue: Boolean = false,
|
||||
) {
|
||||
private fun loadAudio(playerData: PlayerData) {
|
||||
val (videoId, _, _, keepQueue, timestamp) = playerData
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
streams = runCatching {
|
||||
RetrofitInstance.api.getStreams(videoId)
|
||||
@ -183,7 +175,7 @@ class OnlinePlayerService : LifecycleService() {
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
playAudio(seekToPosition)
|
||||
playAudio(timestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,7 +284,7 @@ class OnlinePlayerService : LifecycleService() {
|
||||
this.videoId = nextVideo
|
||||
this.streams = null
|
||||
this.segments = emptyList()
|
||||
loadAudio(videoId, keepQueue = true)
|
||||
loadAudio(PlayerData(videoId, keepQueue = true))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,6 @@ import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.databinding.ActivityMainBinding
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.helpers.BackgroundHelper
|
||||
import com.github.libretube.helpers.NavBarHelper
|
||||
import com.github.libretube.helpers.NavigationHelper
|
||||
import com.github.libretube.helpers.NetworkHelper
|
||||
@ -440,7 +439,7 @@ class MainActivity : BaseActivity() {
|
||||
NavigationHelper.navigateVideo(
|
||||
context = this,
|
||||
videoId = it,
|
||||
timeStamp = intent?.getLongExtra(IntentData.timeStamp, 0L),
|
||||
timestamp = intent.getLongExtra(IntentData.timeStamp, 0L),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
NavigationHelper.navigateVideo(
|
||||
context = requireContext(),
|
||||
videoId = PlayingQueue.getCurrent()?.url?.toID(),
|
||||
timeStamp = playerService?.player?.currentPosition?.div(1000),
|
||||
timestamp = playerService?.player?.currentPosition?.div(1000) ?: 0,
|
||||
keepQueue = true,
|
||||
forceVideo = true,
|
||||
)
|
||||
|
@ -70,6 +70,7 @@ import com.github.libretube.enums.PlayerEvent
|
||||
import com.github.libretube.enums.ShareObjectType
|
||||
import com.github.libretube.extensions.formatShort
|
||||
import com.github.libretube.extensions.hideKeyboard
|
||||
import com.github.libretube.extensions.parcelable
|
||||
import com.github.libretube.extensions.setMetadata
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.extensions.toastFromMainDispatcher
|
||||
@ -86,6 +87,7 @@ import com.github.libretube.helpers.ProxyHelper
|
||||
import com.github.libretube.obj.PlayerNotificationData
|
||||
import com.github.libretube.obj.ShareData
|
||||
import com.github.libretube.obj.VideoResolution
|
||||
import com.github.libretube.parcelable.PlayerData
|
||||
import com.github.libretube.services.DownloadService
|
||||
import com.github.libretube.ui.activities.MainActivity
|
||||
import com.github.libretube.ui.adapters.ChaptersAdapter
|
||||
@ -137,11 +139,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
/**
|
||||
* Video information passed by the intent
|
||||
*/
|
||||
private var videoId: String? = null
|
||||
private lateinit var playerData: PlayerData
|
||||
private lateinit var videoId: String
|
||||
private var playlistId: String? = null
|
||||
private var channelId: String? = null
|
||||
private var keepQueue: Boolean = false
|
||||
private var timeStamp: Long? = null
|
||||
private var timeStamp: Long = 0
|
||||
|
||||
/**
|
||||
* Video information fetched at runtime
|
||||
@ -234,13 +237,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
videoId = it.getString(IntentData.videoId)!!.toID()
|
||||
playlistId = it.getString(IntentData.playlistId)
|
||||
channelId = it.getString(IntentData.channelId)
|
||||
keepQueue = it.getBoolean(IntentData.keepQueue, false)
|
||||
timeStamp = it.getLong(IntentData.timeStamp, 0L)
|
||||
}
|
||||
val playerData = requireArguments().parcelable<PlayerData>(IntentData.playerData)!!
|
||||
videoId = playerData.videoId
|
||||
playlistId = playerData.playlistId
|
||||
channelId = playerData.channelId
|
||||
keepQueue = playerData.keepQueue
|
||||
timeStamp = playerData.timestamp
|
||||
|
||||
// broadcast receiver for PiP actions
|
||||
context?.registerReceiver(
|
||||
@ -390,11 +392,10 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
}
|
||||
|
||||
binding.commentsToggle.setOnClickListener {
|
||||
videoId ?: return@setOnClickListener
|
||||
// set the max height to not cover the currently playing video
|
||||
commentsViewModel.handleLink = this::handleLink
|
||||
commentsViewModel.maxHeight = binding.root.height - binding.player.height
|
||||
commentsViewModel.videoId = videoId
|
||||
commentsViewModel.videoId = playerData.videoId
|
||||
CommentsSheet().show(childFragmentManager)
|
||||
}
|
||||
|
||||
@ -434,7 +435,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
if (!this::streams.isInitialized) return@setOnClickListener
|
||||
val shareDialog =
|
||||
ShareDialog(
|
||||
videoId!!,
|
||||
videoId,
|
||||
ShareObjectType.VIDEO,
|
||||
ShareData(
|
||||
currentVideo = streams.title,
|
||||
@ -487,7 +488,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
BackgroundHelper.stopBackgroundPlay(requireContext())
|
||||
BackgroundHelper.playOnBackground(
|
||||
requireContext(),
|
||||
videoId!!,
|
||||
videoId,
|
||||
exoPlayer.currentPosition,
|
||||
playlistId,
|
||||
channelId,
|
||||
@ -648,7 +649,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
C.TIME_UNSET
|
||||
)
|
||||
) return
|
||||
val watchPosition = WatchPosition(videoId!!, exoPlayer.currentPosition)
|
||||
val watchPosition = WatchPosition(videoId, exoPlayer.currentPosition)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
Database.watchPositionDao().insert(watchPosition)
|
||||
}
|
||||
@ -685,7 +686,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
streams = try {
|
||||
RetrofitInstance.api.getStreams(videoId!!)
|
||||
RetrofitInstance.api.getStreams(videoId)
|
||||
} catch (e: IOException) {
|
||||
context?.toastFromMainDispatcher(R.string.unknown_error, Toast.LENGTH_LONG)
|
||||
return@launch
|
||||
@ -700,18 +701,18 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
if (PlayingQueue.isEmpty()) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
if (playlistId != null) {
|
||||
PlayingQueue.insertPlaylist(playlistId!!, streams.toStreamItem(videoId!!))
|
||||
PlayingQueue.insertPlaylist(playlistId!!, streams.toStreamItem(videoId))
|
||||
} else if (channelId != null) {
|
||||
PlayingQueue.insertChannel(channelId!!, streams.toStreamItem(videoId!!))
|
||||
PlayingQueue.insertChannel(channelId!!, streams.toStreamItem(videoId))
|
||||
} else {
|
||||
PlayingQueue.updateCurrent(streams.toStreamItem(videoId!!))
|
||||
PlayingQueue.updateCurrent(streams.toStreamItem(videoId))
|
||||
if (PlayerHelper.autoInsertRelatedVideos) {
|
||||
PlayingQueue.add(*streams.relatedStreams.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PlayingQueue.updateCurrent(streams.toStreamItem(videoId!!))
|
||||
PlayingQueue.updateCurrent(streams.toStreamItem(videoId))
|
||||
}
|
||||
|
||||
if (PreferenceHelper.getBoolean(PreferenceKeys.AUTO_FULLSCREEN_SHORTS, false)) {
|
||||
@ -761,7 +762,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
|
||||
// add the video to the watch history
|
||||
if (PlayerHelper.watchHistoryEnabled) {
|
||||
DatabaseHelper.addToWatchHistory(videoId!!, streams)
|
||||
DatabaseHelper.addToWatchHistory(videoId, streams)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -777,7 +778,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
if (categories.isEmpty()) return@runCatching
|
||||
segments =
|
||||
RetrofitInstance.api.getSegments(
|
||||
videoId!!,
|
||||
videoId,
|
||||
JsonHelper.json.encodeToString(categories),
|
||||
).segments
|
||||
if (segments.isEmpty()) return@runCatching
|
||||
@ -816,7 +817,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
// browse the watch positions
|
||||
val position = try {
|
||||
runBlocking {
|
||||
Database.watchPositionDao().findById(videoId!!)?.position
|
||||
Database.watchPositionDao().findById(videoId)?.position
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
return
|
||||
@ -832,11 +833,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
*/
|
||||
private fun trySeekToTimeStamp() {
|
||||
// support for time stamped links
|
||||
timeStamp?.let {
|
||||
if (it != 0L) exoPlayer.seekTo(it * 1000)
|
||||
if (timeStamp != 0L) {
|
||||
exoPlayer.seekTo(timeStamp * 1000)
|
||||
}
|
||||
// delete the time stamp because it already got consumed
|
||||
timeStamp = null
|
||||
timeStamp = 0
|
||||
}
|
||||
|
||||
// used for autoplay and skipping to next video
|
||||
@ -1001,7 +1002,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
if (streams.duration <= 0) {
|
||||
Toast.makeText(context, R.string.cannotDownload, Toast.LENGTH_SHORT).show()
|
||||
} else if (!DownloadService.IS_DOWNLOAD_RUNNING) {
|
||||
val newFragment = DownloadDialog(videoId!!)
|
||||
val newFragment = DownloadDialog(videoId)
|
||||
newFragment.show(childFragmentManager, DownloadDialog::class.java.name)
|
||||
} else {
|
||||
Toast.makeText(context, R.string.dlisinprogress, Toast.LENGTH_SHORT)
|
||||
@ -1034,7 +1035,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
)
|
||||
|
||||
binding.relPlayerSave.setOnClickListener {
|
||||
AddToPlaylistDialog(videoId!!).show(
|
||||
AddToPlaylistDialog(videoId).show(
|
||||
childFragmentManager,
|
||||
AddToPlaylistDialog::class.java.name,
|
||||
)
|
||||
@ -1379,7 +1380,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
streams.uploader,
|
||||
streams.thumbnailUrl,
|
||||
)
|
||||
nowPlayingNotification.updatePlayerNotification(videoId!!, playerNotificationData)
|
||||
nowPlayingNotification.updatePlayerNotification(videoId, playerNotificationData)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1458,7 +1459,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
|
||||
override fun onStatsClicked() {
|
||||
if (!this::streams.isInitialized) return
|
||||
StatsDialog(exoPlayer, videoId ?: return)
|
||||
StatsDialog(exoPlayer, videoId)
|
||||
.show(childFragmentManager, null)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user