Add audio format selection for audio-only downloads
Introduces settings and UI for forcing audio format conversion on audio-only downloads, including support for selecting preferred audio formats. Updates language files for all supported languages, adds config options, and passes new settings through the downloader and main app logic.
This commit is contained in:
@@ -61,6 +61,8 @@ class DownloadThread(QThread):
|
||||
geo_proxy_url=None,
|
||||
force_output_format=False,
|
||||
preferred_output_format="mp4",
|
||||
force_audio_format=False,
|
||||
preferred_audio_format="best",
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.url = url
|
||||
@@ -86,6 +88,8 @@ class DownloadThread(QThread):
|
||||
self.geo_proxy_url = geo_proxy_url
|
||||
self.force_output_format = force_output_format
|
||||
self.preferred_output_format = preferred_output_format
|
||||
self.force_audio_format = force_audio_format
|
||||
self.preferred_audio_format = preferred_audio_format
|
||||
self.paused: bool = False
|
||||
self.cancelled: bool = False
|
||||
self.process: Optional[subprocess.Popen] = None
|
||||
@@ -184,7 +188,7 @@ class DownloadThread(QThread):
|
||||
res_value: str = self.resolution if self.resolution else "720" # Default to 720p if no resolution specified
|
||||
cmd.extend(["-S", f"res:{res_value}"])
|
||||
|
||||
# Force output format if enabled and merging is needed
|
||||
# Force output format if enabled and merging is needed (for video)
|
||||
if self.force_output_format and not self.is_audio_only:
|
||||
if self.format_has_audio:
|
||||
# Progressive format (video with audio) - use remux to convert container
|
||||
@@ -195,6 +199,15 @@ class DownloadThread(QThread):
|
||||
cmd.extend(["--merge-output-format", self.preferred_output_format])
|
||||
logger.debug(f"Using --merge-output-format to force merged format to: {self.preferred_output_format}")
|
||||
|
||||
# Force audio format conversion for audio-only downloads
|
||||
if self.is_audio_only and self.force_audio_format:
|
||||
cmd.append("--extract-audio")
|
||||
if self.preferred_audio_format and self.preferred_audio_format != "best":
|
||||
cmd.extend(["--audio-format", self.preferred_audio_format])
|
||||
logger.debug(f"Using --extract-audio with --audio-format {self.preferred_audio_format} for audio-only download")
|
||||
else:
|
||||
logger.debug("Using --extract-audio with best quality (no conversion) for audio-only download")
|
||||
|
||||
# Output template with resolution in filename
|
||||
# Use string concatenation instead of Path.joinpath to avoid Path object issues
|
||||
base_path: str = self.path.as_posix()
|
||||
|
||||
@@ -234,6 +234,52 @@ class DownloadSettingsDialog(QDialog):
|
||||
output_format_group_box.setLayout(output_format_layout)
|
||||
layout.addWidget(output_format_group_box)
|
||||
|
||||
# --- Audio Format Settings Section (for audio-only downloads) ---
|
||||
audio_format_group_box = QGroupBox(_("settings.audio_format_settings"))
|
||||
audio_format_layout = QVBoxLayout()
|
||||
|
||||
# Load current audio format settings from ConfigManager
|
||||
self.force_audio_format_enabled = ConfigManager.get("force_audio_format") or False
|
||||
self.preferred_audio_format_value = ConfigManager.get("preferred_audio_format") or "best"
|
||||
|
||||
# Enable/Disable force audio format checkbox
|
||||
self.force_audio_format_checkbox = QCheckBox(_("settings.force_audio_format"))
|
||||
self.force_audio_format_checkbox.setChecked(self.force_audio_format_enabled)
|
||||
audio_format_layout.addWidget(self.force_audio_format_checkbox)
|
||||
|
||||
# Audio format selection layout
|
||||
audio_format_select_layout = QHBoxLayout()
|
||||
audio_format_label = QLabel(_("settings.preferred_audio_format"))
|
||||
audio_format_label.setStyleSheet("color: #ffffff; margin-top: 5px;")
|
||||
audio_format_select_layout.addWidget(audio_format_label)
|
||||
|
||||
self.audio_format_combo = QComboBox()
|
||||
self.audio_format_combo.addItems([
|
||||
_("settings.audio_format_best"),
|
||||
_("settings.audio_format_aac"),
|
||||
_("settings.audio_format_mp3"),
|
||||
_("settings.audio_format_flac"),
|
||||
_("settings.audio_format_wav"),
|
||||
_("settings.audio_format_opus"),
|
||||
_("settings.audio_format_m4a"),
|
||||
_("settings.audio_format_vorbis")
|
||||
])
|
||||
# Set current selection based on saved format
|
||||
audio_format_index_map = {"best": 0, "aac": 1, "mp3": 2, "flac": 3, "wav": 4, "opus": 5, "m4a": 6, "vorbis": 7}
|
||||
self.audio_format_combo.setCurrentIndex(audio_format_index_map.get(self.preferred_audio_format_value, 0))
|
||||
audio_format_select_layout.addWidget(self.audio_format_combo)
|
||||
audio_format_select_layout.addStretch()
|
||||
audio_format_layout.addLayout(audio_format_select_layout)
|
||||
|
||||
# Help text for audio format
|
||||
audio_help_label = QLabel(_("settings.force_audio_format_help"))
|
||||
audio_help_label.setWordWrap(True)
|
||||
audio_help_label.setStyleSheet("color: #cccccc; margin: 5px; font-size: 10px;")
|
||||
audio_format_layout.addWidget(audio_help_label)
|
||||
|
||||
audio_format_group_box.setLayout(audio_format_layout)
|
||||
layout.addWidget(audio_format_group_box)
|
||||
|
||||
# Dialog buttons (OK/Cancel)
|
||||
button_box = QDialogButtonBox()
|
||||
ok_button = button_box.addButton(_("buttons.ok"), QDialogButtonBox.ButtonRole.AcceptRole)
|
||||
@@ -277,6 +323,15 @@ class DownloadSettingsDialog(QDialog):
|
||||
format_map = {0: "mp4", 1: "webm", 2: "mkv"}
|
||||
return format_map.get(self.format_combo.currentIndex(), "mp4")
|
||||
|
||||
def get_force_audio_format_enabled(self) -> bool:
|
||||
"""Returns whether force audio format is enabled."""
|
||||
return self.force_audio_format_checkbox.isChecked()
|
||||
|
||||
def get_preferred_audio_format(self) -> str:
|
||||
"""Returns the selected preferred audio format (lowercase)."""
|
||||
audio_format_map = {0: "best", 1: "aac", 2: "mp3", 3: "flac", 4: "wav", 5: "opus", 6: "m4a", 7: "vorbis"}
|
||||
return audio_format_map.get(self.audio_format_combo.currentIndex(), "best")
|
||||
|
||||
def _create_styled_message_box(self, icon, title, text) -> QMessageBox:
|
||||
"""Create a styled QMessageBox that matches the app theme."""
|
||||
msg_box = QMessageBox(self)
|
||||
@@ -321,6 +376,12 @@ class DownloadSettingsDialog(QDialog):
|
||||
ConfigManager.set("force_output_format", force_format)
|
||||
ConfigManager.set("preferred_output_format", preferred_format)
|
||||
|
||||
# Save audio format settings
|
||||
force_audio_format = self.get_force_audio_format_enabled()
|
||||
preferred_audio_format = self.get_preferred_audio_format()
|
||||
ConfigManager.set("force_audio_format", force_audio_format)
|
||||
ConfigManager.set("preferred_audio_format", preferred_audio_format)
|
||||
|
||||
QMessageBox.information(
|
||||
self,
|
||||
_("settings.settings_saved_title"),
|
||||
|
||||
@@ -125,6 +125,8 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin): # Inherit from
|
||||
# Initialize output format settings
|
||||
self.force_output_format = ConfigManager.get("force_output_format") or False
|
||||
self.preferred_output_format = ConfigManager.get("preferred_output_format") or "mp4"
|
||||
self.force_audio_format = ConfigManager.get("force_audio_format") or False
|
||||
self.preferred_audio_format = ConfigManager.get("preferred_audio_format") or "best"
|
||||
# Track if video analysis is completed
|
||||
self.analysis_completed = False
|
||||
|
||||
@@ -898,6 +900,8 @@ class YTSageApp(QMainWindow, FormatTableMixin, VideoInfoMixin): # Inherit from
|
||||
geo_proxy_url=self.geo_proxy_url, # Pass the geo-verification proxy URL
|
||||
force_output_format=self.force_output_format, # Pass force output format setting
|
||||
preferred_output_format=self.preferred_output_format, # Pass preferred format
|
||||
force_audio_format=self.force_audio_format, # Pass force audio format setting
|
||||
preferred_audio_format=self.preferred_audio_format, # Pass preferred audio format
|
||||
)
|
||||
|
||||
# Connect signals
|
||||
|
||||
@@ -84,6 +84,8 @@ class ConfigManager:
|
||||
"ytdlp_channel": "stable",
|
||||
"force_output_format": False,
|
||||
"preferred_output_format": "mp4",
|
||||
"force_audio_format": False,
|
||||
"preferred_audio_format": "best",
|
||||
"cached_versions": {
|
||||
"ytdlp": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
||||
"ffmpeg": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
||||
|
||||
Reference in New Issue
Block a user