mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
Merge pull request #2993 from Isira-Seneviratne/LifecycleService
Use LifecycleService.
This commit is contained in:
commit
793ad8e731
@ -92,6 +92,7 @@ dependencies {
|
||||
implementation libs.lifecycle.viewmodel
|
||||
implementation libs.lifecycle.runtime
|
||||
implementation libs.lifecycle.livedata
|
||||
implementation libs.lifecycle.service
|
||||
|
||||
/* Testing */
|
||||
androidTestImplementation libs.androidx.test.junit
|
||||
|
@ -3,7 +3,6 @@ package com.github.libretube.services
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
@ -13,10 +12,11 @@ import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.lifecycle.LifecycleService
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.JsonHelper
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.obj.Segment
|
||||
import com.github.libretube.api.obj.SegmentData
|
||||
import com.github.libretube.api.obj.Streams
|
||||
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
|
||||
@ -37,15 +37,15 @@ import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.encodeToString
|
||||
|
||||
/**
|
||||
* Loads the selected videos audio in background mode with a notification area.
|
||||
*/
|
||||
class BackgroundMode : Service() {
|
||||
class BackgroundMode : LifecycleService() {
|
||||
/**
|
||||
* VideoId of the video
|
||||
*/
|
||||
@ -171,7 +171,7 @@ class BackgroundMode : Service() {
|
||||
seekToPosition: Long = 0,
|
||||
keepQueue: Boolean = false
|
||||
) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
streams = runCatching {
|
||||
RetrofitInstance.api.getStreams(videoId)
|
||||
}.getOrNull() ?: return@launch
|
||||
@ -186,7 +186,7 @@ class BackgroundMode : Service() {
|
||||
PlayingQueue.updateCurrent(it)
|
||||
}
|
||||
|
||||
handler.post {
|
||||
withContext(Dispatchers.Main) {
|
||||
playAudio(seekToPosition)
|
||||
}
|
||||
}
|
||||
@ -292,17 +292,13 @@ class BackgroundMode : Service() {
|
||||
* Sets the [MediaItem] with the [streams] into the [player]
|
||||
*/
|
||||
private fun setMediaItem() {
|
||||
val streams = streams
|
||||
streams ?: return
|
||||
|
||||
val uri = if (streams!!.audioStreams.orEmpty().isNotEmpty()) {
|
||||
PlayerHelper.getAudioSource(
|
||||
this,
|
||||
streams!!.audioStreams!!
|
||||
)
|
||||
} else if (streams!!.hls != null) {
|
||||
streams!!.hls
|
||||
val uri = if (streams.audioStreams.isNotEmpty()) {
|
||||
PlayerHelper.getAudioSource(this, streams.audioStreams)
|
||||
} else {
|
||||
return
|
||||
streams.hls ?: return
|
||||
}
|
||||
|
||||
val mediaItem = MediaItem.Builder()
|
||||
@ -315,7 +311,7 @@ class BackgroundMode : Service() {
|
||||
* fetch the segments for SponsorBlock
|
||||
*/
|
||||
private fun fetchSponsorBlockSegments() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
runCatching {
|
||||
val categories = PlayerHelper.getSponsorBlockCategories()
|
||||
if (categories.isEmpty()) return@runCatching
|
||||
@ -336,7 +332,7 @@ class BackgroundMode : Service() {
|
||||
|
||||
if (segmentData == null || segmentData!!.segments.isEmpty()) return
|
||||
|
||||
segmentData!!.segments.forEach { segment: Segment ->
|
||||
segmentData!!.segments.forEach { segment ->
|
||||
val segmentStart = (segment.segment[0] * 1000f).toLong()
|
||||
val segmentEnd = (segment.segment[1] * 1000f).toLong()
|
||||
val currentPosition = player?.currentPosition
|
||||
@ -399,7 +395,8 @@ class BackgroundMode : Service() {
|
||||
fun getService(): BackgroundMode = this@BackgroundMode
|
||||
}
|
||||
|
||||
override fun onBind(p0: Intent?): IBinder {
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
super.onBind(intent)
|
||||
return binder
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package com.github.libretube.services
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
@ -11,6 +10,8 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.core.util.set
|
||||
import androidx.core.util.valueIterator
|
||||
import androidx.lifecycle.LifecycleService
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.CronetHelper
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
@ -40,9 +41,7 @@ import java.io.File
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.URL
|
||||
import java.util.concurrent.Executors
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -55,16 +54,15 @@ import okio.BufferedSink
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import okio.source
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* Download service with custom implementation of downloading using [HttpURLConnection].
|
||||
*/
|
||||
class DownloadService : Service() {
|
||||
|
||||
class DownloadService : LifecycleService() {
|
||||
private val binder = LocalBinder()
|
||||
private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
private val jobMain = SupervisorJob()
|
||||
private val scope = CoroutineScope(dispatcher + jobMain)
|
||||
private val coroutineContext = dispatcher + SupervisorJob()
|
||||
|
||||
private lateinit var notificationManager: NotificationManager
|
||||
private lateinit var summaryNotificationBuilder: NotificationCompat.Builder
|
||||
@ -81,6 +79,7 @@ class DownloadService : Service() {
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
super.onStartCommand(intent, flags, startId)
|
||||
when (intent?.action) {
|
||||
ACTION_DOWNLOAD_RESUME -> resume(intent.getIntExtra("id", -1))
|
||||
ACTION_DOWNLOAD_PAUSE -> pause(intent.getIntExtra("id", -1))
|
||||
@ -94,9 +93,11 @@ class DownloadService : Service() {
|
||||
val audioQuality = intent.getStringExtra(IntentData.audioQuality)
|
||||
val subtitleCode = intent.getStringExtra(IntentData.subtitleCode)
|
||||
|
||||
scope.launch {
|
||||
lifecycleScope.launch(coroutineContext) {
|
||||
try {
|
||||
val streams = RetrofitInstance.api.getStreams(videoId)
|
||||
val streams = withContext(Dispatchers.IO) {
|
||||
RetrofitInstance.api.getStreams(videoId)
|
||||
}
|
||||
|
||||
val thumbnailTargetFile = getDownloadFile(DownloadHelper.THUMBNAIL_DIR, fileName)
|
||||
|
||||
@ -153,7 +154,7 @@ class DownloadService : Service() {
|
||||
Database.downloadDao().insertDownloadItem(item)
|
||||
}.toInt()
|
||||
|
||||
scope.launch {
|
||||
lifecycleScope.launch(coroutineContext) {
|
||||
downloadFile(item)
|
||||
}
|
||||
}
|
||||
@ -269,7 +270,8 @@ class DownloadService : Service() {
|
||||
sourceByte.close()
|
||||
con.disconnect()
|
||||
}
|
||||
} catch (_: Exception) { }
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
val completed = when {
|
||||
totalRead < item.downloadSize -> {
|
||||
@ -297,7 +299,7 @@ class DownloadService : Service() {
|
||||
val downloadCount = downloadQueue.valueIterator().asSequence().count { it }
|
||||
if (downloadCount >= DownloadHelper.getMaxConcurrentDownloads()) {
|
||||
toastFromMainThread(getString(R.string.concurrent_downloads_limit_reached))
|
||||
scope.launch {
|
||||
lifecycleScope.launch(coroutineContext) {
|
||||
_downloadFlow.emit(id to DownloadStatus.Paused)
|
||||
}
|
||||
return
|
||||
@ -306,7 +308,7 @@ class DownloadService : Service() {
|
||||
val downloadItem = awaitQuery {
|
||||
Database.downloadDao().findDownloadItemById(id)
|
||||
}
|
||||
scope.launch {
|
||||
lifecycleScope.launch(coroutineContext) {
|
||||
downloadFile(downloadItem)
|
||||
}
|
||||
}
|
||||
@ -468,9 +470,9 @@ class DownloadService : Service() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder {
|
||||
val ids = intent?.getIntArrayExtra("ids")
|
||||
ids?.forEach { id -> resume(id) }
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
super.onBind(intent)
|
||||
intent.getIntArrayExtra("ids")?.forEach { resume(it) }
|
||||
return binder
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ square-leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-andr
|
||||
lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
|
||||
lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
|
||||
lifecycle-livedata = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycle" }
|
||||
lifecycle-service = { group = "androidx.lifecycle", name = "lifecycle-service", version.ref = "lifecycle" }
|
||||
room = { group = "androidx.room", name="room-ktx", version.ref = "room" }
|
||||
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
|
||||
|
Loading…
Reference in New Issue
Block a user