more bug fixes
This commit is contained in:
parent
82b2f651ab
commit
73b5be6f6f
19 changed files with 401 additions and 121 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 = 1
|
def versionPatch = 2
|
||||||
def versionBuild = 2 // bump for dogfood builds, public betas, etc.
|
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||||
def isBeta = false
|
def isBeta = false
|
||||||
|
|
||||||
def versionExt = ""
|
def versionExt = ""
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,7 @@ data class VideoPreferences (
|
||||||
var audioFormatIDs : ArrayList<String> = arrayListOf(),
|
var audioFormatIDs : ArrayList<String> = arrayListOf(),
|
||||||
var removeAudio: Boolean = false,
|
var removeAudio: Boolean = false,
|
||||||
var alsoDownloadAsAudio: Boolean = false,
|
var alsoDownloadAsAudio: Boolean = false,
|
||||||
var recodeVideo: Boolean = false
|
var recodeVideo: Boolean = false,
|
||||||
|
var liveFromStart: Boolean = false,
|
||||||
|
var waitForVideoMinutes: Int = 0
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import com.deniscerri.ytdl.database.models.ResultItem
|
||||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
|
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
|
||||||
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
|
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
|
||||||
|
import com.deniscerri.ytdl.util.Extensions.applyFilenameTemplateForCuts
|
||||||
import com.deniscerri.ytdl.util.FileUtil
|
import com.deniscerri.ytdl.util.FileUtil
|
||||||
import com.deniscerri.ytdl.util.FormatUtil
|
import com.deniscerri.ytdl.util.FormatUtil
|
||||||
import com.deniscerri.ytdl.util.UiUtil
|
import com.deniscerri.ytdl.util.UiUtil
|
||||||
|
|
@ -335,6 +336,13 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
||||||
cutValueChanged = {
|
cutValueChanged = {
|
||||||
downloadItem.downloadSections = it
|
downloadItem.downloadSections = it
|
||||||
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, showSize = downloadItem.downloadSections.isEmpty())
|
UiUtil.populateFormatCard(requireContext(), formatCard, downloadItem.format, showSize = downloadItem.downloadSections.isEmpty())
|
||||||
|
|
||||||
|
if (it.isNotBlank()){
|
||||||
|
downloadItem.customFileNameTemplate = downloadItem.customFileNameTemplate.applyFilenameTemplateForCuts()
|
||||||
|
}else{
|
||||||
|
downloadItem.customFileNameTemplate = sharedPreferences.getString("file_name_template_audio", "%(uploader).30B - %(title).170B")!!
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
extraCommandsClicked = {
|
extraCommandsClicked = {
|
||||||
val callback = object : ExtraCommandsListener {
|
val callback = object : ExtraCommandsListener {
|
||||||
|
|
|
||||||
|
|
@ -692,7 +692,9 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
||||||
|
|
||||||
val bottomSheetDialog = AddExtraCommandsDialog(null, callback)
|
val bottomSheetDialog = AddExtraCommandsDialog(null, callback)
|
||||||
bottomSheetDialog.show(parentFragmentManager, "extraCommands")
|
bottomSheetDialog.show(parentFragmentManager, "extraCommands")
|
||||||
}
|
},
|
||||||
|
waitForVideo = {b, i -> },
|
||||||
|
liveFromStart = {}
|
||||||
)
|
)
|
||||||
|
|
||||||
bottomSheet.show()
|
bottomSheet.show()
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import com.deniscerri.ytdl.database.models.ResultItem
|
||||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel
|
||||||
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
|
import com.deniscerri.ytdl.database.viewmodel.DownloadViewModel.Type
|
||||||
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
|
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
|
||||||
|
import com.deniscerri.ytdl.util.Extensions.applyFilenameTemplateForCuts
|
||||||
import com.deniscerri.ytdl.util.FileUtil
|
import com.deniscerri.ytdl.util.FileUtil
|
||||||
import com.deniscerri.ytdl.util.FormatUtil
|
import com.deniscerri.ytdl.util.FormatUtil
|
||||||
import com.deniscerri.ytdl.util.UiUtil
|
import com.deniscerri.ytdl.util.UiUtil
|
||||||
|
|
@ -382,6 +383,12 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
||||||
else downloadItem.allFormats.filter { f -> downloadItem.videoPreferences.audioFormatIDs.contains(f.format_id) },
|
else downloadItem.allFormats.filter { f -> downloadItem.videoPreferences.audioFormatIDs.contains(f.format_id) },
|
||||||
showSize = downloadItem.downloadSections.isEmpty()
|
showSize = downloadItem.downloadSections.isEmpty()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (it.isNotBlank()){
|
||||||
|
downloadItem.customFileNameTemplate = downloadItem.customFileNameTemplate.applyFilenameTemplateForCuts()
|
||||||
|
}else{
|
||||||
|
downloadItem.customFileNameTemplate = sharedPreferences.getString("file_name_template", "%(uploader).30B - %(title).170B")!!
|
||||||
|
}
|
||||||
},
|
},
|
||||||
filenameTemplateSet = {
|
filenameTemplateSet = {
|
||||||
downloadItem.customFileNameTemplate = it
|
downloadItem.customFileNameTemplate = it
|
||||||
|
|
@ -420,6 +427,12 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
||||||
|
|
||||||
val bottomSheetDialog = AddExtraCommandsDialog(downloadItem, callback)
|
val bottomSheetDialog = AddExtraCommandsDialog(downloadItem, callback)
|
||||||
bottomSheetDialog.show(parentFragmentManager, "extraCommands")
|
bottomSheetDialog.show(parentFragmentManager, "extraCommands")
|
||||||
|
},
|
||||||
|
liveFromStart = {
|
||||||
|
downloadItem.videoPreferences.liveFromStart = it
|
||||||
|
},
|
||||||
|
waitForVideo = { wait, value ->
|
||||||
|
downloadItem.videoPreferences.waitForVideoMinutes = if (wait) value else 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -563,4 +563,13 @@ object Extensions {
|
||||||
fun DownloadItem.needsDataUpdating() : Boolean {
|
fun DownloadItem.needsDataUpdating() : Boolean {
|
||||||
return this.title.isBlank() || this.author.isBlank() || this.thumb.isBlank()
|
return this.title.isBlank() || this.author.isBlank() || this.thumb.isBlank()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.applyFilenameTemplateForCuts() : String {
|
||||||
|
return if(this.isBlank()) {
|
||||||
|
"%(section_title&{} - |)s%(title).170B"
|
||||||
|
}else {
|
||||||
|
if(this.startsWith("%(section_title&{} - |)s")) this
|
||||||
|
else "%(section_title&{} - |)s$this"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +38,11 @@ class FormatUtil(private var context: Context) {
|
||||||
orderPreferences.remove("file_size")
|
orderPreferences.remove("file_size")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val preferContainerOverCodec = sharedPreferences.getBoolean("prefer_container_over_codec_audio", false)
|
||||||
|
if(preferContainerOverCodec) {
|
||||||
|
orderPreferences.remove("codec")
|
||||||
|
}
|
||||||
|
|
||||||
return orderPreferences
|
return orderPreferences
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -627,7 +627,7 @@ class NotificationUtil(var context: Context) {
|
||||||
.setContentTitle(resources.getString(R.string.updating_download_data))
|
.setContentTitle(resources.getString(R.string.updating_download_data))
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setCategory(Notification.CATEGORY_PROGRESS)
|
.setCategory(Notification.CATEGORY_PROGRESS)
|
||||||
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
.setSmallIcon(R.drawable.ic_launcher_foreground_large)
|
||||||
.setLargeIcon(
|
.setLargeIcon(
|
||||||
BitmapFactory.decodeResource(
|
BitmapFactory.decodeResource(
|
||||||
resources,
|
resources,
|
||||||
|
|
|
||||||
|
|
@ -1205,7 +1205,9 @@ object UiUtil {
|
||||||
removeAudioClicked: (Boolean) -> Unit,
|
removeAudioClicked: (Boolean) -> Unit,
|
||||||
recodeVideoClicked: (Boolean) -> Unit,
|
recodeVideoClicked: (Boolean) -> Unit,
|
||||||
alsoDownloadAsAudioClicked: (Boolean) -> Unit,
|
alsoDownloadAsAudioClicked: (Boolean) -> Unit,
|
||||||
extraCommandsClicked: () -> Unit
|
extraCommandsClicked: () -> Unit,
|
||||||
|
liveFromStart: (Boolean) -> Unit,
|
||||||
|
waitForVideo: (Boolean, Int) -> Unit,
|
||||||
){
|
){
|
||||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
|
|
@ -1343,6 +1345,64 @@ object UiUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val adjustLiveStream = view.findViewById<Chip>(R.id.adjust_live_stream)
|
||||||
|
if (items.size == 1) {
|
||||||
|
adjustLiveStream.setOnClickListener {
|
||||||
|
val adjustLiveStreamView = context.layoutInflater.inflate(R.layout.livestream_download_preferences_dialog, null)
|
||||||
|
val liveFromStartSwitch = adjustLiveStreamView.findViewById<MaterialSwitch>(R.id.live_from_start)
|
||||||
|
val waitForVideoSwitch = adjustLiveStreamView.findViewById<MaterialSwitch>(R.id.wait_for_video)
|
||||||
|
val waitForVideoSettings = adjustLiveStreamView.findViewById<View>(R.id.wait_for_video_settings)
|
||||||
|
|
||||||
|
val waitEveryNr = adjustLiveStreamView.findViewById<TextInputLayout>(R.id.every_nr).editText!!
|
||||||
|
|
||||||
|
val item = items.first()
|
||||||
|
|
||||||
|
item.videoPreferences.waitForVideoMinutes.apply {
|
||||||
|
if(this > 0) {
|
||||||
|
waitEveryNr.setText(this.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
waitEveryNr.doOnTextChanged { text, start, before, count ->
|
||||||
|
var number = 1
|
||||||
|
kotlin.runCatching {
|
||||||
|
number = Integer.parseInt(waitEveryNr.text.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForVideo(true, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
liveFromStartSwitch.setOnCheckedChangeListener { compoundButton, b ->
|
||||||
|
liveFromStart(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForVideoSwitch.setOnCheckedChangeListener { compoundButton, b ->
|
||||||
|
waitForVideoSettings.isVisible = b
|
||||||
|
|
||||||
|
var number = 1
|
||||||
|
kotlin.runCatching {
|
||||||
|
number = Integer.parseInt(waitEveryNr.text.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForVideo(b, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
liveFromStartSwitch.isChecked = item.videoPreferences.liveFromStart
|
||||||
|
waitForVideoSwitch.isChecked = item.videoPreferences.waitForVideoMinutes > 0
|
||||||
|
waitForVideoSettings.isVisible = waitForVideoSwitch.isChecked
|
||||||
|
|
||||||
|
val adjustLiveStreamDialog = MaterialAlertDialogBuilder(context)
|
||||||
|
.setTitle(context.getString(R.string.live_stream))
|
||||||
|
.setView(adjustLiveStreamView)
|
||||||
|
.setIcon(R.drawable.baseline_live_tv_24)
|
||||||
|
.setNegativeButton(context.resources.getString(R.string.dismiss)) { _: DialogInterface?, _: Int -> }
|
||||||
|
|
||||||
|
adjustLiveStreamDialog.show()
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
adjustLiveStream.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
val recodeVideo = view.findViewById<Chip>(R.id.recode_video)
|
val recodeVideo = view.findViewById<Chip>(R.id.recode_video)
|
||||||
recodeVideo.isChecked = items.all { it.videoPreferences.recodeVideo }
|
recodeVideo.isChecked = items.all { it.videoPreferences.recodeVideo }
|
||||||
recodeVideo.setOnCheckedChangeListener { _, _ ->
|
recodeVideo.setOnCheckedChangeListener { _, _ ->
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class YTDLPUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
addOption("-P", FileUtil.getCachePath(context) + "/tmp")
|
addOption("-P", FileUtil.getCachePath(context) + "/tmp")
|
||||||
|
|
||||||
if (sharedPreferences.getBoolean("no_check_certificates", true)) {
|
if (sharedPreferences.getBoolean("no_check_certificates", false)) {
|
||||||
addOption("--no-check-certificates")
|
addOption("--no-check-certificates")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -594,7 +594,9 @@ class YTDLPUtil(private val context: Context) {
|
||||||
|
|
||||||
val downDir : File
|
val downDir : File
|
||||||
val canWrite = File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite()
|
val canWrite = File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite()
|
||||||
if (!sharedPreferences.getBoolean("cache_downloads", true) && canWrite){
|
val writtenPath = type == DownloadViewModel.Type.command && downloadItem.format.format_note.contains("-P ")
|
||||||
|
|
||||||
|
if (writtenPath || (!sharedPreferences.getBoolean("cache_downloads", true) && canWrite)){
|
||||||
downDir = File(FileUtil.formatPath(downloadItem.downloadPath))
|
downDir = File(FileUtil.formatPath(downloadItem.downloadPath))
|
||||||
request.addOption("--no-quiet")
|
request.addOption("--no-quiet")
|
||||||
request.addOption("--no-simulate")
|
request.addOption("--no-simulate")
|
||||||
|
|
@ -648,7 +650,7 @@ class YTDLPUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedPreferences.getBoolean("no_check_certificates", true)) {
|
if (sharedPreferences.getBoolean("no_check_certificates", false)) {
|
||||||
request.addOption("--no-check-certificates")
|
request.addOption("--no-check-certificates")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -671,7 +673,7 @@ class YTDLPUtil(private val context: Context) {
|
||||||
request.addOption("--no-part")
|
request.addOption("--no-part")
|
||||||
}
|
}
|
||||||
|
|
||||||
request.addOption("--trim-filenames", 254 - downDir.absolutePath.length)
|
request.addOption("--trim-filenames", 254/* - downDir.absolutePath.length*/)
|
||||||
|
|
||||||
if (downloadItem.SaveThumb) {
|
if (downloadItem.SaveThumb) {
|
||||||
request.addOption("--write-thumbnail")
|
request.addOption("--write-thumbnail")
|
||||||
|
|
@ -705,13 +707,13 @@ class YTDLPUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(downloadItem.title.isNotBlank()){
|
if(downloadItem.title.isNotBlank()){
|
||||||
metadataCommands.addOption("--replace-in-metadata", "title", ".+", downloadItem.title.take(180))
|
metadataCommands.addOption("--replace-in-metadata", "title", ".+", downloadItem.title)
|
||||||
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.take(30))
|
metadataCommands.addOption("--replace-in-metadata", "uploader", ".+", downloadItem.author)
|
||||||
metadataCommands.addOption("--parse-metadata", "%(uploader)s:%(artist)s")
|
metadataCommands.addOption("--parse-metadata", "%(uploader)s:%(artist)s")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -724,11 +726,7 @@ class YTDLPUtil(private val context: Context) {
|
||||||
request.addOption("--force-keyframes-at-cuts")
|
request.addOption("--force-keyframes-at-cuts")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filenameTemplate = if (filenameTemplate.isBlank()){
|
|
||||||
"%(section_title&{} |)s%(title).170B"
|
|
||||||
}else{
|
|
||||||
"%(section_title&{} |)s $filenameTemplate"
|
|
||||||
}
|
|
||||||
if (downloadItem.downloadSections.split(";").size > 1){
|
if (downloadItem.downloadSections.split(";").size > 1){
|
||||||
filenameTemplate = "%(autonumber)d. $filenameTemplate [%(section_start>%H∶%M∶%S)s]"
|
filenameTemplate = "%(autonumber)d. $filenameTemplate [%(section_start>%H∶%M∶%S)s]"
|
||||||
}
|
}
|
||||||
|
|
@ -806,35 +804,53 @@ class YTDLPUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
request.addOption("-x")
|
request.addOption("-x")
|
||||||
|
|
||||||
val formatSorting = StringBuilder("hasaud")
|
val formatSorting = mutableListOf("hasaud")
|
||||||
|
val formatImportance = formatUtil.getAudioFormatImportance()
|
||||||
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "wa" || downloadItem.format.format_id == "worst") {
|
for(order in formatImportance) {
|
||||||
formatSorting.append(",+br,+res,+fps")
|
when(order) {
|
||||||
}
|
"file_size" -> {
|
||||||
|
formatSorting.add("size")
|
||||||
if (abrSort.isNotBlank()){
|
}
|
||||||
formatSorting.append(",abr:${abrSort}")
|
"language" -> {
|
||||||
}
|
if (preferredLanguage.isNotBlank()) {
|
||||||
|
formatSorting.add("lang:${preferredLanguage}")
|
||||||
formatSorting.append(",size")
|
}
|
||||||
|
}
|
||||||
if (aCodecPref.isNotBlank()){
|
"codec" -> {
|
||||||
formatSorting.append(",acodec:$aCodecPref")
|
if (aCodecPref.isNotBlank()){
|
||||||
}
|
formatSorting.add("acodec:$aCodecPref")
|
||||||
|
}
|
||||||
if(ext.isNotBlank()){
|
}
|
||||||
if(!ext.matches("(webm)|(Default)|(${context.getString(R.string.defaultValue)})".toRegex()) && supportedContainers.contains(ext)){
|
"container" -> {
|
||||||
request.addOption("--audio-format", ext)
|
if(ext.isNotBlank()){
|
||||||
formatSorting.append(",aext:$ext")
|
if(!ext.matches("(webm)|(Default)|(${context.getString(R.string.defaultValue)})".toRegex()) && supportedContainers.contains(ext)){
|
||||||
|
request.addOption("--audio-format", ext)
|
||||||
|
formatSorting.add("aext:$ext")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferredLanguage.isNotBlank()) {
|
|
||||||
formatSorting.append(",lang:${preferredLanguage}")
|
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "wa" || downloadItem.format.format_id == "worst") {
|
||||||
|
if(formatSorting.contains("size")) {
|
||||||
|
formatSorting.remove("size")
|
||||||
|
}
|
||||||
|
formatSorting.addAll(0,listOf("+br", "+res", "+fps"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abrSort.isNotBlank()){
|
||||||
|
formatSorting.add(0, "abr:${abrSort}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(formatSorting.isNotEmpty()) {
|
||||||
|
request.addOption("-S", formatSorting.joinToString(","))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
request.addOption("-P", downDir.absolutePath)
|
request.addOption("-P", downDir.absolutePath)
|
||||||
request.addOption("-S", formatSorting.toString())
|
|
||||||
|
|
||||||
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
|
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
|
||||||
if (downloadItem.author.isBlank()) {
|
if (downloadItem.author.isBlank()) {
|
||||||
|
|
@ -868,7 +884,7 @@ class YTDLPUtil(private val context: Context) {
|
||||||
|
|
||||||
|
|
||||||
metadataCommands.addOption("--parse-metadata", "%(album_artist,first_artist|)s:%(album_artist)s")
|
metadataCommands.addOption("--parse-metadata", "%(album_artist,first_artist|)s:%(album_artist)s")
|
||||||
metadataCommands.addOption("--parse-metadata", "description:(?:.+?Released\\ on\\s*(?P<dscrptn_year>\\d{4}))?")
|
metadataCommands.addOption("--parse-metadata", "description:(?:.+?Released\\ on\\s*:\\s*(?P<dscrptn_year>\\d{4}))?")
|
||||||
metadataCommands.addOption("--parse-metadata", "%(dscrptn_year,release_year,release_date>%Y,upload_date>%Y)s:(?P<meta_date>\\d+)")
|
metadataCommands.addOption("--parse-metadata", "%(dscrptn_year,release_year,release_date>%Y,upload_date>%Y)s:(?P<meta_date>\\d+)")
|
||||||
|
|
||||||
if (isPlaylistItem) {
|
if (isPlaylistItem) {
|
||||||
|
|
@ -1077,24 +1093,52 @@ class YTDLPUtil(private val context: Context) {
|
||||||
|
|
||||||
val preferredLanguage = sharedPreferences.getString("audio_language","")!!
|
val preferredLanguage = sharedPreferences.getString("audio_language","")!!
|
||||||
|
|
||||||
StringBuilder().apply {
|
val formatImportance = formatUtil.getVideoFormatImportance()
|
||||||
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "worst") {
|
val formatSorting = mutableListOf<String>()
|
||||||
append(",+br,+res,+fps")
|
|
||||||
}else if (hasGenericResulutionFormat.isNotBlank()) {
|
for(order in formatImportance) {
|
||||||
append(",res:${hasGenericResulutionFormat}")
|
when(order) {
|
||||||
}
|
"no_audio" -> {
|
||||||
if (sharedPreferences.getBoolean("prefer_smaller_formats", false)) append(",+size")
|
formatSorting.add("+hasaud")
|
||||||
if (vCodecPref.isNotBlank()) append(",vcodec:$vCodecPref")
|
}
|
||||||
if (aCodecPref.isNotBlank()) append(",acodec:$aCodecPref")
|
"codec" -> {
|
||||||
if (cont.isNotBlank()) append(",vext:$cont")
|
if (vCodecPref.isNotBlank()) formatSorting.add("vcodec:$vCodecPref")
|
||||||
if (acont.isNotBlank()) append(",aext:$acont")
|
if (aCodecPref.isNotBlank()) formatSorting.add("acodec:$aCodecPref")
|
||||||
if (abrSort.isNotBlank()) append(",abr~${abrSort}")
|
}
|
||||||
if (preferredLanguage.isNotBlank()) append(",lang:${preferredLanguage}")
|
"resolution" -> {
|
||||||
if (this.isNotBlank()){
|
if (hasGenericResulutionFormat.isNotBlank()) {
|
||||||
request.addOption("-S", "+hasaud$this")
|
formatSorting.add("res:${hasGenericResulutionFormat}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"container" -> {
|
||||||
|
if (cont.isNotBlank()) formatSorting.add("vext:$cont")
|
||||||
|
if (acont.isNotBlank()) formatSorting.add("aext:$acont")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "worst") {
|
||||||
|
formatSorting.addAll(0, listOf("+br","+res","+fps"))
|
||||||
|
}else {
|
||||||
|
if (sharedPreferences.getBoolean("prefer_smaller_formats", false)) {
|
||||||
|
formatSorting.add(0, "+size")
|
||||||
|
}else {
|
||||||
|
formatSorting.add(0, "size")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (abrSort.isNotBlank()) {
|
||||||
|
formatSorting.add("abr~${abrSort}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preferredLanguage.isNotBlank()) {
|
||||||
|
formatSorting.add("lang:${preferredLanguage}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatSorting.isNotEmpty()) {
|
||||||
|
request.addOption("-S", formatSorting.joinToString(","))
|
||||||
|
}
|
||||||
|
|
||||||
request.addOption("-f", f.toString().replace("/$".toRegex(), ""))
|
request.addOption("-f", f.toString().replace("/$".toRegex(), ""))
|
||||||
|
|
||||||
|
|
@ -1138,9 +1182,22 @@ class YTDLPUtil(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloadItem.videoPreferences.liveFromStart) {
|
||||||
|
request.addOption("--live-from-start")
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadItem.videoPreferences.waitForVideoMinutes.apply {
|
||||||
|
if (this > 0) {
|
||||||
|
request.addOption("--wait-for-video", this * 60)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
DownloadViewModel.Type.command -> {
|
DownloadViewModel.Type.command -> {
|
||||||
request.addOption("-P", downDir.absolutePath)
|
if (!writtenPath) {
|
||||||
|
request.addOption("-P", downDir.absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
request.addOption(
|
request.addOption(
|
||||||
"--config-locations",
|
"--config-locations",
|
||||||
File(context.cacheDir.absolutePath + "/config[${downloadItem.id}].txt").apply {
|
File(context.cacheDir.absolutePath + "/config[${downloadItem.id}].txt").apply {
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,8 @@ class DownloadWorker(
|
||||||
notificationUtil.notify(downloadItem.id.toInt(), notification)
|
notificationUtil.notify(downloadItem.id.toInt(), notification)
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val noCache = !sharedPreferences.getBoolean("cache_downloads", true) && File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite()
|
val writtenPath = downloadItem.format.format_note.contains("-P ")
|
||||||
|
val noCache = writtenPath || (!sharedPreferences.getBoolean("cache_downloads", true) && File(FileUtil.formatPath(downloadItem.downloadPath)).canWrite())
|
||||||
|
|
||||||
val request = ytdlpUtil.buildYoutubeDLRequest(downloadItem)
|
val request = ytdlpUtil.buildYoutubeDLRequest(downloadItem)
|
||||||
downloadItem.status = DownloadRepository.Status.Active.toString()
|
downloadItem.status = DownloadRepository.Status.Active.toString()
|
||||||
|
|
|
||||||
|
|
@ -82,15 +82,22 @@ class TerminalDownloadWorker(
|
||||||
}
|
}
|
||||||
|
|
||||||
val commandPath = sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
|
val commandPath = sharedPreferences.getString("command_path", FileUtil.getDefaultCommandPath())!!
|
||||||
val noCache = !sharedPreferences.getBoolean("cache_downloads", true) && File(FileUtil.formatPath(commandPath)).canWrite()
|
var noCache = !sharedPreferences.getBoolean("cache_downloads", true) && File(FileUtil.formatPath(commandPath)).canWrite()
|
||||||
|
|
||||||
if (!noCache){
|
if (command.contains("-P ")) {
|
||||||
request.addOption("-P", FileUtil.getCachePath(context) + "TERMINAL/" + itemId)
|
noCache = true
|
||||||
}else if (!request.hasOption("-P")){
|
}else {
|
||||||
request.addOption("-P", FileUtil.formatPath(commandPath))
|
if (!noCache){
|
||||||
|
request.addOption("-P", FileUtil.getCachePath(context) + "TERMINAL/" + itemId)
|
||||||
|
}else if (!request.hasOption("-P")){
|
||||||
|
request.addOption("-P", FileUtil.formatPath(commandPath))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false)
|
val logDownloads = sharedPreferences.getBoolean("log_downloads", false) && !sharedPreferences.getBoolean("incognito", false)
|
||||||
|
|
||||||
val initialLogDetails = "Terminal Task\n" +
|
val initialLogDetails = "Terminal Task\n" +
|
||||||
|
|
|
||||||
5
app/src/main/res/drawable/baseline_live_tv_24.xml
Normal file
5
app/src/main/res/drawable/baseline_live_tv_24.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="?attr/colorAccent" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M21,6h-7.59l3.29,-3.29L16,2l-4,4 -4,-4 -0.71,0.71L10.59,6L3,6c-1.1,0 -2,0.89 -2,2v12c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,8c0,-1.11 -0.9,-2 -2,-2zM21,20L3,20L3,8h18v12zM9,10v8l7,-4z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
|
|
@ -110,12 +110,19 @@
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<com.google.android.material.chip.Chip
|
||||||
android:id="@+id/recode_video"
|
android:id="@+id/adjust_live_stream"
|
||||||
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/recode_video" />
|
android:text="@string/live_stream"
|
||||||
|
app:chipIconVisible="true"
|
||||||
|
app:chipIcon="@drawable/baseline_live_tv_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.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
|
|
@ -162,6 +169,14 @@
|
||||||
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/recode_video"
|
||||||
|
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="false"
|
||||||
|
android:text="@string/recode_video" />
|
||||||
|
|
||||||
</com.google.android.material.chip.ChipGroup>
|
</com.google.android.material.chip.ChipGroup>
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
android:id="@+id/filename_edittext"
|
android:id="@+id/filename_edittext"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="text" />
|
android:inputType="text|textMultiLine" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/live_from_start"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/live_from_start" />
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/wait_for_video"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:text="@string/wait_for_video"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:weightSum="5"
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:id="@+id/wait_for_video_settings"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/retries"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="10dp"
|
||||||
|
android:text="@string/retry_every"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/every_nr"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/every_nr"
|
||||||
|
style="@style/Widget.Material3.TextInputLayout.FilledBox.Dense"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/textView8">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number"
|
||||||
|
android:padding="15dp"
|
||||||
|
android:text="1"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView8"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="10dp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="@string/minutes"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -444,4 +444,11 @@
|
||||||
<string name="ytdlp_liked">YT-DLP Youtube Liked Videos (needs cookies)</string>
|
<string name="ytdlp_liked">YT-DLP Youtube Liked Videos (needs cookies)</string>
|
||||||
<string name="ytdlp_watch_history">YT-DLP Youtube Watch History (needs cookies)</string>
|
<string name="ytdlp_watch_history">YT-DLP Youtube Watch History (needs cookies)</string>
|
||||||
<string name="no_check_certificates">Suppress HTTPS certificate validation</string>
|
<string name="no_check_certificates">Suppress HTTPS certificate validation</string>
|
||||||
|
<string name="live_stream">Live Stream</string>
|
||||||
|
<string name="live_from_start">Live From Start</string>
|
||||||
|
<string name="wait_for_video">Wait For Video</string>
|
||||||
|
<string name="retry_every">Retry Every</string>
|
||||||
|
<string name="minutes">Minutes</string>
|
||||||
|
<string name="prefer_container_over_codec_audio">Prefer Container over Codec For Audio Downloads</string>
|
||||||
|
<string name="prefer_container_over_codec_audio_summary">With this enabled, the preferred audio codec preference will be ignored and only container will change</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
app:defaultValue="true"
|
app:defaultValue="false"
|
||||||
android:icon="@drawable/baseline_note_24"
|
android:icon="@drawable/baseline_note_24"
|
||||||
android:key="no_check_certificates"
|
android:key="no_check_certificates"
|
||||||
app:title="@string/no_check_certificates" />
|
app:title="@string/no_check_certificates" />
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,65 @@
|
||||||
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
|
||||||
|
app:icon="@drawable/ic_language"
|
||||||
|
app:dialogTitle="@string/preferred_audio_language"
|
||||||
|
app:entries="@array/language_names"
|
||||||
|
app:entryValues="@array/language_codes"
|
||||||
|
app:key="audio_language"
|
||||||
|
app:useSimpleSummaryProvider="true"
|
||||||
|
app:title="@string/preferred_audio_language" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:defaultValue=""
|
||||||
|
android:entries="@array/audio_codec"
|
||||||
|
android:entryValues="@array/audio_codec_values"
|
||||||
|
android:icon="@drawable/ic_code"
|
||||||
|
app:useSimpleSummaryProvider="true"
|
||||||
|
app:key="audio_codec"
|
||||||
|
app:title="@string/preferred_audio_codec" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
|
app:defaultValue="false"
|
||||||
|
app:icon="@drawable/ic_format"
|
||||||
|
app:key="prefer_container_over_codec_audio"
|
||||||
|
android:summary="@string/prefer_container_over_codec_audio_summary"
|
||||||
|
app:title="@string/prefer_container_over_codec_audio" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:defaultValue=""
|
||||||
|
android:entries="@array/audio_containers"
|
||||||
|
android:entryValues="@array/audio_containers_values"
|
||||||
|
android:icon="@drawable/ic_code"
|
||||||
|
app:key="audio_format"
|
||||||
|
app:useSimpleSummaryProvider="true"
|
||||||
|
app:title="@string/audio_format" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
app:key="format_id_audio"
|
||||||
|
app:defaultValue=""
|
||||||
|
app:icon="@drawable/ic_format_id"
|
||||||
|
app:summary="@string/preferred_format_id_summary"
|
||||||
|
app:title="@string/preferred_format_id" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -167,17 +226,8 @@
|
||||||
app:key="add_chapters"
|
app:key="add_chapters"
|
||||||
app:summary="@string/add_chapters_summary"
|
app:summary="@string/add_chapters_summary"
|
||||||
app:title="@string/add_chapters" />
|
app:title="@string/add_chapters" />
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/format">
|
|
||||||
<ListPreference
|
|
||||||
android:defaultValue=""
|
|
||||||
android:entries="@array/audio_containers"
|
|
||||||
android:entryValues="@array/audio_containers_values"
|
|
||||||
android:icon="@drawable/ic_code"
|
|
||||||
app:key="audio_format"
|
|
||||||
app:useSimpleSummaryProvider="true"
|
|
||||||
app:title="@string/audio_format" />
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:defaultValue=""
|
android:defaultValue=""
|
||||||
|
|
@ -206,41 +256,7 @@
|
||||||
app:key="video_codec"
|
app:key="video_codec"
|
||||||
app:title="@string/preferred_video_codec" />
|
app:title="@string/preferred_video_codec" />
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
android:defaultValue=""
|
|
||||||
android:entries="@array/audio_codec"
|
|
||||||
android:entryValues="@array/audio_codec_values"
|
|
||||||
android:icon="@drawable/ic_code"
|
|
||||||
app:useSimpleSummaryProvider="true"
|
|
||||||
app:key="audio_codec"
|
|
||||||
app:title="@string/preferred_audio_codec" />
|
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
app:icon="@drawable/ic_language"
|
|
||||||
app:dialogTitle="@string/preferred_audio_language"
|
|
||||||
app:entries="@array/language_names"
|
|
||||||
app:entryValues="@array/language_codes"
|
|
||||||
app:key="audio_language"
|
|
||||||
app:useSimpleSummaryProvider="true"
|
|
||||||
app:title="@string/preferred_audio_language" />
|
|
||||||
|
|
||||||
<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
|
||||||
android:defaultValue="best"
|
android:defaultValue="best"
|
||||||
|
|
@ -258,12 +274,9 @@
|
||||||
app:summary="@string/preferred_format_id_summary"
|
app:summary="@string/preferred_format_id_summary"
|
||||||
app:title="@string/preferred_format_id" />
|
app:title="@string/preferred_format_id" />
|
||||||
|
|
||||||
<EditTextPreference
|
</PreferenceCategory>
|
||||||
app:key="format_id_audio"
|
|
||||||
app:defaultValue=""
|
<PreferenceCategory android:title="@string/format">
|
||||||
app:icon="@drawable/ic_format_id"
|
|
||||||
app:summary="@string/preferred_format_id_summary"
|
|
||||||
app:title="@string/preferred_format_id" />
|
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:widgetLayout="@layout/preferece_material_switch"
|
android:widgetLayout="@layout/preferece_material_switch"
|
||||||
|
|
@ -274,12 +287,12 @@
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:icon="@drawable/ic_format"
|
android:icon="@drawable/ic_format"
|
||||||
android:key="format_importance_audio"
|
android:key="format_importance_video"
|
||||||
app:title="@string/format_importance" />
|
app:title="@string/format_importance" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:icon="@drawable/ic_format"
|
android:icon="@drawable/ic_format"
|
||||||
android:key="format_importance_video"
|
android:key="format_importance_audio"
|
||||||
app:title="@string/format_importance" />
|
app:title="@string/format_importance" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue