added sponsorblock settings in download card and other fixes in format data not being correct

This commit is contained in:
deniscerri 2023-03-22 15:04:19 +01:00
parent 071e080aae
commit 0e23d88c74
No known key found for this signature in database
GPG key ID: 95C43D517D830350
9 changed files with 256 additions and 94 deletions

View file

@ -3,4 +3,5 @@ package com.deniscerri.ytdlnis.database.models
data class AudioPreferences( data class AudioPreferences(
var embedThumb: Boolean = true, var embedThumb: Boolean = true,
var splitByChapters: Boolean = false, var splitByChapters: Boolean = false,
var sponsorBlockFilters: ArrayList<String>
) )

View file

@ -4,4 +4,5 @@ data class VideoPreferences (
var embedSubs: Boolean = true, var embedSubs: Boolean = true,
var addChapters: Boolean = true, var addChapters: Boolean = true,
var splitByChapters: Boolean = false, var splitByChapters: Boolean = false,
var sponsorBlockFilters: ArrayList<String>
) )

View file

@ -118,8 +118,10 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path)) else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
} }
val audioPreferences = AudioPreferences(embedThumb) val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
val videoPreferences = VideoPreferences(embedSubs, addChapters)
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock))
return DownloadItem(0, return DownloadItem(0,
resultItem.url, resultItem.url,
@ -157,8 +159,10 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path)) else -> sharedPreferences.getString("command_path", getApplication<App>().resources.getString(R.string.command_path))
} }
val audioPreferences = AudioPreferences(embedThumb) val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
val videoPreferences = VideoPreferences(embedSubs, addChapters)
val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!))
val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock))
return DownloadItem(0, return DownloadItem(0,
historyItem.url, historyItem.url,
@ -179,30 +183,32 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
when(type) { when(type) {
Type.audio -> { Type.audio -> {
return try { return try {
formats.last { it.format_note.contains("audio", ignoreCase = true) } cloneFormat(formats.last { it.format_note.contains("audio", ignoreCase = true) })
}catch (e: Exception){ }catch (e: Exception){
bestAudioFormat bestAudioFormat
} }
} }
Type.video -> { Type.video -> {
return try { return cloneFormat(
val theFormats = formats.ifEmpty { defaultVideoFormats } try {
val theFormats = formats.ifEmpty { defaultVideoFormats }
val qualityPreference = sharedPreferences.getString("video_quality", getApplication<App>().resources.getString(R.string.best_quality)) val qualityPreference = sharedPreferences.getString("video_quality", getApplication<App>().resources.getString(R.string.best_quality))
if (qualityPreference == getApplication<App>().resources.getString(R.string.worst_quality)){ if (qualityPreference == getApplication<App>().resources.getString(R.string.worst_quality)){
theFormats.first { !it.format_note.contains("audio", ignoreCase = true) } theFormats.first { !it.format_note.contains("audio", ignoreCase = true) }
} }
if (qualityPreference == getApplication<App>().resources.getString(R.string.best_quality)){ if (qualityPreference == getApplication<App>().resources.getString(R.string.best_quality)){
theFormats.last { !it.format_note.contains("audio", ignoreCase = true) } theFormats.last { !it.format_note.contains("audio", ignoreCase = true) }
} }
try{ try{
theFormats.last { format -> format.format_note.contains(qualityPreference!!.substring(0, qualityPreference.length - 1)) } theFormats.last { format -> format.format_note.contains(qualityPreference!!.substring(0, qualityPreference.length - 1)) }
}catch (e: Exception){
theFormats.last { !it.format_note.contains("audio", ignoreCase = true) }
}
}catch (e: Exception){ }catch (e: Exception){
theFormats.last { !it.format_note.contains("audio", ignoreCase = true) } bestVideoFormat
} }
}catch (e: Exception){ )
bestVideoFormat
}
} }
else -> { else -> {
val c = commandTemplateDao.getFirst() val c = commandTemplateDao.getFirst()
@ -268,9 +274,9 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application
repository.deleteQueued() repository.deleteQueued()
} }
fun cloneDownloadItem(item: DownloadItem) : DownloadItem { fun cloneFormat(item: Format) : Format {
val string = Gson().toJson(item, DownloadItem::class.java) val string = Gson().toJson(item, Format::class.java)
return Gson().fromJson(string, DownloadItem::class.java) return Gson().fromJson(string, Format::class.java)
} }
suspend fun queueDownloads(items: List<DownloadItem>) { suspend fun queueDownloads(items: List<DownloadItem>) {

View file

@ -1,7 +1,9 @@
package com.deniscerri.ytdlnis.ui.downloadcard package com.deniscerri.ytdlnis.ui.downloadcard
import android.app.Activity import android.app.Activity
import android.app.AlertDialog
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -20,6 +22,8 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.MultiSelectListPreference
import androidx.preference.Preference
import com.deniscerri.ytdlnis.R import com.deniscerri.ytdlnis.R
import com.deniscerri.ytdlnis.database.models.DownloadItem import com.deniscerri.ytdlnis.database.models.DownloadItem
import com.deniscerri.ytdlnis.database.models.Format import com.deniscerri.ytdlnis.database.models.Format
@ -30,6 +34,7 @@ import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -104,8 +109,8 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
saveDir.editText!!.setText( saveDir.editText!!.setText(
fileUtil.formatPath(downloadItem.downloadPath) fileUtil.formatPath(downloadItem.downloadPath)
) )
saveDir.editText!!.isFocusable = false; saveDir.editText!!.isFocusable = false
saveDir.editText!!.isClickable = true; saveDir.editText!!.isClickable = true
saveDir.editText!!.setOnClickListener { saveDir.editText!!.setOnClickListener {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
@ -189,6 +194,49 @@ class DownloadAudioFragment(private var resultItem: ResultItem, private var curr
downloadItem.audioPreferences.splitByChapters = splitByChapters.isChecked downloadItem.audioPreferences.splitByChapters = splitByChapters.isChecked
} }
val sponsorblock = view.findViewById<Chip>(R.id.sponsorblock_filters)
sponsorblock!!.setOnClickListener {
val builder = MaterialAlertDialogBuilder(requireContext())
builder.setTitle(getString(R.string.select_sponsorblock_filtering))
val values = resources.getStringArray(R.array.sponsorblock_settings_values)
val entries = resources.getStringArray(R.array.sponsorblock_settings_entries)
val checkedItems : ArrayList<Boolean> = arrayListOf()
values.forEach {
if (downloadItem.audioPreferences.sponsorBlockFilters.contains(it)) {
checkedItems.add(true)
}else{
checkedItems.add(false)
}
}
builder.setMultiChoiceItems(
entries,
checkedItems.toBooleanArray()
) { dialog, which, isChecked ->
checkedItems[which] = isChecked
}
builder.setPositiveButton(
getString(R.string.ok)
) { dialog: DialogInterface?, which: Int ->
downloadItem.audioPreferences.sponsorBlockFilters.clear()
for (i in 0 until checkedItems.size) {
if (checkedItems[i]) {
downloadItem.audioPreferences.sponsorBlockFilters.add(values[i])
}
}
}
// handle the negative button of the alert dialog
builder.setNegativeButton(
getString(R.string.cancel)
) { dialog: DialogInterface?, which: Int -> }
val dialog = builder.create()
dialog.show()
}
val copyURL = view.findViewById<Chip>(R.id.copy_url) val copyURL = view.findViewById<Chip>(R.id.copy_url)
copyURL.setOnClickListener { copyURL.setOnClickListener {
val clipboard: ClipboardManager = val clipboard: ClipboardManager =

View file

@ -2,6 +2,7 @@ package com.deniscerri.ytdlnis.ui.downloadcard
import android.app.Activity import android.app.Activity
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -30,6 +31,7 @@ import com.deniscerri.ytdlnis.databinding.FragmentHomeBinding
import com.deniscerri.ytdlnis.util.FileUtil import com.deniscerri.ytdlnis.util.FileUtil
import com.deniscerri.ytdlnis.util.UiUtil import com.deniscerri.ytdlnis.util.UiUtil
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -127,6 +129,11 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
var formats = mutableListOf<Format>() var formats = mutableListOf<Format>()
formats.addAll(resultItem.formats.filter { !it.format_note.contains("audio", ignoreCase = true) }) formats.addAll(resultItem.formats.filter { !it.format_note.contains("audio", ignoreCase = true) })
val videoFormats = resources.getStringArray(R.array.video_formats) val videoFormats = resources.getStringArray(R.array.video_formats)
val containers = requireContext().resources.getStringArray(R.array.video_containers)
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
val containerAutoCompleteTextView =
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
val containerPreference = sharedPreferences.getString("video_format", getString(R.string.defaultValue)) val containerPreference = sharedPreferences.getString("video_format", getString(R.string.defaultValue))
if (formats.isEmpty()) { if (formats.isEmpty()) {
@ -134,29 +141,8 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
videoFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) } videoFormats.forEach { formats.add(Format(it, containerPreference!!,"","", "",0, it)) }
} }
val containers = requireContext().resources.getStringArray(R.array.video_containers)
val container = view.findViewById<TextInputLayout>(R.id.downloadContainer)
val containerAutoCompleteTextView =
view.findViewById<AutoCompleteTextView>(R.id.container_textview)
container?.isEnabled = true
containerAutoCompleteTextView?.setAdapter(
ArrayAdapter(
requireContext(),
android.R.layout.simple_dropdown_item_1line,
containers
)
)
downloadItem.format.container = containerPreference!!
containerAutoCompleteTextView!!.setText(downloadItem.format.container, false)
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.format.container = containers[index]
}
val formatCard = view.findViewById<ConstraintLayout>(R.id.format_card_constraintLayout) val formatCard = view.findViewById<ConstraintLayout>(R.id.format_card_constraintLayout)
val chosenFormat = downloadItem.format val chosenFormat = downloadItem.format
uiUtil.populateFormatCard(formatCard, chosenFormat) uiUtil.populateFormatCard(formatCard, chosenFormat)
val listener = object : OnFormatClickListener { val listener = object : OnFormatClickListener {
@ -184,6 +170,23 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
bottomSheet.show(parentFragmentManager, "formatSheet") bottomSheet.show(parentFragmentManager, "formatSheet")
} }
container?.isEnabled = true
containerAutoCompleteTextView?.setAdapter(
ArrayAdapter(
requireContext(),
android.R.layout.simple_dropdown_item_1line,
containers
)
)
downloadItem.format.container = containerPreference!!
containerAutoCompleteTextView!!.setText(downloadItem.format.container, false)
(container!!.editText as AutoCompleteTextView?)!!.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, index: Int, _: Long ->
downloadItem.format.container = containers[index]
}
val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles) val embedSubs = view.findViewById<Chip>(R.id.embed_subtitles)
embedSubs!!.isChecked = downloadItem.videoPreferences.embedSubs embedSubs!!.isChecked = downloadItem.videoPreferences.embedSubs
embedSubs.setOnClickListener { embedSubs.setOnClickListener {
@ -216,6 +219,49 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr
downloadItem.SaveThumb = saveThumbnail.isChecked downloadItem.SaveThumb = saveThumbnail.isChecked
} }
val sponsorblock = view.findViewById<Chip>(R.id.sponsorblock_filters)
sponsorblock!!.setOnClickListener {
val builder = MaterialAlertDialogBuilder(requireContext())
builder.setTitle(getString(R.string.select_sponsorblock_filtering))
val values = resources.getStringArray(R.array.sponsorblock_settings_values)
val entries = resources.getStringArray(R.array.sponsorblock_settings_entries)
val checkedItems : ArrayList<Boolean> = arrayListOf()
values.forEach {
if (downloadItem.videoPreferences.sponsorBlockFilters.contains(it)) {
checkedItems.add(true)
}else{
checkedItems.add(false)
}
}
builder.setMultiChoiceItems(
entries,
checkedItems.toBooleanArray()
) { dialog, which, isChecked ->
checkedItems[which] = isChecked
}
builder.setPositiveButton(
getString(R.string.ok)
) { dialog: DialogInterface?, which: Int ->
downloadItem.videoPreferences.sponsorBlockFilters.clear()
for (i in 0 until checkedItems.size) {
if (checkedItems[i]) {
downloadItem.videoPreferences.sponsorBlockFilters.add(values[i])
}
}
}
// handle the negative button of the alert dialog
builder.setNegativeButton(
getString(R.string.cancel)
) { dialog: DialogInterface?, which: Int -> }
val dialog = builder.create()
dialog.show()
}
val copyURL = view.findViewById<Chip>(R.id.copy_url) val copyURL = view.findViewById<Chip>(R.id.copy_url)
copyURL.setOnClickListener { copyURL.setOnClickListener {
val clipboard: ClipboardManager = val clipboard: ClipboardManager =

View file

@ -5,6 +5,7 @@ import android.app.Dialog
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.* import android.widget.*
@ -98,6 +99,7 @@ class FormatSelectionBottomSheetDialog(private val item: DownloadItem, private v
private fun addFormatsToView(linearLayout: LinearLayout){ private fun addFormatsToView(linearLayout: LinearLayout){
linearLayout.removeAllViews() linearLayout.removeAllViews()
Log.e("aa", formats.toString())
for (i in formats.lastIndex downTo 0){ for (i in formats.lastIndex downTo 0){
val it = formats[i] val it = formats[i]
val formatItem = LayoutInflater.from(context).inflate(R.layout.format_item, null) val formatItem = LayoutInflater.from(context).inflate(R.layout.format_item, null)

View file

@ -94,8 +94,18 @@ class DownloadWorker(
if (!sharedPreferences.getBoolean("mtime", false)){ if (!sharedPreferences.getBoolean("mtime", false)){
request.addOption("--no-mtime") request.addOption("--no-mtime")
} }
val sponsorBlockFilters = sharedPreferences.getStringSet("sponsorblock_filters", emptySet())
if (sponsorBlockFilters!!.isNotEmpty()) { val sponsorBlockFilters : ArrayList<String> = when(downloadItem.type) {
DownloadViewModel.Type.audio -> {
downloadItem.audioPreferences.sponsorBlockFilters
}
//video
else -> {
downloadItem.videoPreferences.sponsorBlockFilters
}
}
if (sponsorBlockFilters.isNotEmpty()) {
val filters = java.lang.String.join(",", sponsorBlockFilters) val filters = java.lang.String.join(",", sponsorBlockFilters)
request.addOption("--sponsorblock-remove", filters) request.addOption("--sponsorblock-remove", filters)
} }

View file

@ -197,6 +197,20 @@
android:checked="false" android:checked="false"
android:text="@string/split_by_chapters"/> android:text="@string/split_by_chapters"/>
<com.google.android.material.chip.Chip
android:id="@+id/sponsorblock_filters"
style="@style/Widget.Material3.Chip.Assist.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="SponsorBlock"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_money"
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/copy_url" android:id="@+id/copy_url"

View file

@ -168,63 +168,97 @@
android:text="@string/adjust_video" android:text="@string/adjust_video"
android:textSize="15sp" /> android:textSize="15sp" />
<HorizontalScrollView
<com.google.android.material.chip.ChipGroup
android:id="@+id/chipGroup"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
app:chipSpacingVertical="0dp"
app:singleLine="false">
<com.google.android.material.chip.Chip <com.google.android.material.chip.ChipGroup
android:id="@+id/embed_subtitles" android:id="@+id/chipGroup1"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" app:chipSpacingVertical="0dp"
android:text="@string/embed_subtitles" /> app:singleLine="true">
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/add_chapters" android:id="@+id/embed_subtitles"
style="@style/Widget.Material3.Chip.Filter.Elevated" style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/embed_subtitles" />
<com.google.android.material.chip.Chip
android:id="@+id/add_chapters"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/add_chapter" />
<com.google.android.material.chip.Chip
android:id="@+id/split_by_chapters"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/split_by_chapters"/>
<com.google.android.material.chip.Chip
android:id="@+id/save_thumbnail"
style="@style/Widget.Material3.Chip.Filter.Elevated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:text="@string/save_thumb" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" app:singleLine="true">
android:text="@string/add_chapter" />
<com.google.android.material.chip.Chip <com.google.android.material.chip.Chip
android:id="@+id/split_by_chapters" android:id="@+id/sponsorblock_filters"
style="@style/Widget.Material3.Chip.Filter.Elevated" style="@style/Widget.Material3.Chip.Assist.Elevated"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" android:gravity="center"
android:text="@string/split_by_chapters"/> android:text="SponsorBlock"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_money"
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/save_thumbnail" android:id="@+id/copy_url"
style="@style/Widget.Material3.Chip.Filter.Elevated" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:gravity="center"
android:checked="false" android:text="@string/copy_url"
android:text="@string/save_thumb" /> app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
<com.google.android.material.chip.Chip android:minWidth="30dp"
android:id="@+id/copy_url" app:cornerRadius="10dp"
android:layout_width="wrap_content" app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent"
android:gravity="center" app:layout_constraintTop_toTopOf="parent" />
android:text="@string/copy_url"
app:chipIconVisible="true"
app:chipIcon="@drawable/ic_clipboard"
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.ChipGroup> </com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
</LinearLayout> </LinearLayout>