more fixes

pull/848/head
deniscerri 1 year ago
parent e5674805da
commit da276e4518
No known key found for this signature in database
GPG Key ID: 95C43D517D830350

@ -11,8 +11,8 @@ plugins {
def properties = new Properties()
def versionMajor = 1
def versionMinor = 8
def versionPatch = 5
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
def versionPatch = 4
def versionBuild = 2 // bump for dogfood builds, public betas, etc.
def isBeta = true
def versionExt = ""

@ -8,5 +8,6 @@ data class AudioPreferences(
var embedThumb: Boolean = true,
var cropThumb: Boolean? = null,
var splitByChapters: Boolean = false,
var sponsorBlockFilters: ArrayList<String> = arrayListOf()
var sponsorBlockFilters: ArrayList<String> = arrayListOf(),
var bitrate: String = ""
) : Parcelable

@ -293,8 +293,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
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)
@ -473,6 +474,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
}
val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
val audioBitrate = sharedPreferences.getString("audio_bitrate", "")
val extraCommands = when (historyItem.type) {
Type.audio -> extraCommandsForAudio
@ -484,7 +486,7 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
}
}.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)
var path = defaultPath
historyItem.downloadPath.first().apply {
@ -890,9 +892,9 @@ class DownloadViewModel(private val application: Application) : AndroidViewModel
repository.startDownloadWorker(emptyList(), application)
}
suspend fun queueProcessingDownloads() : QueueDownloadsResult {
suspend fun queueProcessingDownloads(ignoreDuplicates: Boolean = false) : QueueDownloadsResult {
val processingItems = repository.getAllProcessingDownloads()
return queueDownloads(processingItems)
return queueDownloads(processingItems, ignoreDuplicates)
}
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()
processing.forEach {
it.downloadStartTime = time
it.status = DownloadRepository.Status.Scheduled.toString()
}
return queueDownloads(processing)
return queueDownloads(processing, ignoreDuplicates)
}
fun checkIfAllProcessingItemsHaveSameType(selectedItems: List<Long>?) : Pair<Boolean, Type> {

@ -315,6 +315,9 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
splitByChaptersClicked = {
downloadItem.audioPreferences.splitByChapters = it
},
bitrateSet = {
downloadItem.audioPreferences.bitrate = it
},
filenameTemplateSet = {
downloadItem.customFileNameTemplate = it
},

@ -85,6 +85,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
private lateinit var result: ResultItem
private lateinit var type: Type
private var ignoreDuplicates: Boolean = false
private var disableUpdateData : Boolean = false
private var currentDownloadItem: DownloadItem? = null
private var incognito: Boolean = false
@ -108,6 +109,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
}
type = arguments?.getSerializable("type") as Type
disableUpdateData = arguments?.getBoolean("disableUpdateData") == true
ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true
if (res == null){
dismiss()
@ -335,7 +337,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
lifecycleScope.launch {
val result = withContext(Dispatchers.IO){
downloadViewModel.queueDownloads(itemsToQueue)
downloadViewModel.queueDownloads(itemsToQueue, ignoreDuplicates)
}
if (result.message.isNotBlank()){
@ -350,7 +352,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
}else{
lifecycleScope.launch {
val result = withContext(Dispatchers.IO){
downloadViewModel.queueDownloads(listOf(item))
downloadViewModel.queueDownloads(listOf(item), ignoreDuplicates)
}
if (result.message.isNotBlank()){
@ -381,7 +383,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) {
downloadViewModel.queueDownloads(itemsToQueue)
downloadViewModel.queueDownloads(itemsToQueue, ignoreDuplicates)
}
withContext(Dispatchers.Main){
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
@ -390,7 +392,7 @@ class DownloadBottomSheetDialog : BottomSheetDialogFragment() {
})
}else{
val result = withContext(Dispatchers.IO) {
downloadViewModel.queueDownloads(listOf(item))
downloadViewModel.queueDownloads(listOf(item), ignoreDuplicates)
}
handleDuplicatesAndDismiss(result.duplicateDownloadIDs)
}

@ -105,6 +105,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
private lateinit var currentDownloadIDs: List<Long>
private lateinit var currentHistoryIDs: List<Long>
private var ignoreDuplicates: Boolean = false
private var processingItemsCount : Int = 0
private lateinit var formatBtn : MenuItem
@ -128,6 +129,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
currentDownloadIDs = arguments?.getLongArray("currentDownloadIDs")?.toList() ?: listOf()
currentHistoryIDs = arguments?.getLongArray("currentHistoryIDs")?.toList() ?: listOf()
ignoreDuplicates = arguments?.getBoolean("ignore_duplicates") == true
processingItemsCount = currentDownloadIDs.size
}
@ -242,7 +244,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
lifecycleScope.launch {
withContext(Dispatchers.IO){
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
val result = downloadViewModel.updateProcessingDownloadTimeAndQueueScheduled(cal.timeInMillis)
val result = downloadViewModel.updateProcessingDownloadTimeAndQueueScheduled(cal.timeInMillis, ignoreDuplicates)
if (result.message.isNotBlank()){
lifecycleScope.launch {
withContext(Dispatchers.Main) {
@ -265,7 +267,7 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
lifecycleScope.launch {
withContext(Dispatchers.IO){
historyViewModel.deleteAllWithIDsCheckFiles(currentHistoryIDs)
val result = downloadViewModel.queueProcessingDownloads()
val result = downloadViewModel.queueProcessingDownloads(ignoreDuplicates)
if (result.message.isNotBlank()){
lifecycleScope.launch {
withContext(Dispatchers.Main) {
@ -545,6 +547,15 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
}
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 ->
items.forEach {
it.customFileNameTemplate = template

@ -516,7 +516,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
if (!filePresent) {
historyViewModel.delete(it, false)
}
downloadViewModel.queueDownloads(listOf(downloadItem))
downloadViewModel.queueDownloads(listOf(downloadItem), ignoreDuplicates = true)
}
historyViewModel.delete(it, false)
},
@ -524,6 +524,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
Pair("result", downloadViewModel.createResultItemFromHistory(it)),
Pair("type", it.type),
Pair("ignore_duplicates", true),
))
}
)
@ -647,7 +648,8 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
Pair("result", downloadViewModel.createResultItemFromHistory(tmp)),
Pair("type", tmp.type)
Pair("type", tmp.type),
Pair("ignore_duplicates", true)
))
}else {
val showDownloadCard = sharedPreferences.getBoolean("download_card", true)
@ -656,6 +658,7 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
if (showDownloadCard){
val bundle = Bundle()
bundle.putLongArray("currentHistoryIDs", selectedObjects.toLongArray())
bundle.putBoolean("ignore_duplicates", true)
findNavController().navigate(R.id.downloadMultipleBottomSheetDialog2, bundle)
}
}
@ -741,7 +744,8 @@ class HistoryFragment : Fragment(), HistoryPaginatedAdapter.OnItemClickListener{
historyAdapter.notifyItemChanged(position)
findNavController().navigate(R.id.downloadBottomSheetDialog, bundleOf(
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.Preference
import androidx.preference.PreferenceManager
import com.afollestad.materialdialogs.utils.MDUtil.getStringArray
import com.deniscerri.ytdl.R
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 {
UiUtil.showGenericConfirmDialog(requireContext(), getString(R.string.reset), getString(R.string.reset_preferences_in_screen)) {
resetPreferences(editor, R.xml.processing_preferences)

@ -320,7 +320,7 @@ object Extensions {
Picasso.get()
.load(imageURL)
.resize(1280, 0)
.transform(BlurTransformation(context, 10, 1))
.transform(BlurTransformation(context, 7, 1))
.onlyScaleDown()
.into(this)

@ -1180,6 +1180,21 @@ object UiUtil {
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){
val clipboard = activity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@ -1620,6 +1635,7 @@ object UiUtil {
embedThumbClicked: (Boolean) -> Unit,
cropThumbClicked: (Boolean) -> Unit,
splitByChaptersClicked: (Boolean) -> Unit,
bitrateSet: (String) -> Unit,
filenameTemplateSet: (String) -> Unit,
sponsorBlockItemsSet: (Array<String>, List<Boolean>) -> Unit,
cutClicked: (VideoCutListener) -> Unit,
@ -1654,6 +1670,34 @@ object UiUtil {
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)
filenameTemplate.setOnClickListener {
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()){
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")
}
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")
}
@ -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)){
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 -> {
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""

@ -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_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
android:id="@+id/filename_template"
style="@style/Widget.Material3.Chip.Assist.Elevated"

@ -24,7 +24,7 @@
android:checked="false"
android:textSize="16sp"
android:textStyle="bold"
android:text="Web Client Po Token"
android:text="@string/web_client_po_token"
tools:ignore="HardcodedText" />
<com.google.android.material.card.MaterialCardView

@ -131,7 +131,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="PO Token"
android:text="@string/potoken"
tools:ignore="HardcodedText" />
<com.google.android.material.textfield.TextInputLayout
@ -140,7 +140,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="potoken_gvs"
android:hint="PO Token (GVS)"
android:hint="GVS"
app:endIconDrawable="@drawable/ic_clipboard"
app:endIconMode="custom"
android:paddingBottom="10dp">
@ -158,10 +158,30 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="potoken_player"
android:hint="PO Token (Player)"
android:hint="Player"
app:endIconDrawable="@drawable/ic_clipboard"
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
android:layout_width="match_parent"
@ -176,7 +196,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="url_regex"
android:hint="PO Token URL Regex"
android:hint="URL Regex"
app:endIconDrawable="@drawable/ic_plus"
app:endIconMode="custom"
android:paddingBottom="10dp"

@ -1556,4 +1556,20 @@
<item>web_music</item>
</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>

@ -478,4 +478,6 @@
<string name="custom">Custom</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="potoken">PO Token</string>
<string name="web_client_po_token">Web Client PO Token</string>
</resources>

@ -14,7 +14,7 @@
android:defaultValue=""
android:icon="@drawable/baseline_stars_24"
android:key="generate_po_tokens"
android:summary="Web Client PO Token"
android:summary="@string/web_client_po_token"
android:title="@string/generate_potokens" />
<SwitchPreferenceCompat

@ -73,6 +73,13 @@
app:summary="@string/embed_metadata_summary"
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
android:widgetLayout="@layout/preferece_material_switch"
app:defaultValue="true"
@ -98,23 +105,6 @@
app:summary="@string/playlist_as_album_summary"
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
app:icon="@drawable/ic_language"
app:dialogTitle="@string/preferred_audio_language"

Loading…
Cancel
Save