more fixes
This commit is contained in:
parent
e5674805da
commit
da276e4518
19 changed files with 190 additions and 49 deletions
|
|
@ -11,8 +11,8 @@ plugins {
|
||||||
def properties = new Properties()
|
def properties = new Properties()
|
||||||
def versionMajor = 1
|
def versionMajor = 1
|
||||||
def versionMinor = 8
|
def versionMinor = 8
|
||||||
def versionPatch = 5
|
def versionPatch = 4
|
||||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
def versionBuild = 2 // bump for dogfood builds, public betas, etc.
|
||||||
def isBeta = true
|
def isBeta = true
|
||||||
|
|
||||||
def versionExt = ""
|
def versionExt = ""
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ data class AudioPreferences(
|
||||||
var embedThumb: Boolean = true,
|
var embedThumb: Boolean = true,
|
||||||
var cropThumb: Boolean? = null,
|
var cropThumb: Boolean? = null,
|
||||||
var splitByChapters: Boolean = false,
|
var splitByChapters: Boolean = false,
|
||||||
var sponsorBlockFilters: ArrayList<String> = arrayListOf()
|
var sponsorBlockFilters: ArrayList<String> = arrayListOf(),
|
||||||
|
var bitrate: String = ""
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
|
||||||
|
|
@ -293,8 +293,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
|
|
||||||
|
|
||||||
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
|
val bitrate = sharedPreferences.getString("audio_bitrate", "")
|
||||||
|
|
||||||
val audioPreferences = AudioPreferences(embedThumb, cropThumb,false, ArrayList(sponsorblock!!))
|
val audioPreferences = AudioPreferences(embedThumb, cropThumb,false, ArrayList(sponsorblock!!), bitrate!!)
|
||||||
|
|
||||||
|
|
||||||
val preferredAudioFormats = getPreferredAudioFormats(resultItem.formats)
|
val preferredAudioFormats = getPreferredAudioFormats(resultItem.formats)
|
||||||
|
|
@ -473,6 +474,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
|
||||||
|
val audioBitrate = sharedPreferences.getString("audio_bitrate", "")
|
||||||
|
|
||||||
val extraCommands = when (historyItem.type) {
|
val extraCommands = when (historyItem.type) {
|
||||||
Type.audio -> extraCommandsForAudio
|
Type.audio -> extraCommandsForAudio
|
||||||
|
|
@ -484,7 +486,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
}.joinToString(" ") { it.content }
|
}.joinToString(" ") { it.content }
|
||||||
|
|
||||||
val audioPreferences = AudioPreferences(embedThumb, cropThumb,false, ArrayList(sponsorblock!!))
|
val audioPreferences = AudioPreferences(embedThumb, cropThumb,false, ArrayList(sponsorblock!!), audioBitrate!!)
|
||||||
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs, saveAutoSubs, subsLanguages, recodeVideo = recodeVideo)
|
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs, saveAutoSubs, subsLanguages, recodeVideo = recodeVideo)
|
||||||
var path = defaultPath
|
var path = defaultPath
|
||||||
historyItem.downloadPath.first().apply {
|
historyItem.downloadPath.first().apply {
|
||||||
|
|
@ -890,9 +892,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
repository.startDownloadWorker(emptyList(), application)
|
repository.startDownloadWorker(emptyList(), application)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun queueProcessingDownloads() : QueueDownloadsResult {
|
suspend fun queueProcessingDownloads(ignoreDuplicates: Boolean = false) : QueueDownloadsResult {
|
||||||
val processingItems = repository.getAllProcessingDownloads()
|
val processingItems = repository.getAllProcessingDownloads()
|
||||||
return queueDownloads(processingItems)
|
return queueDownloads(processingItems, ignoreDuplicates)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class QueueDownloadsResult(
|
data class QueueDownloadsResult(
|
||||||
|
|
@ -1262,13 +1264,13 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateProcessingDownloadTimeAndQueueScheduled(time: Long) : QueueDownloadsResult {
|
suspend fun updateProcessingDownloadTimeAndQueueScheduled(time: Long, ignoreDuplicates: Boolean = false) : QueueDownloadsResult {
|
||||||
val processing = repository.getAllProcessingDownloads()
|
val processing = repository.getAllProcessingDownloads()
|
||||||
processing.forEach {
|
processing.forEach {
|
||||||
it.downloadStartTime = time
|
it.downloadStartTime = time
|
||||||
it.status = DownloadRepository.Status.Scheduled.toString()
|
it.status = DownloadRepository.Status.Scheduled.toString()
|
||||||
}
|
}
|
||||||
return queueDownloads(processing)
|
return queueDownloads(processing, ignoreDuplicates)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkIfAllProcessingItemsHaveSameType(selectedItems: List<Long>?) : Pair<Boolean, Type> {
|
fun checkIfAllProcessingItemsHaveSameType(selectedItems: List<Long>?) : Pair<Boolean, Type> {
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,9 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
||||||
splitByChaptersClicked = {
|
splitByChaptersClicked = {
|
||||||
downloadItem.audioPreferences.splitByChapters = it
|
downloadItem.audioPreferences.splitByChapters = it
|
||||||
},
|
},
|
||||||
|
bitrateSet = {
|
||||||
|
downloadItem.audioPreferences.bitrate = it
|
||||||
|
},
|
||||||
filenameTemplateSet = {
|
filenameTemplateSet = {
|
||||||
downloadItem.customFileNameTemplate = it
|
downloadItem.customFileNameTemplate = it
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
private lateinit var result: ResultItem
|
private lateinit var result: ResultItem
|
||||||
private lateinit var type: Type
|
private lateinit var type: Type
|
||||||
|
private var ignoreDuplicates: Boolean = false
|
||||||
private var disableUpdateData : Boolean = false
|
private var disableUpdateData : Boolean = false
|
||||||
private var currentDownloadItem: DownloadItem? = null
|
private var currentDownloadItem: DownloadItem? = null
|
||||||
private var incognito: Boolean = false
|
private var incognito: Boolean = false
|
||||||
|
|
@ -108,6 +109,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
type = arguments?.getSerializable("type") as Type
|
type = arguments?.getSerializable("type") as Type
|
||||||
disableUpdateData = arguments?.getBoolean("disableUpdateData") == true
|
disableUpdateData = arguments?.getBoolean("disableUpdateData") == true
|
||||||
|
ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true
|
||||||
|
|
||||||
if (res == null){
|
if (res == null){
|
||||||
dismiss()
|
dismiss()
|
||||||
|
|
@ -335,7 +337,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val result = withContext(Dispatchers.IO){
|
val result = withContext(Dispatchers.IO){
|
||||||
downloadViewModel.queueDownloads(itemsToQueue)
|
downloadViewModel.queueDownloads(itemsToQueue, ignoreDuplicates)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.message.isNotBlank()){
|
if (result.message.isNotBlank()){
|
||||||
|
|
@ -350,7 +352,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
}else{
|
}else{
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val result = withContext(Dispatchers.IO){
|
val result = withContext(Dispatchers.IO){
|
||||||
downloadViewModel.queueDownloads(listOf(item))
|
downloadViewModel.queueDownloads(listOf(item), ignoreDuplicates)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.message.isNotBlank()){
|
if (result.message.isNotBlank()){
|
||||||
|
|
@ -381,7 +383,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val result = withContext(Dispatchers.IO) {
|
val result = withContext(Dispatchers.IO) {
|
||||||
downloadViewModel.queueDownloads(itemsToQueue)
|
downloadViewModel.queueDownloads(itemsToQueue, ignoreDuplicates)
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Main){
|
withContext(Dispatchers.Main){
|
||||||
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
|
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
|
||||||
|
|
@ -390,7 +392,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
val result = withContext(Dispatchers.IO) {
|
val result = withContext(Dispatchers.IO) {
|
||||||
downloadViewModel.queueDownloads(listOf(item))
|
downloadViewModel.queueDownloads(listOf(item), ignoreDuplicates)
|
||||||
}
|
}
|
||||||
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
|
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
|
|
||||||
private lateinit var currentDownloadIDs: List<Long>
|
private lateinit var currentDownloadIDs: List<Long>
|
||||||
private lateinit var currentHistoryIDs: List<Long>
|
private lateinit var currentHistoryIDs: List<Long>
|
||||||
|
private var ignoreDuplicates: Boolean = false
|
||||||
private var processingItemsCount : Int = 0
|
private var processingItemsCount : Int = 0
|
||||||
|
|
||||||
private lateinit var formatBtn : MenuItem
|
private lateinit var formatBtn : MenuItem
|
||||||
|
|
@ -128,6 +129,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
|
|
||||||
currentDownloadIDs = arguments?.getLongArray("currentDownloadIDs")?.toList() ?: listOf()
|
currentDownloadIDs = arguments?.getLongArray("currentDownloadIDs")?.toList() ?: listOf()
|
||||||
currentHistoryIDs = arguments?.getLongArray("currentHistoryIDs")?.toList() ?: listOf()
|
currentHistoryIDs = arguments?.getLongArray("currentHistoryIDs")?.toList() ?: listOf()
|
||||||
|
ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true
|
||||||
processingItemsCount = currentDownloadIDs.size
|
processingItemsCount = currentDownloadIDs.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,7 +244,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO){
|
||||||
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
|
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
|
||||||
val result = downloadViewModel.updateProcessingDownloadTimeAndQueueScheduled(cal.timeInMillis)
|
val result = downloadViewModel.updateProcessingDownloadTimeAndQueueScheduled(cal.timeInMillis, ignoreDuplicates)
|
||||||
if (result.message.isNotBlank()){
|
if (result.message.isNotBlank()){
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
|
@ -265,7 +267,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO){
|
||||||
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
|
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
|
||||||
val result = downloadViewModel.queueProcessingDownloads()
|
val result = downloadViewModel.queueProcessingDownloads(ignoreDuplicates)
|
||||||
if (result.message.isNotBlank()){
|
if (result.message.isNotBlank()){
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
|
@ -545,6 +547,15 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
}
|
}
|
||||||
CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } }
|
CoroutineScope(Dispatchers.IO).launch { items.forEach { downloadViewModel.updateDownload(it) } }
|
||||||
},
|
},
|
||||||
|
bitrateSet = { bitrate ->
|
||||||
|
items.forEach {
|
||||||
|
it.audioPreferences.bitrate = bitrate
|
||||||
|
}
|
||||||
|
requireActivity().lifecycleScope.launch {
|
||||||
|
items.forEach { downloadViewModel.updateDownload(it) }
|
||||||
|
}
|
||||||
|
bottomSheet.dismiss()
|
||||||
|
},
|
||||||
filenameTemplateSet = {template ->
|
filenameTemplateSet = {template ->
|
||||||
items.forEach {
|
items.forEach {
|
||||||
it.customFileNameTemplate = template
|
it.customFileNameTemplate = template
|
||||||
|
|
|
||||||
|
|
@ -516,7 +516,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
if (!filePresent) {
|
if (!filePresent) {
|
||||||
historyViewModel.delete(it, false)
|
historyViewModel.delete(it, false)
|
||||||
}
|
}
|
||||||
downloadViewModel.queueDownloads(listOf(downloadItem))
|
downloadViewModel.queueDownloads(listOf(downloadItem), ignoreDuplicates = true)
|
||||||
}
|
}
|
||||||
historyViewModel.delete(it, false)
|
historyViewModel.delete(it, false)
|
||||||
},
|
},
|
||||||
|
|
@ -524,6 +524,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||||
Pair("result", downloadViewModel.createResultItemFromHistory(it)),
|
Pair("result", downloadViewModel.createResultItemFromHistory(it)),
|
||||||
Pair("type", it.type),
|
Pair("type", it.type),
|
||||||
|
Pair("ignore_duplicates", true),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -647,7 +648,8 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
|
|
||||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||||
Pair("result", downloadViewModel.createResultItemFromHistory(tmp)),
|
Pair("result", downloadViewModel.createResultItemFromHistory(tmp)),
|
||||||
Pair("type", tmp.type)
|
Pair("type", tmp.type),
|
||||||
|
Pair("ignore_duplicates", true)
|
||||||
))
|
))
|
||||||
}else {
|
}else {
|
||||||
val showDownloadCard = sharedPreferences.getBoolean("download_card", true)
|
val showDownloadCard = sharedPreferences.getBoolean("download_card", true)
|
||||||
|
|
@ -656,6 +658,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
if (showDownloadCard){
|
if (showDownloadCard){
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putLongArray("currentHistoryIDs", selectedObjects.toLongArray())
|
bundle.putLongArray("currentHistoryIDs", selectedObjects.toLongArray())
|
||||||
|
bundle.putBoolean("ignore_duplicates", true)
|
||||||
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundle)
|
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -741,7 +744,8 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
|
||||||
historyAdapter.notifyItemChanged(position)
|
historyAdapter.notifyItemChanged(position)
|
||||||
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
|
||||||
Pair("result", downloadViewModel.createResultItemFromHistory(item)),
|
Pair("result", downloadViewModel.createResultItemFromHistory(item)),
|
||||||
Pair("type", item.type)
|
Pair("type", item.type),
|
||||||
|
Pair("ignore_duplicates", true)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import androidx.navigation.fragment.findNavController
|
||||||
import androidx.preference.EditTextPreference
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
|
||||||
import com.deniscerri.ytdl.R
|
import com.deniscerri.ytdl.R
|
||||||
import com.deniscerri.ytdl.util.UiUtil
|
import com.deniscerri.ytdl.util.UiUtil
|
||||||
|
|
||||||
|
|
@ -74,6 +75,31 @@ class ProcessingSettingsFragment : BaseSettingsFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>("audio_bitrate")?.apply {
|
||||||
|
var currentValue = prefs.getString("audio_bitrate", "")!!
|
||||||
|
val entries = context.getStringArray(R.array.audio_bitrate)
|
||||||
|
val entryValues = context.getStringArray(R.array.audio_bitrate_values)
|
||||||
|
|
||||||
|
summary = if (currentValue.isNotBlank()) {
|
||||||
|
entries[entryValues.indexOf(currentValue)]
|
||||||
|
}else {
|
||||||
|
getString(R.string.defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnPreferenceClickListener {
|
||||||
|
currentValue = prefs.getString("audio_bitrate", "")!!
|
||||||
|
UiUtil.showAudioBitrateDialog(requireActivity(), currentValue) {
|
||||||
|
editor.putString("audio_bitrate", it).apply()
|
||||||
|
summary = if (it.isNotBlank()) {
|
||||||
|
entries[entryValues.indexOf(it)]
|
||||||
|
}else {
|
||||||
|
getString(R.string.defaultValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
findPreference<Preference>("reset_preferences")?.setOnPreferenceClickListener {
|
findPreference<Preference>("reset_preferences")?.setOnPreferenceClickListener {
|
||||||
UiUtil.showGenericConfirmDialog(requireContext(), getString(R.string.reset), getString(R.string.reset_preferences_in_screen)) {
|
UiUtil.showGenericConfirmDialog(requireContext(), getString(R.string.reset), getString(R.string.reset_preferences_in_screen)) {
|
||||||
resetPreferences(editor, R.xml.processing_preferences)
|
resetPreferences(editor, R.xml.processing_preferences)
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ object Extensions {
|
||||||
Picasso.get()
|
Picasso.get()
|
||||||
.load(imageURL)
|
.load(imageURL)
|
||||||
.resize(1280, 0)
|
.resize(1280, 0)
|
||||||
.transform(BlurTransformation(context, 10, 1))
|
.transform(BlurTransformation(context, 7, 1))
|
||||||
.onlyScaleDown()
|
.onlyScaleDown()
|
||||||
.into(this)
|
.into(this)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1180,6 +1180,21 @@ object UiUtil {
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).gravity = Gravity.START
|
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).gravity = Gravity.START
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showAudioBitrateDialog(context: Activity, currentValue: String, ok: (newValue: String) -> Unit){
|
||||||
|
val entries = context.getStringArray(R.array.audio_bitrate)
|
||||||
|
val entryValues = context.getStringArray(R.array.audio_bitrate_values)
|
||||||
|
|
||||||
|
val prefIndex = entryValues.indexOf(currentValue)
|
||||||
|
MaterialAlertDialogBuilder(context)
|
||||||
|
.setTitle(context.getString(R.string.bitrate))
|
||||||
|
.setSingleChoiceItems(entries, prefIndex) { dialog, index ->
|
||||||
|
ok(entryValues[index])
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun copyToClipboard(text: String, activity: Activity){
|
fun copyToClipboard(text: String, activity: Activity){
|
||||||
val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
|
@ -1620,6 +1635,7 @@ object UiUtil {
|
||||||
embedThumbClicked: (Boolean) -> Unit,
|
embedThumbClicked: (Boolean) -> Unit,
|
||||||
cropThumbClicked: (Boolean) -> Unit,
|
cropThumbClicked: (Boolean) -> Unit,
|
||||||
splitByChaptersClicked: (Boolean) -> Unit,
|
splitByChaptersClicked: (Boolean) -> Unit,
|
||||||
|
bitrateSet: (String) -> Unit,
|
||||||
filenameTemplateSet: (String) -> Unit,
|
filenameTemplateSet: (String) -> Unit,
|
||||||
sponsorBlockItemsSet: (Array<String>, List<Boolean>) -> Unit,
|
sponsorBlockItemsSet: (Array<String>, List<Boolean>) -> Unit,
|
||||||
cutClicked: (VideoCutListener) -> Unit,
|
cutClicked: (VideoCutListener) -> Unit,
|
||||||
|
|
@ -1654,6 +1670,34 @@ object UiUtil {
|
||||||
splitByChaptersClicked(splitByChapters.isChecked)
|
splitByChaptersClicked(splitByChapters.isChecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val bitrate = view.findViewById<Chip>(R.id.audio_bitrate)
|
||||||
|
bitrate.apply {
|
||||||
|
fun changeLabelText(newVal: String) {
|
||||||
|
if(newVal.isBlank()) return
|
||||||
|
val t = context.getString(R.string.bitrate) + " (${newVal})"
|
||||||
|
text = t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCurrentBitrate() = if (items.size == 1 || items.all { it.audioPreferences.bitrate == items[0].audioPreferences.bitrate }){
|
||||||
|
items[0].audioPreferences.bitrate
|
||||||
|
}else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
changeLabelText(getCurrentBitrate())
|
||||||
|
|
||||||
|
setOnClickListener {
|
||||||
|
showAudioBitrateDialog(context, getCurrentBitrate()) {
|
||||||
|
var newText = context.getString(R.string.bitrate)
|
||||||
|
if (it.isNotBlank()) {
|
||||||
|
newText += " (${it})"
|
||||||
|
}
|
||||||
|
text = newText
|
||||||
|
bitrateSet(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val filenameTemplate = view.findViewById<Chip>(R.id.filename_template)
|
val filenameTemplate = view.findViewById<Chip>(R.id.filename_template)
|
||||||
filenameTemplate.setOnClickListener {
|
filenameTemplate.setOnClickListener {
|
||||||
val currentFilename = if (items.size == 1 || items.all { it.customFileNameTemplate == items[0].customFileNameTemplate }){
|
val currentFilename = if (items.size == 1 || items.all { it.customFileNameTemplate == items[0].customFileNameTemplate }){
|
||||||
|
|
|
||||||
|
|
@ -867,13 +867,13 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
|
||||||
}
|
}
|
||||||
|
|
||||||
if(downloadItem.title.isNotBlank()){
|
if(downloadItem.title.isNotBlank()){
|
||||||
metadataCommands.addOption("--replace-in-metadata", "title", """^.*$""", downloadItem.title)
|
metadataCommands.addOption("--replace-in-metadata", "title", """^.*$""", downloadItem.title.replace("""\""", """\\"""))
|
||||||
metadataCommands.addOption("--parse-metadata", "%(title)s:%(meta_title)s")
|
metadataCommands.addOption("--parse-metadata", "%(title)s:%(meta_title)s")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (downloadItem.author.isNotBlank()){
|
if (downloadItem.author.isNotBlank()){
|
||||||
metadataCommands.addOption("--replace-in-metadata", "uploader", """^.*$""", downloadItem.author)
|
metadataCommands.addOption("--replace-in-metadata", "uploader", """^.*$""", downloadItem.author.replace("""\""", """\\"""))
|
||||||
metadataCommands.addOption("--parse-metadata", "%(uploader)s:%(artist)s")
|
metadataCommands.addOption("--parse-metadata", "%(uploader)s:%(artist)s")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -892,10 +892,6 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedPreferences.getBoolean("use_audio_quality", false)){
|
|
||||||
request.addOption("--audio-quality", sharedPreferences.getInt("audio_quality", 0).toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sharedPreferences.getBoolean("write_description", false)){
|
if (sharedPreferences.getBoolean("write_description", false)){
|
||||||
request.addOption("--write-description")
|
request.addOption("--write-description")
|
||||||
}
|
}
|
||||||
|
|
@ -1089,6 +1085,10 @@ class YTDLPUtil(private val context: Context, private val commandTemplateDao: Co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloadItem.audioPreferences.bitrate.isNotBlank()) {
|
||||||
|
request.addOption("--audio-quality", downloadItem.audioPreferences.bitrate)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
DownloadViewModel.Type.video -> {
|
DownloadViewModel.Type.video -> {
|
||||||
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
|
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
|
||||||
|
|
|
||||||
5
app/src/main/res/drawable/baseline_high_quality_24.xml
Normal file
5
app/src/main/res/drawable/baseline_high_quality_24.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="?android:colorAccent" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM18,14c0,0.55 -0.45,1 -1,1h-0.75v1.5h-1.5L14.75,15L14,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v4zM14.5,13.5h2v-3h-2v3z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
|
|
@ -80,6 +80,21 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/audio_bitrate"
|
||||||
|
style="@style/Widget.Material3.Chip.Assist.Elevated"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/bitrate"
|
||||||
|
app:chipIconVisible="true"
|
||||||
|
app:chipIcon="@drawable/baseline_high_quality_24"
|
||||||
|
android:minWidth="30dp"
|
||||||
|
app:cornerRadius="10dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/filename_template"
|
android:id="@+id/filename_template"
|
||||||
style="@style/Widget.Material3.Chip.Assist.Elevated"
|
style="@style/Widget.Material3.Chip.Assist.Elevated"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:text="Web Client Po Token"
|
android:text="@string/web_client_po_token"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:text="PO Token"
|
android:text="@string/potoken"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
|
@ -140,7 +140,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:tag="potoken_gvs"
|
android:tag="potoken_gvs"
|
||||||
android:hint="PO Token (GVS)"
|
android:hint="GVS"
|
||||||
app:endIconDrawable="@drawable/ic_clipboard"
|
app:endIconDrawable="@drawable/ic_clipboard"
|
||||||
app:endIconMode="custom"
|
app:endIconMode="custom"
|
||||||
android:paddingBottom="10dp">
|
android:paddingBottom="10dp">
|
||||||
|
|
@ -158,10 +158,30 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:tag="potoken_player"
|
android:tag="potoken_player"
|
||||||
android:hint="PO Token (Player)"
|
android:hint="Player"
|
||||||
app:endIconDrawable="@drawable/ic_clipboard"
|
app:endIconDrawable="@drawable/ic_clipboard"
|
||||||
app:endIconMode="custom"
|
app:endIconMode="custom"
|
||||||
android:paddingBottom="10dp">
|
android:paddingBottom="10dp"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="text" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/po_token_subs"
|
||||||
|
style="@style/Widget.Material3.TextInputLayout.FilledBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:tag="potoken_subs"
|
||||||
|
android:hint="Subs"
|
||||||
|
app:endIconDrawable="@drawable/ic_clipboard"
|
||||||
|
app:endIconMode="custom"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -176,7 +196,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:tag="url_regex"
|
android:tag="url_regex"
|
||||||
android:hint="PO Token URL Regex"
|
android:hint="URL Regex"
|
||||||
app:endIconDrawable="@drawable/ic_plus"
|
app:endIconDrawable="@drawable/ic_plus"
|
||||||
app:endIconMode="custom"
|
app:endIconMode="custom"
|
||||||
android:paddingBottom="10dp"
|
android:paddingBottom="10dp"
|
||||||
|
|
|
||||||
|
|
@ -1556,4 +1556,20 @@
|
||||||
<item>web_music</item>
|
<item>web_music</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="audio_bitrate">
|
||||||
|
<item>@string/defaultValue</item>
|
||||||
|
<item>320 kpbs</item>
|
||||||
|
<item>192 kpbs</item>
|
||||||
|
<item>128 kpbs</item>
|
||||||
|
<item>64 kpbs</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="audio_bitrate_values">
|
||||||
|
<item></item>
|
||||||
|
<item>320k</item>
|
||||||
|
<item>192k</item>
|
||||||
|
<item>128k</item>
|
||||||
|
<item>64k</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -478,4 +478,6 @@
|
||||||
<string name="custom">Custom</string>
|
<string name="custom">Custom</string>
|
||||||
<string name="cut_unsupported">Cutting is not available for this item</string>
|
<string name="cut_unsupported">Cutting is not available for this item</string>
|
||||||
<string name="select_between_desc">Specify the range of items to select</string>
|
<string name="select_between_desc">Specify the range of items to select</string>
|
||||||
|
<string name="potoken">PO Token</string>
|
||||||
|
<string name="web_client_po_token">Web Client PO Token</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
android:defaultValue=""
|
android:defaultValue=""
|
||||||
android:icon="@drawable/baseline_stars_24"
|
android:icon="@drawable/baseline_stars_24"
|
||||||
android:key="generate_po_tokens"
|
android:key="generate_po_tokens"
|
||||||
android:summary="Web Client PO Token"
|
android:summary="@string/web_client_po_token"
|
||||||
android:title="@string/generate_potokens" />
|
android:title="@string/generate_potokens" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,13 @@
|
||||||
app:summary="@string/embed_metadata_summary"
|
app:summary="@string/embed_metadata_summary"
|
||||||
app:title="@string/embed_metadata" />
|
app:title="@string/embed_metadata" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:icon="@drawable/baseline_high_quality_24"
|
||||||
|
app:key="audio_bitrate"
|
||||||
|
app:defaultValue=""
|
||||||
|
android:summary="@string/defaultValue"
|
||||||
|
app:title="@string/bitrate" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
app:defaultValue="true"
|
app:defaultValue="true"
|
||||||
|
|
@ -98,23 +105,6 @@
|
||||||
app:summary="@string/playlist_as_album_summary"
|
app:summary="@string/playlist_as_album_summary"
|
||||||
app:title="@string/playlist_as_album" />
|
app:title="@string/playlist_as_album" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
|
||||||
app:defaultValue="false"
|
|
||||||
app:icon="@drawable/ic_music"
|
|
||||||
app:key="use_audio_quality"
|
|
||||||
app:title="@string/custom_audio_quality" />
|
|
||||||
|
|
||||||
<SeekBarPreference
|
|
||||||
android:defaultValue="0"
|
|
||||||
android:max="10"
|
|
||||||
android:dependency="use_audio_quality"
|
|
||||||
app:key="audio_quality"
|
|
||||||
app:min="0"
|
|
||||||
app:showSeekBarValue="true"
|
|
||||||
app:summary="@string/audio_quality_summary"
|
|
||||||
app:title="@string/audio_quality" />
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
app:icon="@drawable/ic_language"
|
app:icon="@drawable/ic_language"
|
||||||
app:dialogTitle="@string/preferred_audio_language"
|
app:dialogTitle="@string/preferred_audio_language"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue