1.The videos are not visible on the home screen, but they are visible on the same server in libretube.

2.Open download card late on YouTube.

3.When you enter the end time or a higher value there and confirm, the application is closed and the error..

4.The home page player and cut player do not open. When the cut player opens, the video often stops

5.The cutting player does not do its work exactly.
This commit is contained in:
deniscerri 2023-07-30 16:20:09 +02:00
parent 8a42b3f515
commit 444f0cc582
No known key found for this signature in database
GPG key ID: 95C43D517D830350
18 changed files with 185 additions and 74 deletions

View file

@ -10,7 +10,7 @@ def properties = new Properties()
def versionMajor = 1
def versionMinor = 6
def versionPatch = 3
def versionBuild = 15 // bump for dogfood builds, public betas, etc.
def versionBuild = 17 // bump for dogfood builds, public betas, etc.
def versionExt = ""
if (versionBuild > 0){

View file

@ -52,7 +52,10 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.io.File
import java.util.Locale
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.random.Random
import kotlin.random.nextInt
class DownloadViewModel(application: Application) : AndroidViewModel(application) {
@ -149,7 +152,13 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
}
suspend fun updateDownload(item: DownloadItem){
repository.update(item)
if (sharedPreferences.getBoolean("incognito", false)){
if (item.status == DownloadRepository.Status.Cancelled.toString() || item.status == DownloadRepository.Status.Error.toString()){
repository.delete(item)
}
}else{
repository.update(item)
}
}
fun getItemByID(id: Long) : DownloadItem {
@ -485,6 +494,8 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
if (it.status != DownloadRepository.Status.Paused.toString()) it.status = DownloadRepository.Status.Queued.toString()
if (activeAndQueuedDownloads.firstOrNull{d ->
d.id = 0
d.logID = null
d.customFileNameTemplate = it.customFileNameTemplate
d.status = DownloadRepository.Status.Queued.toString()
d.toString() == it.toString()
} != null) {
@ -506,6 +517,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
Toast.makeText(context, context.getString(R.string.download_already_exists), Toast.LENGTH_LONG).show()
}
}
val workManager = WorkManager.getInstance(context)
queuedItems.forEach {
val currentTime = System.currentTimeMillis()
var delay = if (it.downloadStartTime != 0L){
@ -518,19 +532,20 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
val workRequest = OneTimeWorkRequestBuilder<DownloadWorker>()
.setInputData(Data.Builder().putLong("id", it.id).build())
.addTag(it.id.toString())
.addTag("download")
.setConstraints(workConstraints.build())
.setInitialDelay(delay, TimeUnit.SECONDS)
.build()
WorkManager.getInstance(context).beginUniqueWork(
it.id.toString(),
ExistingWorkPolicy.KEEP,
workManager.enqueueUniqueWork(
Random.nextInt(1000000000).toString(),
ExistingWorkPolicy.REPLACE,
workRequest
).enqueue()
)
}
val isCurrentNetworkMetered = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).isActiveNetworkMetered
if (!allowMeteredNetworks && isCurrentNetworkMetered){
Looper.prepare().run {

View file

@ -17,15 +17,17 @@ class CancelDownloadNotificationReceiver : BroadcastReceiver() {
val message = intent.getStringExtra("cancel")
val id = intent.getIntExtra("workID", 0)
if (message != null) {
val notificationUtil = NotificationUtil(c)
notificationUtil.cancelDownloadNotification(id)
YoutubeDL.getInstance().destroyProcessById(id.toString())
runCatching {
val notificationUtil = NotificationUtil(c)
notificationUtil.cancelDownloadNotification(id)
YoutubeDL.getInstance().destroyProcessById(id.toString())
val dbManager = DBManager.getInstance(c)
CoroutineScope(Dispatchers.IO).launch{
val item = dbManager.downloadDao.getDownloadById(id.toLong())
item.status = DownloadRepository.Status.Cancelled.toString()
dbManager.downloadDao.update(item)
val dbManager = DBManager.getInstance(c)
CoroutineScope(Dispatchers.IO).launch{
val item = dbManager.downloadDao.getDownloadById(id.toLong())
item.status = DownloadRepository.Status.Cancelled.toString()
dbManager.downloadDao.update(item)
}
}
}

View file

@ -10,11 +10,13 @@ class PauseDownloadNotificationReceiver : BroadcastReceiver() {
override fun onReceive(c: Context, intent: Intent) {
val id = intent.getIntExtra("workID", 0)
if (id != 0) {
val title = intent.getStringExtra("title")
val notificationUtil = NotificationUtil(c)
notificationUtil.cancelDownloadNotification(id)
YoutubeDL.getInstance().destroyProcessById(id.toString())
notificationUtil.createResumeDownload(id, title, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
runCatching {
val title = intent.getStringExtra("title")
val notificationUtil = NotificationUtil(c)
notificationUtil.cancelDownloadNotification(id)
YoutubeDL.getInstance().destroyProcessById(id.toString())
notificationUtil.createResumeDownload(id, title, NotificationUtil.DOWNLOAD_SERVICE_CHANNEL_ID)
}
}
}
}

View file

@ -6,6 +6,7 @@ import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
@ -26,10 +27,14 @@ import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.neo.highlight.core.Highlight
import com.neo.highlight.util.listener.HighlightTextWatcher
import com.neo.highlight.util.scheme.ColorScheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
import java.util.regex.Pattern
class AddExtraCommandsDialog(private val item: DownloadItem, private val callback: ExtraCommandsListener) : BottomSheetDialogFragment() {
@ -81,11 +86,32 @@ class AddExtraCommandsDialog(private val item: DownloadItem, private val callbac
val text = view.findViewById<EditText>(R.id.command)
val templates = view.findViewById<Button>(R.id.commands)
val shortcuts = view.findViewById<Button>(R.id.shortcuts)
val currentCommand = infoUtil.buildYoutubeDLRequest(item).buildCommand().joinToString(" ")
view.findViewById<TextView>(R.id.currentText)?.text = currentCommand
val currentCommand = infoUtil.parseYTDLRequestString(infoUtil.buildYoutubeDLRequest(item))
val currentText = view.findViewById<TextView>(R.id.currentText)
currentText?.text = currentCommand
//init syntax highlighter
val highlight = Highlight()
val highlightWatcher = HighlightTextWatcher()
val schemes = listOf(
ColorScheme(Pattern.compile("([\"'])(?:\\\\1|.)*?\\1"), Color.parseColor("#FC8500")),
ColorScheme(Pattern.compile("yt-dlp"), Color.parseColor("#00FF00")),
ColorScheme(Pattern.compile("(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})"), Color.parseColor("#b5942f")),
ColorScheme(Pattern.compile("\\d+(\\.\\d)?%"), Color.parseColor("#43a564"))
)
highlight.addScheme(
*schemes.map { it }.toTypedArray()
)
highlightWatcher.addScheme(
*schemes.map { it }.toTypedArray()
)
highlight.setSpan(currentText)
currentText.addTextChangedListener(highlightWatcher)
text?.setText(item.extraCommands)
val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
text!!.postDelayed({
text.setSelection(text.length())

View file

@ -8,28 +8,21 @@ import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Range
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.*
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.MediaItem.fromUri
import androidx.media3.common.Player
import androidx.media3.datasource.DefaultDataSource
import androidx.media3.datasource.cronet.CronetDataSource
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.exoplayer.source.MergingMediaSource
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.ui.PlayerView
import com.deniscerri.ytdlnis.App
import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.ChapterItem
import com.deniscerri.ytdlnis.database.models.DownloadItem
@ -54,14 +47,12 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.chromium.net.CronetEngine
import java.lang.reflect.Type
import java.util.*
import java.util.concurrent.Executors
import kotlin.properties.Delegates
class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls : String?, private var chapters: List<ChapterItem>?, private val listener: VideoCutListener) : BottomSheetDialogFragment() {
class CutVideoBottomSheetDialog(private val item: DownloadItem, private val urls : String?, private var chapters: List<ChapterItem>?, private val listener: VideoCutListener) : BottomSheetDialogFragment() {
private lateinit var behavior: BottomSheetBehavior<View>
private lateinit var infoUtil: InfoUtil
private lateinit var player: ExoPlayer
@ -279,7 +270,7 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
toTextInput.editText!!.setTextAndRecalculateWidth(endTimestampString)
okBtn.isEnabled = !(values[0] == 0F && values[1] == 100F)
okBtn.isEnabled = values[0] != 0F && values[1] != 100F
try {
player.seekTo((startTimestamp * 1000).toLong())
@ -294,26 +285,29 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
if ((event!!.action == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
val startTimestamp = (rangeSlider.valueFrom.toInt() * timeSeconds) / 100
var startTimestamp = (rangeSlider.valueFrom.toInt() * timeSeconds) / 100
val endTimestamp = (rangeSlider.valueTo.toInt() * timeSeconds) / 100
fromTextInput.editText!!.clearFocus()
val seconds = convertStringToTimestamp(fromTextInput.editText!!.text.toString())
var seconds = convertStringToTimestamp(fromTextInput.editText!!.text.toString())
val endSeconds = convertStringToTimestamp(toTextInput.editText!!.text.toString())
val startValue = (seconds.toFloat() / endTimestamp) * 100
var startValue = (seconds.toFloat() / endTimestamp) * 100
val endValue = (endSeconds.toFloat() / endTimestamp) * 100
if (seconds == 0) {
fromTextInput.editText!!.setTextAndRecalculateWidth(infoUtil.formatIntegerDuration(startTimestamp, Locale.US))
}else if (startValue > 100){
startTimestamp = 0
seconds = 0
fromTextInput.editText!!.setTextAndRecalculateWidth(infoUtil.formatIntegerDuration(startTimestamp, Locale.US))
startValue = 0F
}
rangeSlider.setValues(startValue, endValue)
okBtn.isEnabled = !(startValue == 0F && endValue == 100F)
okBtn.isEnabled = startValue != 0F && endValue != 100F
try {
player.seekTo((((startValue * timeSeconds) / 100) * 1000).toLong())
player.seekTo(seconds.toLong() * 1000)
player.play()
}catch (ignored: Exception) {}
@ -331,14 +325,19 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
(keyCode == KeyEvent.KEYCODE_ENTER)) {
val values = rangeSlider.values
val endTimestamp = (rangeSlider.valueTo.toInt() * timeSeconds) / 100
var endTimestamp = (rangeSlider.valueTo.toInt() * timeSeconds) / 100
toTextInput.editText!!.clearFocus()
val startSeconds = convertStringToTimestamp(fromTextInput.editText!!.text.toString())
val seconds = convertStringToTimestamp(toTextInput.editText!!.text.toString())
val startValue = (startSeconds.toFloat() / endTimestamp) * 100
val endValue = (seconds.toFloat() / endTimestamp) * 100
var endValue = (seconds.toFloat() / endTimestamp) * 100
if (endValue > 100F){
endTimestamp = timeSeconds
toTextInput.editText!!.setTextAndRecalculateWidth(infoUtil.formatIntegerDuration(endTimestamp, Locale.US))
endValue = 100F
}
if (seconds == 0) {
toTextInput.editText!!.setTextAndRecalculateWidth(infoUtil.formatIntegerDuration(endTimestamp, Locale.US))
@ -347,9 +346,9 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
}
rangeSlider.setValues(startValue, endValue)
okBtn.isEnabled = !(startValue == 0F && endValue == 100F)
okBtn.isEnabled = startValue != 0F && endValue != 100F
try {
player.seekTo((((startValue * timeSeconds) / 100) * 1000).toLong())
player.seekTo(startSeconds.toLong() * 1000)
player.play()
}catch (ignored: Exception) {}
@ -543,10 +542,8 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
private fun videoProgress(player: ExoPlayer?) = flow {
while (true) {
runCatching {
emit((player!!.currentPosition / 1000).toInt())
delay(1000)
}
emit((player!!.currentPosition / 1000).toInt())
delay(1000)
}
}.flowOn(Dispatchers.Main)
@ -587,4 +584,4 @@ class CutVideoBottomSheetDialog(private val item: DownloadItem, private var urls
interface VideoCutListener{
fun onChangeCut(list: List<String>)
}
}

View file

@ -182,7 +182,11 @@ class DownloadMultipleBottomSheetDialog(private var results: List<ResultItem?>,
}
items.forEachIndexed { index, i ->
i.allFormats.clear()
if (formatCollection.isNotEmpty() && formatCollection[index].isNotEmpty()) i.allFormats.addAll(formatCollection[index])
if (formatCollection.size == items.size && formatCollection[index].isNotEmpty()) {
runCatching {
i.allFormats.addAll(formatCollection[index])
}
}
i.format = selectedFormats[index].format
if (i.type == DownloadViewModel.Type.video) selectedFormats[index].audioFormats?.map { it.format_id }?.let { i.videoPreferences.audioFormatIDs.addAll(it) }
}

View file

@ -75,6 +75,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
private lateinit var activeDownloads: ActiveDownloadMinifiedAdapter
private lateinit var queuedDownloads: GenericDownloadAdapter
private var activeCount: Int = 0
private lateinit var queuedItems : List<DownloadItem>
private lateinit var activeItems : List<DownloadItem>
@ -197,6 +198,10 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
queuedDownloads.submitList(it)
}
downloadViewModel.activeDownloadsCount.observe(viewLifecycleOwner){
activeCount = it
}
bottomSheetLink.text = item.url
bottomSheetLink.setOnClickListener{
@ -448,7 +453,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
Toast.makeText(context, getString(R.string.download_rescheduled_to) + " " + it.time, Toast.LENGTH_LONG).show()
downloadViewModel.deleteDownload(item)
item.downloadStartTime = it.timeInMillis
WorkManager.getInstance(requireContext()).cancelUniqueWork(item.id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(item.id.toString())
runBlocking {
downloadViewModel.queueDownloads(listOf(item))
}
@ -512,7 +517,7 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
bottomSheet.dismiss()
downloadViewModel.deleteDownload(item)
item.downloadStartTime = 0
WorkManager.getInstance(requireContext()).cancelUniqueWork(item.id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(item.id.toString())
runBlocking {
downloadViewModel.queueDownloads(listOf(item))
}
@ -534,6 +539,21 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
}
override fun onCancelClick(itemID: Long) {
lifecycleScope.launch {
if (activeCount == 1){
val queue = withContext(Dispatchers.IO){
val list = downloadViewModel.getQueued().toMutableList()
list.map { it.status = DownloadRepository.Status.Queued.toString() }
list
}
runBlocking {
downloadViewModel.queueDownloads(queue)
}
}
}
cancelActiveDownload(itemID)
}
override fun onPauseClick(itemID: Long, action: ActiveDownloadAdapter.ActiveDownloadAction, position: Int) {
@ -557,8 +577,16 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
}
activeDownloads.notifyItemChanged(position)
val queue = if (activeCount > 1) listOf(item)
else withContext(Dispatchers.IO){
val list = downloadViewModel.getQueued().toMutableList()
list.map { it.status = DownloadRepository.Status.Queued.toString() }
list.add(0, item)
list
}
runBlocking {
downloadViewModel.queueDownloads(listOf(item))
downloadViewModel.queueDownloads(queue)
}
}
}
@ -574,14 +602,14 @@ class ResultCardDetailsDialog(private val item: ResultItem) : BottomSheetDialogF
private fun cancelItem(id: Int){
YoutubeDL.getInstance().destroyProcessById(id.toString())
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(id.toString())
notificationUtil.cancelDownloadNotification(id)
}
private fun cancelActiveDownload(itemID: Long){
val id = itemID.toInt()
YoutubeDL.getInstance().destroyProcessById(id.toString())
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(id.toString())
notificationUtil.cancelDownloadNotification(id)
activeItems.find { it.id == itemID }?.let {

View file

@ -41,6 +41,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
private lateinit var notificationUtil: NotificationUtil
private lateinit var list: List<DownloadItem>
private lateinit var pauseResume: MaterialButton
private lateinit var workManager: WorkManager
override fun onCreateView(
@ -53,6 +54,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
notificationUtil = NotificationUtil(requireContext())
downloadViewModel = ViewModelProvider(this)[DownloadViewModel::class.java]
list = listOf()
workManager = WorkManager.getInstance(requireContext())
return fragmentView
}
@ -87,7 +89,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
}
queued.forEach {
WorkManager.getInstance(requireContext()).cancelUniqueWork(it.id.toString())
workManager.cancelAllWorkByTag(it.id.toString())
}
list.forEach {
@ -136,7 +138,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
it.forEach{item ->
WorkManager.getInstance(requireContext())
.getWorkInfosForUniqueWorkLiveData(item.id.toString())
.getWorkInfosByTagLiveData(item.id.toString())
.observe(viewLifecycleOwner){ list ->
list.forEach {work ->
if (work == null) return@observe
@ -162,6 +164,21 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
}
override fun onCancelClick(itemID: Long) {
lifecycleScope.launch {
if (list.size == 1){
val queue = withContext(Dispatchers.IO){
val list = downloadViewModel.getQueued().toMutableList()
list.map { it.status = DownloadRepository.Status.Queued.toString() }
list
}
runBlocking {
downloadViewModel.queueDownloads(queue)
}
}
}
cancelDownload(itemID)
}
@ -216,7 +233,7 @@ class ActiveDownloadsFragment : Fragment(), ActiveDownloadAdapter.OnItemClickLis
private fun cancelItem(id: Int){
YoutubeDL.getInstance().destroyProcessById(id.toString())
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(id.toString())
notificationUtil.cancelDownloadNotification(id)
}

View file

@ -167,7 +167,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
Toast.makeText(context, getString(R.string.download_rescheduled_to) + " " + it.time, Toast.LENGTH_LONG).show()
downloadViewModel.deleteDownload(item)
item.downloadStartTime = it.timeInMillis
WorkManager.getInstance(requireContext()).cancelUniqueWork(item.id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(item.id.toString())
runBlocking {
downloadViewModel.queueDownloads(listOf(item))
}
@ -231,7 +231,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
bottomSheet.dismiss()
downloadViewModel.deleteDownload(item)
item.downloadStartTime = 0
WorkManager.getInstance(requireContext()).cancelUniqueWork(item.id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(item.id.toString())
runBlocking {
downloadViewModel.queueDownloads(listOf(item))
}
@ -321,7 +321,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
for (obj in selectedObjects!!){
val id = obj.id.toInt()
YoutubeDL.getInstance().destroyProcessById(id.toString())
WorkManager.getInstance(requireContext()).cancelUniqueWork(id.toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(id.toString())
notificationUtil.cancelDownloadNotification(id)
downloadViewModel.deleteDownload(obj)
}
@ -333,7 +333,7 @@ class QueuedDownloadsFragment : Fragment(), GenericDownloadAdapter.OnItemClickLi
}
R.id.download -> {
for (obj in selectedObjects!!){
WorkManager.getInstance(requireContext()).cancelUniqueWork(obj.id.toInt().toString())
WorkManager.getInstance(requireContext()).cancelAllWorkByTag(obj.id.toInt().toString())
}
selectedObjects!!.forEach { it.downloadStartTime = 0L }
lifecycleScope.launch(Dispatchers.IO) {

View file

@ -337,7 +337,7 @@ class TerminalActivity : BaseActivity() {
private fun cancelDownload() {
YoutubeDL.getInstance().destroyProcessById(downloadID.toString())
WorkManager.getInstance(this).cancelUniqueWork(downloadID.toString())
WorkManager.getInstance(this).cancelAllWorkByTag(downloadID.toString())
notificationUtil.cancelDownloadNotification(downloadID)
}

View file

@ -1139,9 +1139,9 @@ class InfoUtil(private val context: Context) {
formatArgument = if (downloadItem.videoPreferences.audioFormatIDs.isNotEmpty() && ! downloadItem.videoPreferences.removeAudio){
val audioIds = downloadItem.videoPreferences.audioFormatIDs.joinToString("+")
"$videoFormatID+$audioIds/best/$videoFormatID"
"$videoFormatID+$audioIds/$videoFormatID/best"
}else{
"$videoFormatID+bestaudio/best/$videoFormatID"
"$videoFormatID+bestaudio/$videoFormatID/best"
}
}
Log.e(DownloadWorker.TAG, formatArgument)
@ -1200,6 +1200,18 @@ class InfoUtil(private val context: Context) {
return request
}
fun parseYTDLRequestString(request : YoutubeDLRequest) : String {
val arr = request.buildCommand().toMutableList()
for (i in arr.indices) {
if (!arr[i].startsWith("-")) {
arr[i] = "\"${arr[i]}\""
}
}
return java.lang.String.join(" ", arr).replace("\"\"", "\" \"")
}
private val pipedURL = sharedPreferences.getString("piped_instance", defaultPipedURL)?.ifEmpty { defaultPipedURL }?.removeSuffix("/")
class PlaylistTuple internal constructor(

View file

@ -342,6 +342,12 @@ class NotificationUtil(var context: Context) {
}
}
fun showYTDLUpdateNotification() : Notification{
val notificationBuilder = getBuilder(DOWNLOAD_MISC_CHANNEL_ID)
notificationBuilder.setContentTitle("Updating YT-DLP...")
return notificationBuilder.build()
}
companion object {
const val DOWNLOAD_SERVICE_CHANNEL_ID = "1"
const val COMMAND_DOWNLOAD_SERVICE_CHANNEL_ID = "2"

View file

@ -39,7 +39,7 @@ class DownloadWorker(
) : Worker(context, workerParams) {
override fun doWork(): Result {
itemId = inputData.getLong("id", 0)
if (itemId == 0L || isStopped) return Result.failure()
if (itemId == 0L || isStopped) return Result.success()
val notificationUtil = NotificationUtil(context)
val infoUtil = InfoUtil(context)
@ -56,10 +56,10 @@ class DownloadWorker(
downloadItem = repository.getItemByID(itemId)
}catch (e: Exception){
e.printStackTrace()
return Result.failure()
return Result.success()
}
if (downloadItem.status != DownloadRepository.Status.Queued.toString() && downloadItem.status != DownloadRepository.Status.Paused.toString()) return Result.failure()
if (downloadItem.status != DownloadRepository.Status.Queued.toString() && downloadItem.status != DownloadRepository.Status.Paused.toString()) return Result.success()
val pendingIntent = NavDeepLinkBuilder(context)
.setGraph(R.navigation.nav_graph)
@ -101,7 +101,7 @@ class DownloadWorker(
"URL: ${downloadItem.url}\n" +
"Type: ${downloadItem.type}\n" +
"Format: ${downloadItem.format}\n\n" +
"Command: ${java.lang.String.join(" ", request.buildCommand())}\n\n",
"Command: ${infoUtil.parseYTDLRequestString(request)} ${downloadItem.extraCommands}\n\n",
downloadItem.format,
downloadItem.type,
System.currentTimeMillis(),
@ -194,7 +194,7 @@ class DownloadWorker(
}.onFailure {
if (it is YoutubeDL.CanceledException) {
return Result.failure(
return Result.success(
Data.Builder().putString("output", "Download has been cancelled!").build()
)
}else{
@ -225,7 +225,7 @@ class DownloadWorker(
NotificationUtil.DOWNLOAD_FINISHED_CHANNEL_ID
)
return Result.failure(
return Result.success(
Data.Builder().putString("output", it.toString()).build()
)
}

View file

@ -39,6 +39,9 @@ class UpdateYTDLWorker(
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result {
val notification = NotificationUtil(context).showYTDLUpdateNotification()
val foregroundInfo = ForegroundInfo(System.currentTimeMillis().toInt(), notification)
setForeground(foregroundInfo)
UpdateUtil(context).updateYoutubeDL()
return Result.success()
}

View file

@ -49,7 +49,6 @@
app:icon="@drawable/exomedia_ic_play_arrow_white"
android:layout_width="wrap_content"
android:indeterminate="true"
android:translationZ="10dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/frame_layout"
app:layout_constraintEnd_toEndOf="parent"
@ -67,7 +66,6 @@
android:layout_width="wrap_content"
android:indeterminate="true"
app:layout_constraintHorizontal_bias="0.0"
android:translationZ="10dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/frame_layout"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -72,6 +72,7 @@
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:textIsSelectable="true"
android:id="@+id/currentText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View file

@ -15,7 +15,7 @@ buildscript {
// supports java 1.6
commonsCompressVer = '1.12'
youtubedlAndroidVer = "23b26d55f8"
workVer = "2.8.1"
workVer = "2.7.0"
composeVer = '1.4.2'
kotlinVer = "1.7.21"
coroutineVer = "1.6.4"