more stuff
Added crop thumbnail as a preference Added ability to backup errored downloads Format cards will show collected filesize when multiple audio formats are chosen
This commit is contained in:
parent
0b487e10e6
commit
f259d31b7f
14 changed files with 117 additions and 38 deletions
|
|
@ -37,6 +37,9 @@ interface DownloadDao {
|
||||||
@Query("SELECT * FROM downloads WHERE status='Error' ORDER BY id DESC")
|
@Query("SELECT * FROM downloads WHERE status='Error' ORDER BY id DESC")
|
||||||
fun getErroredDownloads() : Flow<List<DownloadItem>>
|
fun getErroredDownloads() : Flow<List<DownloadItem>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM downloads WHERE status='Error' ORDER BY id DESC")
|
||||||
|
fun getErroredDownloadsList() : List<DownloadItem>
|
||||||
|
|
||||||
@Query("SELECT * FROM downloads WHERE status='Processing' ORDER BY id DESC")
|
@Query("SELECT * FROM downloads WHERE status='Processing' ORDER BY id DESC")
|
||||||
fun getProcessingDownloads() : Flow<List<DownloadItem>>
|
fun getProcessingDownloads() : Flow<List<DownloadItem>>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@ class DownloadRepository(private val downloadDao: DownloadDao) {
|
||||||
return downloadDao.getCancelledDownloadsList()
|
return downloadDao.getCancelledDownloadsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getErroredDownloads() : List<DownloadItem> {
|
||||||
|
return downloadDao.getErroredDownloadsList()
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun deleteCancelled(){
|
suspend fun deleteCancelled(){
|
||||||
downloadDao.deleteCancelled()
|
downloadDao.deleteCancelled()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ package com.deniscerri.ytdlnis.database.viewmodel
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.content.res.Resources
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
|
import android.os.Environment
|
||||||
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
|
@ -37,8 +41,11 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class DownloadViewModel(private val application: Application) : AndroidViewModel(application) {
|
class DownloadViewModel(private val application: Application) : AndroidViewModel(application) {
|
||||||
private val repository : DownloadRepository
|
private val repository : DownloadRepository
|
||||||
private val sharedPreferences: SharedPreferences
|
private val sharedPreferences: SharedPreferences
|
||||||
|
|
@ -58,6 +65,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
|
|
||||||
private val videoQualityPreference: String
|
private val videoQualityPreference: String
|
||||||
private val formatIDPreference: String
|
private val formatIDPreference: String
|
||||||
|
private val resources : Resources
|
||||||
enum class Type {
|
enum class Type {
|
||||||
audio, video, command
|
audio, video, command
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +88,13 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
videoQualityPreference = sharedPreferences.getString("video_quality", application.getString(R.string.best_quality)).toString()
|
videoQualityPreference = sharedPreferences.getString("video_quality", application.getString(R.string.best_quality)).toString()
|
||||||
formatIDPreference = sharedPreferences.getString("format_id", "").toString()
|
formatIDPreference = sharedPreferences.getString("format_id", "").toString()
|
||||||
|
|
||||||
val videoFormat = App.instance.resources.getStringArray(R.array.video_formats)
|
val confTmp = Configuration(application.resources.configuration)
|
||||||
|
confTmp.locale = Locale(sharedPreferences.getString("app_language", "en")!!)
|
||||||
|
val metrics = DisplayMetrics()
|
||||||
|
resources = Resources(application.assets, metrics, confTmp)
|
||||||
|
|
||||||
|
|
||||||
|
val videoFormat = resources.getStringArray(R.array.video_formats)
|
||||||
var videoContainer = sharedPreferences.getString("video_format", "Default")
|
var videoContainer = sharedPreferences.getString("video_format", "Default")
|
||||||
if (videoContainer == "Default") videoContainer = App.instance.getString(R.string.defaultValue)
|
if (videoContainer == "Default") videoContainer = App.instance.getString(R.string.defaultValue)
|
||||||
|
|
||||||
|
|
@ -103,13 +117,13 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
var audioContainer = sharedPreferences.getString("audio_format", "mp3")
|
var audioContainer = sharedPreferences.getString("audio_format", "mp3")
|
||||||
if (audioContainer == "Default") audioContainer = App.instance.getString(R.string.defaultValue)
|
if (audioContainer == "Default") audioContainer = App.instance.getString(R.string.defaultValue)
|
||||||
bestAudioFormat = Format(
|
bestAudioFormat = Format(
|
||||||
getApplication<App>().resources.getString(R.string.best_quality),
|
resources.getString(R.string.best_quality),
|
||||||
audioContainer!!,
|
audioContainer!!,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
getApplication<App>().resources.getString(R.string.best_quality)
|
resources.getString(R.string.best_quality)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,9 +152,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
val downloadPath = when(type){
|
val downloadPath = when(type){
|
||||||
Type.audio -> sharedPreferences.getString("music_path", getApplication<App>().resources.getString(R.string.music_path))
|
Type.audio -> sharedPreferences.getString("music_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Audio").absolutePath)
|
||||||
Type.video -> sharedPreferences.getString("video_path", getApplication<App>().resources.getString(R.string.video_path))
|
Type.video -> sharedPreferences.getString("video_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Video").absolutePath)
|
||||||
else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
else -> sharedPreferences.getString("command_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Command").absolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
|
|
@ -233,9 +247,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
val downloadPath = when(historyItem.type){
|
val downloadPath = when(historyItem.type){
|
||||||
Type.audio -> sharedPreferences.getString("music_path", getApplication<App>().resources.getString(R.string.music_path))
|
Type.audio -> sharedPreferences.getString("music_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Audio").absolutePath)
|
||||||
Type.video -> sharedPreferences.getString("video_path", getApplication<App>().resources.getString(R.string.video_path))
|
Type.video -> sharedPreferences.getString("video_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Video").absolutePath)
|
||||||
else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
|
else -> sharedPreferences.getString("command_path", File(Environment.DIRECTORY_DOWNLOADS, "YTDLnis/Command").absolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
|
|
@ -283,10 +297,10 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
formats.first { !it.format_note.contains("audio", ignoreCase = true) && it.format_id == formatIDPreference }
|
formats.first { !it.format_note.contains("audio", ignoreCase = true) && it.format_id == formatIDPreference }
|
||||||
}catch (e: Exception){
|
}catch (e: Exception){
|
||||||
when (videoQualityPreference) {
|
when (videoQualityPreference) {
|
||||||
getApplication<App>().resources.getString(R.string.worst_quality) -> {
|
"worst" -> {
|
||||||
theFormats.first {!it.format_note.contains("audio", ignoreCase = true) }
|
theFormats.first {!it.format_note.contains("audio", ignoreCase = true) }
|
||||||
}
|
}
|
||||||
getApplication<App>().resources.getString(R.string.best_quality) -> {
|
"best" -> {
|
||||||
theFormats.last {!it.format_note.contains("audio", ignoreCase = true) }
|
theFormats.last {!it.format_note.contains("audio", ignoreCase = true) }
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
@ -323,20 +337,20 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGenericAudioFormats() : MutableList<Format>{
|
fun getGenericAudioFormats() : MutableList<Format>{
|
||||||
val audioFormats = App.instance.resources.getStringArray(R.array.audio_formats)
|
val audioFormats = resources.getStringArray(R.array.audio_formats)
|
||||||
val formats = mutableListOf<Format>()
|
val formats = mutableListOf<Format>()
|
||||||
var containerPreference = sharedPreferences.getString("audio_format", "Default")
|
var containerPreference = sharedPreferences.getString("audio_format", "Default")
|
||||||
if (containerPreference == "Default") containerPreference = App.instance.getString(R.string.defaultValue)
|
if (containerPreference == "Default") containerPreference = resources.getString(R.string.defaultValue)
|
||||||
audioFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
audioFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
|
||||||
return formats
|
return formats
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGenericVideoFormats() : MutableList<Format>{
|
fun getGenericVideoFormats() : MutableList<Format>{
|
||||||
val videoFormats = App.instance.resources.getStringArray(R.array.video_formats)
|
val videoFormats = resources.getStringArray(R.array.video_formats)
|
||||||
val formats = mutableListOf<Format>()
|
val formats = mutableListOf<Format>()
|
||||||
var containerPreference = sharedPreferences.getString("video_format", "Default")
|
var containerPreference = sharedPreferences.getString("video_format", "Default")
|
||||||
if (containerPreference == "Default") containerPreference = application.getString(R.string.defaultValue)
|
if (containerPreference == "Default") containerPreference = resources.getString(R.string.defaultValue)
|
||||||
videoFormats.forEach { formats.add(Format(it, containerPreference!!,application.getString(R.string.defaultValue),"", "",0, it)) }
|
videoFormats.forEach { formats.add(Format(it, containerPreference!!,resources.getString(R.string.defaultValue),"", "",0, it)) }
|
||||||
return formats
|
return formats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,6 +392,10 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
return repository.getCancelledDownloads()
|
return repository.getCancelledDownloads()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getErrored() : List<DownloadItem> {
|
||||||
|
return repository.getErroredDownloads()
|
||||||
|
}
|
||||||
|
|
||||||
private fun cloneFormat(item: Format) : Format {
|
private fun cloneFormat(item: Format) : Format {
|
||||||
val string = Gson().toJson(item, Format::class.java)
|
val string = Gson().toJson(item, Format::class.java)
|
||||||
return Gson().fromJson(string, Format::class.java)
|
return Gson().fromJson(string, Format::class.java)
|
||||||
|
|
@ -407,10 +425,15 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
} != null) {
|
} != null) {
|
||||||
Toast.makeText(context, context.getString(R.string.download_already_exists), Toast.LENGTH_LONG).show()
|
Toast.makeText(context, context.getString(R.string.download_already_exists), Toast.LENGTH_LONG).show()
|
||||||
}else{
|
}else{
|
||||||
it.id = lastDownloadId
|
if (it.id == 0L){
|
||||||
val insert = async {repository.insert(it)}
|
it.id = lastDownloadId
|
||||||
val id = insert.await()
|
val insert = async {repository.insert(it)}
|
||||||
it.id = id
|
val id = insert.await()
|
||||||
|
it.id = id
|
||||||
|
}else{
|
||||||
|
repository.update(it)
|
||||||
|
}
|
||||||
|
|
||||||
queuedItems.add(it)
|
queuedItems.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formats = allFormats.first().toMutableList()
|
formats = allFormats.first().toMutableList()
|
||||||
uiUtil.populateFormatCard(formatCard, item.first(), item.drop(1).map { it.format_note })
|
uiUtil.populateFormatCard(formatCard, item.first(), item.drop(1))
|
||||||
downloadItem.format.container = container.editText?.text.toString()
|
downloadItem.format.container = container.editText?.text.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
"downloads" -> json.add("downloads", backupHistory())
|
"downloads" -> json.add("downloads", backupHistory())
|
||||||
"queued" -> json.add("queued", backupQueuedDownloads() )
|
"queued" -> json.add("queued", backupQueuedDownloads() )
|
||||||
"cancelled" -> json.add("cancelled", backupCancelledDownloads() )
|
"cancelled" -> json.add("cancelled", backupCancelledDownloads() )
|
||||||
|
"errored" -> json.add("errored", backupErroredDownloads() )
|
||||||
"cookies" -> json.add("cookies", backupCookies() )
|
"cookies" -> json.add("cookies", backupCookies() )
|
||||||
"templates" -> json.add("templates", backupCommandTemplates() )
|
"templates" -> json.add("templates", backupCommandTemplates() )
|
||||||
"shortcuts" -> json.add("shortcuts", backupShortcuts() )
|
"shortcuts" -> json.add("shortcuts", backupShortcuts() )
|
||||||
|
|
@ -273,6 +274,20 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
return JsonArray()
|
return JsonArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun backupErroredDownloads() : JsonArray {
|
||||||
|
runCatching {
|
||||||
|
val items = withContext(Dispatchers.IO) {
|
||||||
|
downloadViewModel.getErrored()
|
||||||
|
}
|
||||||
|
val arr = JsonArray()
|
||||||
|
items.forEach {
|
||||||
|
arr.add(JsonParser().parse(Gson().toJson(it)).asJsonObject)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
return JsonArray()
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun backupCookies() : JsonArray {
|
private suspend fun backupCookies() : JsonArray {
|
||||||
runCatching {
|
runCatching {
|
||||||
val items = withContext(Dispatchers.IO) {
|
val items = withContext(Dispatchers.IO) {
|
||||||
|
|
@ -436,6 +451,23 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//erorred downloads restore
|
||||||
|
if(json.has("errored")){
|
||||||
|
val items = json.getAsJsonArray("errored")
|
||||||
|
val errored = mutableListOf<DownloadItem>()
|
||||||
|
items.forEach {
|
||||||
|
val item = Gson().fromJson(it.toString().replace("^\"|\"$", ""), DownloadItem::class.java)
|
||||||
|
item.id = 0L
|
||||||
|
errored.add(item)
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
downloadViewModel.insert(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(errored.isNotEmpty()){
|
||||||
|
finalMessage.append("${getString(R.string.errored)}: ${errored.count()}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//cookies restore
|
//cookies restore
|
||||||
if(json.has("cookies")){
|
if(json.has("cookies")){
|
||||||
val items = json.getAsJsonArray("cookies")
|
val items = json.getAsJsonArray("cookies")
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@ package com.deniscerri.ytdlnis.util
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.text.Html
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.deniscerri.ytdlnis.R
|
import com.deniscerri.ytdlnis.R
|
||||||
import com.deniscerri.ytdlnis.database.models.Format
|
import com.deniscerri.ytdlnis.database.models.Format
|
||||||
|
|
@ -282,12 +284,8 @@ class InfoUtil(private val context: Context) {
|
||||||
var video: ResultItem? = null
|
var video: ResultItem? = null
|
||||||
try {
|
try {
|
||||||
val id = obj.getString("videoId")
|
val id = obj.getString("videoId")
|
||||||
val title = obj.getString("title").toString()
|
val title = Html.fromHtml(obj.getString("title").toString()).toString()
|
||||||
title.replace("'s", "'")
|
val author = Html.fromHtml(obj.getString("author").toString()).toString()
|
||||||
title.replace("&", "&")
|
|
||||||
val author = obj.getString("author").toString()
|
|
||||||
author.replace("'s", "'")
|
|
||||||
author.replace("&", "&")
|
|
||||||
|
|
||||||
if (author.isBlank()) throw Exception()
|
if (author.isBlank()) throw Exception()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,12 @@ import java.util.Calendar
|
||||||
|
|
||||||
class UiUtil(private val fileUtil: FileUtil) {
|
class UiUtil(private val fileUtil: FileUtil) {
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun populateFormatCard(formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List<String>?){
|
fun populateFormatCard(formatCard : MaterialCardView, chosenFormat: Format, audioFormats: List<Format>?){
|
||||||
formatCard.findViewById<TextView>(R.id.container).text = chosenFormat.container.uppercase()
|
formatCard.findViewById<TextView>(R.id.container).text = chosenFormat.container.uppercase()
|
||||||
if (audioFormats.isNullOrEmpty()){
|
if (audioFormats.isNullOrEmpty()){
|
||||||
formatCard.findViewById<TextView>(R.id.format_note).text = chosenFormat.format_note.uppercase()
|
formatCard.findViewById<TextView>(R.id.format_note).text = chosenFormat.format_note.uppercase()
|
||||||
}else{
|
}else{
|
||||||
val title = "${chosenFormat.format_note.uppercase()} + [${audioFormats.joinToString("/")}]"
|
val title = "${chosenFormat.format_note.uppercase()} + [${audioFormats.joinToString("/") { it.format_note }}]"
|
||||||
formatCard.findViewById<TextView>(R.id.format_note).text = title
|
formatCard.findViewById<TextView>(R.id.format_note).text = title
|
||||||
}
|
}
|
||||||
formatCard.findViewById<TextView>(R.id.format_id).text = "id: ${chosenFormat.format_id}"
|
formatCard.findViewById<TextView>(R.id.format_id).text = "id: ${chosenFormat.format_id}"
|
||||||
|
|
@ -77,7 +77,9 @@ class UiUtil(private val fileUtil: FileUtil) {
|
||||||
formatCard.findViewById<TextView>(R.id.codec).visibility = View.VISIBLE
|
formatCard.findViewById<TextView>(R.id.codec).visibility = View.VISIBLE
|
||||||
formatCard.findViewById<TextView>(R.id.codec).text = codec
|
formatCard.findViewById<TextView>(R.id.codec).text = codec
|
||||||
}
|
}
|
||||||
formatCard.findViewById<TextView>(R.id.file_size).text = fileUtil.convertFileSize(chosenFormat.filesize)
|
var filesize = chosenFormat.filesize
|
||||||
|
if (!audioFormats.isNullOrEmpty()) filesize += audioFormats.sumOf { it.filesize }
|
||||||
|
formatCard.findViewById<TextView>(R.id.file_size).text = fileUtil.convertFileSize(filesize)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,19 +184,20 @@ class DownloadWorker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
request.addOption("--embed-metadata")
|
request.addOption("--embed-metadata")
|
||||||
|
|
||||||
if (downloadItem.audioPreferences.embedThumb) {
|
if (downloadItem.audioPreferences.embedThumb) {
|
||||||
request.addOption("--embed-thumbnail")
|
request.addOption("--embed-thumbnail")
|
||||||
request.addOption("--convert-thumbnails", "jpg")
|
request.addOption("--convert-thumbnails", "jpg")
|
||||||
try {
|
if (sharedPreferences.getBoolean("crop_thumbnail", true)){
|
||||||
val config = File(context.cacheDir.absolutePath + "/downloads/${downloadItem.id}/config" + downloadItem.title + "##" + downloadItem.format.format_id + ".txt")
|
try {
|
||||||
val configData = "--ppa \"ffmpeg: -c:v mjpeg -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
val config = File(context.cacheDir.absolutePath + "/downloads/${downloadItem.id}/config" + downloadItem.title + "##" + downloadItem.format.format_id + ".txt")
|
||||||
config.writeText(configData)
|
val configData = "--ppa \"ffmpeg: -c:v mjpeg -vf crop=\\\"'if(gt(ih,iw),iw,ih)':'if(gt(iw,ih),ih,iw)'\\\"\""
|
||||||
request.addOption("--ppa", "ThumbnailsConvertor:-qmin 1 -q:v 1")
|
config.writeText(configData)
|
||||||
request.addOption("--config", config.absolutePath)
|
request.addOption("--ppa", "ThumbnailsConvertor:-qmin 1 -q:v 1")
|
||||||
} catch (ignored: Exception) {}
|
request.addOption("--config", config.absolutePath)
|
||||||
|
} catch (ignored: Exception) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
request.addOption("--parse-metadata", "%(release_year,upload_date)s:%(meta_date)s")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
||||||
|
|
@ -702,6 +702,7 @@
|
||||||
<item>@string/downloads</item>
|
<item>@string/downloads</item>
|
||||||
<item>@string/in_queue</item>
|
<item>@string/in_queue</item>
|
||||||
<item>@string/cancelled</item>
|
<item>@string/cancelled</item>
|
||||||
|
<item>@string/errored</item>
|
||||||
<item>@string/cookies</item>
|
<item>@string/cookies</item>
|
||||||
<item>@string/command_templates</item>
|
<item>@string/command_templates</item>
|
||||||
<item>@string/shortcuts</item>
|
<item>@string/shortcuts</item>
|
||||||
|
|
@ -713,6 +714,7 @@
|
||||||
<item>downloads</item>
|
<item>downloads</item>
|
||||||
<item>queued</item>
|
<item>queued</item>
|
||||||
<item>cancelled</item>
|
<item>cancelled</item>
|
||||||
|
<item>errored</item>
|
||||||
<item>cookies</item>
|
<item>cookies</item>
|
||||||
<item>templates</item>
|
<item>templates</item>
|
||||||
<item>shortcuts</item>
|
<item>shortcuts</item>
|
||||||
|
|
|
||||||
|
|
@ -269,4 +269,6 @@
|
||||||
<string name="general">General</string>
|
<string name="general">General</string>
|
||||||
<string name="swipe_gestures">Swipe Gestures</string>
|
<string name="swipe_gestures">Swipe Gestures</string>
|
||||||
<string name="swipe_gestures_summary">Swipe items for certain actions</string>
|
<string name="swipe_gestures_summary">Swipe items for certain actions</string>
|
||||||
|
<string name="crop_thumb">Crop Thumbnail</string>
|
||||||
|
<string name="crop_thumb_summary">Crop the thumbnail into a square for audio downloads</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -74,6 +74,15 @@
|
||||||
app:summary="@string/embed_thumb_summary"
|
app:summary="@string/embed_thumb_summary"
|
||||||
app:title="@string/embed_thumb" />
|
app:title="@string/embed_thumb" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
|
app:defaultValue="true"
|
||||||
|
android:dependency="embed_thumbnail"
|
||||||
|
app:icon="@drawable/ic_cut"
|
||||||
|
app:key="crop_thumbnail"
|
||||||
|
app:summary="@string/crop_thumb_summary"
|
||||||
|
app:title="@string/crop_thumb" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
app:defaultValue="true"
|
app:defaultValue="true"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue