diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/models/VideoPreferences.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/models/VideoPreferences.kt index 6893581e..2fbe7a4d 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/models/VideoPreferences.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/models/VideoPreferences.kt @@ -4,5 +4,7 @@ data class VideoPreferences ( var embedSubs: Boolean = true, var addChapters: Boolean = true, var splitByChapters: Boolean = false, - var sponsorBlockFilters: ArrayList + var sponsorBlockFilters: ArrayList, + var writeSubs: Boolean = false, + var subsLanguages: String = "en.*,.*-orig" ) diff --git a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt index 9aebda3c..f8e7bf48 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/database/viewmodel/DownloadViewModel.kt @@ -108,6 +108,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application fun createDownloadItemFromResult(resultItem: ResultItem, type: Type) : DownloadItem { val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false) + val saveSubs = sharedPreferences.getBoolean("write_subtitles", false) val addChapters = sharedPreferences.getBoolean("add_chapters", false) val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false) val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false) @@ -122,7 +123,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet()) val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!)) - val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock)) + val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs) return DownloadItem(0, resultItem.url, @@ -150,6 +151,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application fun createDownloadItemFromHistory(historyItem: HistoryItem) : DownloadItem { val embedSubs = sharedPreferences.getBoolean("embed_subtitles", false) + val saveSubs = sharedPreferences.getBoolean("write_subtitles", false) val addChapters = sharedPreferences.getBoolean("add_chapters", false) val saveThumb = sharedPreferences.getBoolean("write_thumbnail", false) val embedThumb = sharedPreferences.getBoolean("embed_thumbnail", false) @@ -164,7 +166,7 @@ class DownloadViewModel(application: Application) : AndroidViewModel(application val sponsorblock = sharedPreferences.getStringSet("sponsorblock_filters", emptySet()) val audioPreferences = AudioPreferences(embedThumb, false, ArrayList(sponsorblock!!)) - val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock)) + val videoPreferences = VideoPreferences(embedSubs, addChapters, false, ArrayList(sponsorblock), saveSubs) return DownloadItem(0, historyItem.url, diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt index 2ed0765e..f2a25b2a 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/downloadcard/DownloadVideoFragment.kt @@ -1,19 +1,23 @@ package com.deniscerri.ytdlnis.ui.downloadcard import android.app.Activity -import android.content.ClipboardManager import android.content.DialogInterface import android.content.Intent +import android.net.Uri import android.os.Bundle import android.text.Editable import android.text.TextWatcher +import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager import android.widget.* import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.widget.doOnTextChanged import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -303,6 +307,60 @@ class DownloadVideoFragment(private val resultItem: ResultItem, private var curr } } + val saveSubtitles = view.findViewById(R.id.save_subtitles) + val subtitleLanguages = view.findViewById(R.id.subtitle_languages) + if (downloadItem.videoPreferences.writeSubs) { + saveSubtitles.isChecked = true + subtitleLanguages.visibility = View.VISIBLE + } + + saveSubtitles.setOnCheckedChangeListener { compoundButton, b -> + if (saveSubtitles.isChecked) subtitleLanguages.visibility = View.VISIBLE + else subtitleLanguages.visibility = View.GONE + downloadItem.videoPreferences.writeSubs = saveSubtitles.isChecked + } + + subtitleLanguages.setOnClickListener { + val builder = MaterialAlertDialogBuilder(requireContext()) + builder.setTitle(getString(R.string.subtitle_languages)) + val inputLayout = layoutInflater.inflate(R.layout.textinput, null) + val editText = inputLayout.findViewById(R.id.url_edittext) + editText.setHint(R.string.subtitle_languages) + editText.setText(downloadItem.videoPreferences.subsLanguages) + editText.setSelection(editText.text.length) + builder.setView(inputLayout) + builder.setPositiveButton( + getString(R.string.ok) + ) { dialog: DialogInterface?, which: Int -> + downloadItem.videoPreferences.subsLanguages = editText.text.toString() + } + + // handle the negative button of the alert dialog + builder.setNegativeButton( + getString(R.string.cancel) + ) { dialog: DialogInterface?, which: Int -> } + + builder.setNeutralButton("?") { dialog: DialogInterface?, which: Int -> + val browserIntent = + Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/yt-dlp/yt-dlp#subtitle-options")) + startActivity(browserIntent) + } + + + val dialog = builder.create() + editText.doOnTextChanged { text, start, before, count -> + dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty() + } + dialog.show() + val imm = context?.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as InputMethodManager + editText!!.postDelayed({ + editText.requestFocus() + imm.showSoftInput(editText, 0) + }, 300) + dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = editText.text.isNotEmpty() + dialog.getButton(AlertDialog.BUTTON_NEUTRAL).gravity = Gravity.START + } + } catch (e: Exception) { e.printStackTrace() } diff --git a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/SettingsFragment.kt b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/SettingsFragment.kt index c578baa3..63267223 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/SettingsFragment.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/ui/more/settings/SettingsFragment.kt @@ -55,6 +55,7 @@ class SettingsFragment : PreferenceFragmentCompat() { private var restrictFilenames: SwitchPreferenceCompat? = null private var mtime: SwitchPreferenceCompat? = null private var embedSubtitles: SwitchPreferenceCompat? = null + private var writeSubtitles: SwitchPreferenceCompat? = null private var embedThumbnail: SwitchPreferenceCompat? = null private var addChapters: SwitchPreferenceCompat? = null private var writeThumbnail: SwitchPreferenceCompat? = null @@ -117,6 +118,7 @@ class SettingsFragment : PreferenceFragmentCompat() { sponsorblockFilters = findPreference("sponsorblock_filters") mtime = findPreference("mtime") embedSubtitles = findPreference("embed_subtitles") + writeSubtitles = findPreference("write_subtitles") filenameTemplate = findPreference("file_name_template") restrictFilenames = findPreference("restrict_filenames") embedThumbnail = findPreference("embed_thumbnail") @@ -182,6 +184,7 @@ class SettingsFragment : PreferenceFragmentCompat() { editor.putBoolean("restrict_filenames", restrictFilenames!!.isChecked) editor.putBoolean("mtime", mtime!!.isChecked) editor.putBoolean("embed_subtitles", embedSubtitles!!.isChecked) + editor.putBoolean("write_subtitles", writeSubtitles!!.isChecked) editor.putBoolean("embed_thumbnail", embedThumbnail!!.isChecked) editor.putBoolean("add_chapters", addChapters!!.isChecked) editor.putBoolean("write_thumbnail", writeThumbnail!!.isChecked) @@ -391,6 +394,13 @@ class SettingsFragment : PreferenceFragmentCompat() { editor.apply() true } + writeSubtitles!!.onPreferenceChangeListener = + Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any -> + val embed = newValue as Boolean + editor.putBoolean("write_subtitles", embed) + editor.apply() + true + } embedThumbnail!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any -> val embed = newValue as Boolean diff --git a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt index 8a4c77a3..e190a5f5 100644 --- a/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt +++ b/app/src/main/java/com/deniscerri/ytdlnis/work/DownloadWorker.kt @@ -230,6 +230,14 @@ class DownloadWorker( } } + if (downloadItem.videoPreferences.writeSubs){ + request.addOption("--write-subs") + request.addOption("--write-auto-subs") + request.addOption("--sub-format", "str/ass/best") + request.addOption("--convert-subtitles", "srt") + request.addOption("--sub-langs", downloadItem.videoPreferences.subsLanguages) + } + if (downloadItem.videoPreferences.splitByChapters && downloadItem.downloadSections.isBlank()){ request.addOption("--split-chapters") request.addOption("-P", tempFileDir.absolutePath) @@ -267,7 +275,7 @@ class DownloadWorker( } YoutubeDL.getInstance().execute(request, downloadItem.id.toString()){ progress, _, line -> - setProgressAsync(workDataOf("progress" to progress.toInt(), "output" to line, "id" to downloadItem.id, "log" to logDownloads)) + setProgressAsync(workDataOf("progress" to progress.toInt(), "output" to line.chunked(5000).first().toString(), "id" to downloadItem.id, "log" to logDownloads)) val title: String = downloadItem.title notificationUtil.updateDownloadNotification( downloadItem.id.toInt(), diff --git a/app/src/main/res/drawable/ic_subtitles_alternative.xml b/app/src/main/res/drawable/ic_subtitles_alternative.xml new file mode 100644 index 00000000..a1ae0db4 --- /dev/null +++ b/app/src/main/res/drawable/ic_subtitles_alternative.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_download_video.xml b/app/src/main/res/layout/fragment_download_video.xml index 109c213e..1f9b776d 100644 --- a/app/src/main/res/layout/fragment_download_video.xml +++ b/app/src/main/res/layout/fragment_download_video.xml @@ -215,6 +215,41 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 63da7497..afbb967d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,4 +208,7 @@ Let the download worker work on any network type. If disabled, it will wait for an unmetered network to start the downloads Download worker will start after you are connected to an unmetered network Invert Selected + Save Subtitles + Write subtitle file + Subtitle languages \ No newline at end of file diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index ce5ad3ba..f1b75ae8 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -179,6 +179,14 @@ app:summary="@string/embed_subs_summary" app:title="@string/embed_subtitles" /> + +