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 versionMajor = 1
|
||||
def versionMinor = 8
|
||||
def versionPatch = 1
|
||||
def versionBuild = 2 // bump for dogfood builds, public betas, etc.
|
||||
def versionPatch = 2
|
||||
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
|
||||
def isBeta = false
|
||||
|
||||
def versionExt = ""
|
||||
|
|
|
|||
|
|
@ -15,5 +15,7 @@ data class VideoPreferences (
|
|||
var audioFormatIDs : ArrayList<String> = arrayListOf(),
|
||||
var removeAudio: Boolean = false,
|
||||
var alsoDownloadAsAudio: Boolean = false,
|
||||
var recodeVideo: Boolean = false
|
||||
var recodeVideo: Boolean = false,
|
||||
var liveFromStart: Boolean = false,
|
||||
var waitForVideoMinutes: Int = 0
|
||||
) : 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.Type
|
||||
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.FormatUtil
|
||||
import com.deniscerri.ytdl.util.UiUtil
|
||||
|
|
@ -335,6 +336,13 @@ class DownloadAudioFragment(private var resultItem: ResultItem? = null, private
|
|||
cutValueChanged = {
|
||||
downloadItem.downloadSections = it
|
||||
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 = {
|
||||
val callback = object : ExtraCommandsListener {
|
||||
|
|
|
|||
|
|
@ -692,7 +692,9 @@ class DownloadMultipleBottomSheetDialog : BottomSheetDialogFragment(), Configure
|
|||
|
||||
val bottomSheetDialog = AddExtraCommandsDialog(null, callback)
|
||||
bottomSheetDialog.show(parentFragmentManager, "extraCommands")
|
||||
}
|
||||
},
|
||||
waitForVideo = {b, i -> },
|
||||
liveFromStart = {}
|
||||
)
|
||||
|
||||
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.Type
|
||||
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.FormatUtil
|
||||
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) },
|
||||
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 = {
|
||||
downloadItem.customFileNameTemplate = it
|
||||
|
|
@ -420,6 +427,12 @@ class DownloadVideoFragment(private var resultItem: ResultItem? = null, private
|
|||
|
||||
val bottomSheetDialog = AddExtraCommandsDialog(downloadItem, callback)
|
||||
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 {
|
||||
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")
|
||||
}
|
||||
|
||||
val preferContainerOverCodec = sharedPreferences.getBoolean("prefer_container_over_codec_audio", false)
|
||||
if(preferContainerOverCodec) {
|
||||
orderPreferences.remove("codec")
|
||||
}
|
||||
|
||||
return orderPreferences
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ class NotificationUtil(var context: Context) {
|
|||
.setContentTitle(resources.getString(R.string.updating_download_data))
|
||||
.setOngoing(true)
|
||||
.setCategory(Notification.CATEGORY_PROGRESS)
|
||||
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||
.setSmallIcon(R.drawable.ic_launcher_foreground_large)
|
||||
.setLargeIcon(
|
||||
BitmapFactory.decodeResource(
|
||||
resources,
|
||||
|
|
|
|||
|
|
@ -1205,7 +1205,9 @@ object UiUtil {
|
|||
removeAudioClicked: (Boolean) -> Unit,
|
||||
recodeVideoClicked: (Boolean) -> Unit,
|
||||
alsoDownloadAsAudioClicked: (Boolean) -> Unit,
|
||||
extraCommandsClicked: () -> Unit
|
||||
extraCommandsClicked: () -> Unit,
|
||||
liveFromStart: (Boolean) -> Unit,
|
||||
waitForVideo: (Boolean, Int) -> Unit,
|
||||
){
|
||||
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)
|
||||
recodeVideo.isChecked = items.all { it.videoPreferences.recodeVideo }
|
||||
recodeVideo.setOnCheckedChangeListener { _, _ ->
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class YTDLPUtil(private val context: Context) {
|
|||
}
|
||||
addOption("-P", FileUtil.getCachePath(context) + "/tmp")
|
||||
|
||||
if (sharedPreferences.getBoolean("no_check_certificates", true)) {
|
||||
if (sharedPreferences.getBoolean("no_check_certificates", false)) {
|
||||
addOption("--no-check-certificates")
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +594,9 @@ class YTDLPUtil(private val context: Context) {
|
|||
|
||||
val downDir : File
|
||||
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))
|
||||
request.addOption("--no-quiet")
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
@ -671,7 +673,7 @@ class YTDLPUtil(private val context: Context) {
|
|||
request.addOption("--no-part")
|
||||
}
|
||||
|
||||
request.addOption("--trim-filenames", 254 - downDir.absolutePath.length)
|
||||
request.addOption("--trim-filenames", 254/* - downDir.absolutePath.length*/)
|
||||
|
||||
if (downloadItem.SaveThumb) {
|
||||
request.addOption("--write-thumbnail")
|
||||
|
|
@ -705,13 +707,13 @@ class YTDLPUtil(private val context: Context) {
|
|||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
@ -724,11 +726,7 @@ class YTDLPUtil(private val context: Context) {
|
|||
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){
|
||||
filenameTemplate = "%(autonumber)d. $filenameTemplate [%(section_start>%H∶%M∶%S)s]"
|
||||
}
|
||||
|
|
@ -806,35 +804,53 @@ class YTDLPUtil(private val context: Context) {
|
|||
}
|
||||
request.addOption("-x")
|
||||
|
||||
val formatSorting = StringBuilder("hasaud")
|
||||
|
||||
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "wa" || downloadItem.format.format_id == "worst") {
|
||||
formatSorting.append(",+br,+res,+fps")
|
||||
}
|
||||
|
||||
if (abrSort.isNotBlank()){
|
||||
formatSorting.append(",abr:${abrSort}")
|
||||
}
|
||||
|
||||
formatSorting.append(",size")
|
||||
|
||||
if (aCodecPref.isNotBlank()){
|
||||
formatSorting.append(",acodec:$aCodecPref")
|
||||
}
|
||||
|
||||
if(ext.isNotBlank()){
|
||||
if(!ext.matches("(webm)|(Default)|(${context.getString(R.string.defaultValue)})".toRegex()) && supportedContainers.contains(ext)){
|
||||
request.addOption("--audio-format", ext)
|
||||
formatSorting.append(",aext:$ext")
|
||||
val formatSorting = mutableListOf("hasaud")
|
||||
val formatImportance = formatUtil.getAudioFormatImportance()
|
||||
for(order in formatImportance) {
|
||||
when(order) {
|
||||
"file_size" -> {
|
||||
formatSorting.add("size")
|
||||
}
|
||||
"language" -> {
|
||||
if (preferredLanguage.isNotBlank()) {
|
||||
formatSorting.add("lang:${preferredLanguage}")
|
||||
}
|
||||
}
|
||||
"codec" -> {
|
||||
if (aCodecPref.isNotBlank()){
|
||||
formatSorting.add("acodec:$aCodecPref")
|
||||
}
|
||||
}
|
||||
"container" -> {
|
||||
if(ext.isNotBlank()){
|
||||
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("-S", formatSorting.toString())
|
||||
|
||||
|
||||
val useArtistTags = if (downloadItem.url.isYoutubeURL()) "artists,artist," else ""
|
||||
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", "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+)")
|
||||
|
||||
if (isPlaylistItem) {
|
||||
|
|
@ -1077,24 +1093,52 @@ class YTDLPUtil(private val context: Context) {
|
|||
|
||||
val preferredLanguage = sharedPreferences.getString("audio_language","")!!
|
||||
|
||||
StringBuilder().apply {
|
||||
if (downloadItem.format.format_id == context.resources.getString(R.string.worst_quality) || downloadItem.format.format_id == "worst") {
|
||||
append(",+br,+res,+fps")
|
||||
}else if (hasGenericResulutionFormat.isNotBlank()) {
|
||||
append(",res:${hasGenericResulutionFormat}")
|
||||
}
|
||||
if (sharedPreferences.getBoolean("prefer_smaller_formats", false)) append(",+size")
|
||||
if (vCodecPref.isNotBlank()) append(",vcodec:$vCodecPref")
|
||||
if (aCodecPref.isNotBlank()) append(",acodec:$aCodecPref")
|
||||
if (cont.isNotBlank()) append(",vext:$cont")
|
||||
if (acont.isNotBlank()) append(",aext:$acont")
|
||||
if (abrSort.isNotBlank()) append(",abr~${abrSort}")
|
||||
if (preferredLanguage.isNotBlank()) append(",lang:${preferredLanguage}")
|
||||
if (this.isNotBlank()){
|
||||
request.addOption("-S", "+hasaud$this")
|
||||
val formatImportance = formatUtil.getVideoFormatImportance()
|
||||
val formatSorting = mutableListOf<String>()
|
||||
|
||||
for(order in formatImportance) {
|
||||
when(order) {
|
||||
"no_audio" -> {
|
||||
formatSorting.add("+hasaud")
|
||||
}
|
||||
"codec" -> {
|
||||
if (vCodecPref.isNotBlank()) formatSorting.add("vcodec:$vCodecPref")
|
||||
if (aCodecPref.isNotBlank()) formatSorting.add("acodec:$aCodecPref")
|
||||
}
|
||||
"resolution" -> {
|
||||
if (hasGenericResulutionFormat.isNotBlank()) {
|
||||
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(), ""))
|
||||
|
||||
|
|
@ -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 -> {
|
||||
request.addOption("-P", downDir.absolutePath)
|
||||
if (!writtenPath) {
|
||||
request.addOption("-P", downDir.absolutePath)
|
||||
}
|
||||
|
||||
request.addOption(
|
||||
"--config-locations",
|
||||
File(context.cacheDir.absolutePath + "/config[${downloadItem.id}].txt").apply {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ class DownloadWorker(
|
|||
notificationUtil.notify(downloadItem.id.toInt(), notification)
|
||||
|
||||
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)
|
||||
downloadItem.status = DownloadRepository.Status.Active.toString()
|
||||
|
|
|
|||
|
|
@ -82,15 +82,22 @@ class TerminalDownloadWorker(
|
|||
}
|
||||
|
||||
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){
|
||||
request.addOption("-P", FileUtil.getCachePath(context) + "TERMINAL/" + itemId)
|
||||
}else if (!request.hasOption("-P")){
|
||||
request.addOption("-P", FileUtil.formatPath(commandPath))
|
||||
if (command.contains("-P ")) {
|
||||
noCache = true
|
||||
}else {
|
||||
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 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" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/recode_video"
|
||||
style="@style/Widget.Material3.Chip.Filter.Elevated"
|
||||
android:id="@+id/adjust_live_stream"
|
||||
style="@style/Widget.Material3.Chip.Assist.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="@string/recode_video" />
|
||||
android:gravity="center"
|
||||
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>
|
||||
|
|
@ -162,6 +169,14 @@
|
|||
app:layout_constraintStart_toStartOf="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>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
android:id="@+id/filename_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text" />
|
||||
android:inputType="text|textMultiLine" />
|
||||
|
||||
</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_watch_history">YT-DLP Youtube Watch History (needs cookies)</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>
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
<SwitchPreferenceCompat
|
||||
android:widgetLayout="@layout/preferece_material_switch"
|
||||
app:defaultValue="true"
|
||||
app:defaultValue="false"
|
||||
android:icon="@drawable/baseline_note_24"
|
||||
android:key="no_check_certificates"
|
||||
app:title="@string/no_check_certificates" />
|
||||
|
|
|
|||
|
|
@ -98,6 +98,65 @@
|
|||
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"
|
||||
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>
|
||||
|
||||
|
||||
|
|
@ -167,17 +226,8 @@
|
|||
app:key="add_chapters"
|
||||
app:summary="@string/add_chapters_summary"
|
||||
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
|
||||
android:defaultValue=""
|
||||
|
|
@ -206,41 +256,7 @@
|
|||
app:key="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
|
||||
android:defaultValue="best"
|
||||
|
|
@ -258,12 +274,9 @@
|
|||
app:summary="@string/preferred_format_id_summary"
|
||||
app:title="@string/preferred_format_id" />
|
||||
|
||||
<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 android:title="@string/format">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:widgetLayout="@layout/preferece_material_switch"
|
||||
|
|
@ -274,12 +287,12 @@
|
|||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_format"
|
||||
android:key="format_importance_audio"
|
||||
android:key="format_importance_video"
|
||||
app:title="@string/format_importance" />
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_format"
|
||||
android:key="format_importance_video"
|
||||
android:key="format_importance_audio"
|
||||
app:title="@string/format_importance" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
|
|
|||
Loading…
Reference in a new issue