✨ FLAC can be extracted from MP4 containers (see options). Downgrade on HI_RES download is possible (see options). Fixes #93 #86
This commit is contained in:
@@ -160,6 +160,8 @@ class DialogPreferences(QtWidgets.QDialog):
|
|||||||
"video_download",
|
"video_download",
|
||||||
"download_delay",
|
"download_delay",
|
||||||
"video_convert_mp4",
|
"video_convert_mp4",
|
||||||
|
"extract_flac",
|
||||||
|
"downgrade_on_hi_res",
|
||||||
]
|
]
|
||||||
|
|
||||||
def gui_populate(self):
|
def gui_populate(self):
|
||||||
|
|||||||
+71
-17
@@ -12,7 +12,7 @@ import requests
|
|||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
from rich.progress import Progress, TaskID
|
from rich.progress import Progress, TaskID
|
||||||
from tidalapi import Album, Mix, Playlist, Session, Track, UserPlaylist, Video
|
from tidalapi import Album, Mix, Playlist, Session, Track, UserPlaylist, Video
|
||||||
from tidalapi.media import AudioExtensions, Quality, StreamManifest, VideoExtensions
|
from tidalapi.media import AudioExtensions, Codec, Quality, StreamManifest, VideoExtensions, VideoQuality
|
||||||
|
|
||||||
from tidal_dl_ng.config import Settings, Tidal
|
from tidal_dl_ng.config import Settings, Tidal
|
||||||
from tidal_dl_ng.constants import EXTENSION_LYRICS, REQUESTS_TIMEOUT_SEC, MediaType, SkipExisting
|
from tidal_dl_ng.constants import EXTENSION_LYRICS, REQUESTS_TIMEOUT_SEC, MediaType, SkipExisting
|
||||||
@@ -70,11 +70,15 @@ class Download:
|
|||||||
self.progress = progress
|
self.progress = progress
|
||||||
self.path_base = path_base
|
self.path_base = path_base
|
||||||
|
|
||||||
if not self.settings.data.path_binary_ffmpeg and self.settings.data.video_convert_mp4:
|
if not self.settings.data.path_binary_ffmpeg and (
|
||||||
|
self.settings.data.video_convert_mp4 or self.settings.data.extract_flac
|
||||||
|
):
|
||||||
self.settings.data.video_convert_mp4 = False
|
self.settings.data.video_convert_mp4 = False
|
||||||
|
self.settings.data.extract_flac = False
|
||||||
|
|
||||||
self.fn_logger.error(
|
self.fn_logger.error(
|
||||||
"FFmpeg in path is not set. Videos can be downloaded but will not be processed. "
|
"FFmpeg is not set. Videos can be downloaded but will not be processed. FLAC cannot be extracted from MP4 containers. "
|
||||||
"Make sure FFmpeg is installed and the path to the binary is configured ('path_binary_ffmpeg')."
|
"Make sure FFmpeg is installed and the path to the binary is configured (`path_binary_ffmpeg`)."
|
||||||
)
|
)
|
||||||
|
|
||||||
def _download(
|
def _download(
|
||||||
@@ -174,7 +178,8 @@ class Download:
|
|||||||
media_type: MediaType = None,
|
media_type: MediaType = None,
|
||||||
video_download: bool = True,
|
video_download: bool = True,
|
||||||
download_delay: bool = False,
|
download_delay: bool = False,
|
||||||
quality: Quality | None = None,
|
quality_audio: Quality | None = None,
|
||||||
|
quality_video: VideoQuality | None = None,
|
||||||
) -> (bool, str):
|
) -> (bool, str):
|
||||||
try:
|
try:
|
||||||
if media_id and media_type:
|
if media_id and media_type:
|
||||||
@@ -203,17 +208,34 @@ class Download:
|
|||||||
|
|
||||||
return False, ""
|
return False, ""
|
||||||
|
|
||||||
# If a quality is explicitly set, change it.
|
|
||||||
if quality:
|
|
||||||
quality_old: Quality = self.quality_adjust(quality)
|
|
||||||
|
|
||||||
# Get extension.
|
# Get extension.
|
||||||
file_extension: str
|
file_extension: str
|
||||||
|
|
||||||
if isinstance(media, Track):
|
if isinstance(media, Track):
|
||||||
|
# If hi_res is forbidden in settings and highest track quality is hi_res, downgrade to high_lossless.
|
||||||
|
if self.settings.data.downgrade_on_hires and media.get_stream().audio_quality == Quality.hi_res:
|
||||||
|
quality_audio = Quality.high_lossless
|
||||||
|
|
||||||
|
# If a quality is explicitly set, change it.
|
||||||
|
if quality_audio:
|
||||||
|
quality_audio_old: Quality = self.adjust_quality_audio(quality_audio)
|
||||||
|
|
||||||
file_extension = media.get_stream().get_stream_manifest().file_extension
|
file_extension = media.get_stream().get_stream_manifest().file_extension
|
||||||
|
|
||||||
|
if self.settings.data.extract_flac:
|
||||||
|
do_flac_extract = False
|
||||||
|
|
||||||
|
if (
|
||||||
|
media.get_stream().get_stream_manifest().codecs.upper() == Codec.FLAC
|
||||||
|
and file_extension != AudioExtensions.FLAC
|
||||||
|
):
|
||||||
|
file_extension = AudioExtensions.FLAC
|
||||||
|
do_flac_extract = True
|
||||||
elif isinstance(media, Video):
|
elif isinstance(media, Video):
|
||||||
file_extension = VideoExtensions.TS
|
if quality_video:
|
||||||
|
quality_video_old = self.adjust_quality_video(quality_video)
|
||||||
|
|
||||||
|
file_extension = AudioExtensions.MP4 if self.settings.data.video_convert_mp4 else VideoExtensions.TS
|
||||||
|
|
||||||
# Create file name and path
|
# Create file name and path
|
||||||
file_name_relative = format_path_media(file_template, media)
|
file_name_relative = format_path_media(file_template, media)
|
||||||
@@ -235,14 +257,18 @@ class Download:
|
|||||||
if not file_exists:
|
if not file_exists:
|
||||||
# Create a temp directory and file.
|
# Create a temp directory and file.
|
||||||
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmp_path_dir:
|
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmp_path_dir:
|
||||||
tmp_path_file = os.path.join(tmp_path_dir, str(uuid4()) + file_extension)
|
tmp_path_file = os.path.join(tmp_path_dir, str(uuid4()))
|
||||||
# Download media.
|
# Download media.
|
||||||
tmp_path_file = self._download(media=media, path_file=tmp_path_file)
|
tmp_path_file = self._download(media=media, path_file=tmp_path_file)
|
||||||
|
|
||||||
|
# Convert video from TS to MP4
|
||||||
if isinstance(media, Video) and self.settings.data.video_convert_mp4:
|
if isinstance(media, Video) and self.settings.data.video_convert_mp4:
|
||||||
# Convert `*.ts` file to `*.mp4` using ffmpeg
|
# Convert `*.ts` file to `*.mp4` using ffmpeg
|
||||||
tmp_path_file = self._video_convert(tmp_path_file)
|
tmp_path_file = self._video_convert(tmp_path_file)
|
||||||
path_file = os.path.splitext(path_file)[0] + ".mp4"
|
|
||||||
|
# Extract FLAC from MP4 container using ffmpeg
|
||||||
|
if self.settings.data.extract_flac and do_flac_extract:
|
||||||
|
tmp_path_file = self._extract_flac(tmp_path_file, media.isrc)
|
||||||
|
|
||||||
# Move final file to the configured destination directory.
|
# Move final file to the configured destination directory.
|
||||||
os.makedirs(os.path.dirname(path_file), exist_ok=True)
|
os.makedirs(os.path.dirname(path_file), exist_ok=True)
|
||||||
@@ -256,9 +282,13 @@ class Download:
|
|||||||
|
|
||||||
status_download: bool = not file_exists
|
status_download: bool = not file_exists
|
||||||
|
|
||||||
if quality:
|
if quality_audio:
|
||||||
# Set quality back to the global user value
|
# Set quality back to the global user value
|
||||||
self.quality_adjust(quality_old)
|
self.adjust_quality_audio(quality_audio_old)
|
||||||
|
|
||||||
|
if quality_video:
|
||||||
|
# Set quality back to the global user value
|
||||||
|
self.adjust_quality_video(quality_video_old)
|
||||||
|
|
||||||
# Whether a file was downloaded or skipped and the download delay is enabled, wait until the next download.
|
# Whether a file was downloaded or skipped and the download delay is enabled, wait until the next download.
|
||||||
# Only use this, if you have a list of several Track items.
|
# Only use this, if you have a list of several Track items.
|
||||||
@@ -270,7 +300,7 @@ class Download:
|
|||||||
|
|
||||||
return status_download, path_file
|
return status_download, path_file
|
||||||
|
|
||||||
def quality_adjust(self, quality) -> Quality:
|
def adjust_quality_audio(self, quality) -> Quality:
|
||||||
# Save original quality settings
|
# Save original quality settings
|
||||||
quality_old: Quality = self.session.audio_quality
|
quality_old: Quality = self.session.audio_quality
|
||||||
self.session.audio_quality = quality
|
self.session.audio_quality = quality
|
||||||
@@ -284,6 +314,13 @@ class Download:
|
|||||||
|
|
||||||
return quality_old
|
return quality_old
|
||||||
|
|
||||||
|
def adjust_quality_video(self, quality) -> VideoQuality:
|
||||||
|
quality_old: VideoQuality = self.session.video_quality
|
||||||
|
|
||||||
|
self.session.video_quality = quality
|
||||||
|
|
||||||
|
return quality_old
|
||||||
|
|
||||||
def _move_lyrics(self, file_media_dst: str, file_media_src: str):
|
def _move_lyrics(self, file_media_dst: str, file_media_src: str):
|
||||||
# Build tmp lyrics filename
|
# Build tmp lyrics filename
|
||||||
tmp_lyrics_file_path: str = file_media_src + EXTENSION_LYRICS
|
tmp_lyrics_file_path: str = file_media_src + EXTENSION_LYRICS
|
||||||
@@ -405,7 +442,7 @@ class Download:
|
|||||||
for media in items:
|
for media in items:
|
||||||
# Download the item.
|
# Download the item.
|
||||||
status_download, result_path_file = self.item(
|
status_download, result_path_file = self.item(
|
||||||
media=media, file_template=file_name_relative, quality=quality
|
media=media, file_template=file_name_relative, quality_audio=quality
|
||||||
)
|
)
|
||||||
|
|
||||||
# Advance progress bar.
|
# Advance progress bar.
|
||||||
@@ -422,11 +459,28 @@ class Download:
|
|||||||
time.sleep(time_sleep)
|
time.sleep(time_sleep)
|
||||||
|
|
||||||
def _video_convert(self, path_file: str) -> str:
|
def _video_convert(self, path_file: str) -> str:
|
||||||
path_file_out = os.path.splitext(path_file)[0] + AudioExtensions.MP4
|
path_file_out = path_file + AudioExtensions.MP4
|
||||||
result, _ = ffmpeg.input(path_file).output(path_file_out, map=0, c="copy").run()
|
result, _ = ffmpeg.input(path_file).output(path_file_out, map=0, c="copy").run()
|
||||||
|
|
||||||
return path_file_out
|
return path_file_out
|
||||||
|
|
||||||
|
def _extract_flac(self, path_file: str, isrc: str) -> str:
|
||||||
|
path_file_out = path_file + AudioExtensions.FLAC
|
||||||
|
result, _ = (
|
||||||
|
ffmpeg.input(path_file)
|
||||||
|
.output(
|
||||||
|
path_file_out,
|
||||||
|
map=0,
|
||||||
|
movflags="use_metadata_tags",
|
||||||
|
acodec="copy",
|
||||||
|
map_metadata="0:g",
|
||||||
|
metadata=f"isrc={isrc}",
|
||||||
|
)
|
||||||
|
.run()
|
||||||
|
)
|
||||||
|
|
||||||
|
return path_file_out
|
||||||
|
|
||||||
def _extract_video_stream(self, m3u8_variant: m3u8.M3U8, quality: int) -> (m3u8.M3U8 | bool, str):
|
def _extract_video_stream(self, m3u8_variant: m3u8.M3U8, quality: int) -> (m3u8.M3U8 | bool, str):
|
||||||
m3u8_playlist: m3u8.M3U8 | bool = False
|
m3u8_playlist: m3u8.M3U8 | bool = False
|
||||||
resolution_best: int = 0
|
resolution_best: int = 0
|
||||||
|
|||||||
+1
-1
@@ -864,7 +864,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
if isinstance(media, Track | Video):
|
if isinstance(media, Track | Video):
|
||||||
result_dl, path_file = dl.item(
|
result_dl, path_file = dl.item(
|
||||||
media=media, file_template=file_template, download_delay=delay_track, quality=quality
|
media=media, file_template=file_template, download_delay=delay_track, quality_audio=quality
|
||||||
)
|
)
|
||||||
elif isinstance(media, Album | Playlist | Mix):
|
elif isinstance(media, Album | Playlist | Mix):
|
||||||
dl.items(
|
dl.items(
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class Metadata:
|
|||||||
self.m.tags["\xa9day"] = self.date
|
self.m.tags["\xa9day"] = self.date
|
||||||
self.m.tags["\xa9wrt"] = ", ".join(self.composer) if self.composer else ""
|
self.m.tags["\xa9wrt"] = ", ".join(self.composer) if self.composer else ""
|
||||||
self.m.tags["\xa9lyr"] = self.lyrics
|
self.m.tags["\xa9lyr"] = self.lyrics
|
||||||
self.m.tags["ISRC"] = self.isrc
|
self.m.tags["isrc"] = self.isrc
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def cover_data(url: str = None, path_file: str = None) -> str | bytes:
|
def cover_data(url: str = None, path_file: str = None) -> str | bytes:
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ class Settings:
|
|||||||
video_convert_mp4: bool = True
|
video_convert_mp4: bool = True
|
||||||
path_binary_ffmpeg: str = ""
|
path_binary_ffmpeg: str = ""
|
||||||
metadata_cover_dimension: CoverDimensions = CoverDimensions.Px320
|
metadata_cover_dimension: CoverDimensions = CoverDimensions.Px320
|
||||||
|
extract_flac: bool = True
|
||||||
|
downgrade_on_hi_res: bool = False
|
||||||
|
|
||||||
|
|
||||||
@dataclass_json
|
@dataclass_json
|
||||||
@@ -74,6 +76,10 @@ class HelpSettings:
|
|||||||
metadata_cover_dimension: str = (
|
metadata_cover_dimension: str = (
|
||||||
"The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280."
|
"The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280."
|
||||||
)
|
)
|
||||||
|
extract_flac: str = "Extract FLAC audio tracks from MP4 containers and save them as `*.flac` (uses FFmpeg)."
|
||||||
|
downgrade_on_hi_res: bool = (
|
||||||
|
"Never download HI_RES (MQA) quality. Downgrade to the next best available quality instead."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass_json
|
@dataclass_json
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
## Form generated from reading UI file 'dialog_settings.ui'
|
## Form generated from reading UI file 'dialog_settings.ui'
|
||||||
##
|
##
|
||||||
## Created by: Qt User Interface Compiler version 6.6.1
|
## Created by: Qt User Interface Compiler version 6.7.0
|
||||||
##
|
##
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -27,7 +27,7 @@ class Ui_DialogSettings:
|
|||||||
if not DialogSettings.objectName():
|
if not DialogSettings.objectName():
|
||||||
DialogSettings.setObjectName("DialogSettings")
|
DialogSettings.setObjectName("DialogSettings")
|
||||||
DialogSettings.resize(640, 682)
|
DialogSettings.resize(640, 682)
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||||
sizePolicy.setHorizontalStretch(100)
|
sizePolicy.setHorizontalStretch(100)
|
||||||
sizePolicy.setVerticalStretch(100)
|
sizePolicy.setVerticalStretch(100)
|
||||||
sizePolicy.setHeightForWidth(DialogSettings.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(DialogSettings.sizePolicy().hasHeightForWidth())
|
||||||
@@ -41,7 +41,7 @@ class Ui_DialogSettings:
|
|||||||
self.lv_main.setContentsMargins(12, 12, 12, 12)
|
self.lv_main.setContentsMargins(12, 12, 12, 12)
|
||||||
self.gb_flags = QGroupBox(DialogSettings)
|
self.gb_flags = QGroupBox(DialogSettings)
|
||||||
self.gb_flags.setObjectName("gb_flags")
|
self.gb_flags.setObjectName("gb_flags")
|
||||||
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||||
sizePolicy1.setHorizontalStretch(100)
|
sizePolicy1.setHorizontalStretch(100)
|
||||||
sizePolicy1.setVerticalStretch(100)
|
sizePolicy1.setVerticalStretch(100)
|
||||||
sizePolicy1.setHeightForWidth(self.gb_flags.sizePolicy().hasHeightForWidth())
|
sizePolicy1.setHeightForWidth(self.gb_flags.sizePolicy().hasHeightForWidth())
|
||||||
@@ -52,56 +52,56 @@ class Ui_DialogSettings:
|
|||||||
self.lv_flags.setObjectName("lv_flags")
|
self.lv_flags.setObjectName("lv_flags")
|
||||||
self.lh_flags_1 = QHBoxLayout()
|
self.lh_flags_1 = QHBoxLayout()
|
||||||
self.lh_flags_1.setObjectName("lh_flags_1")
|
self.lh_flags_1.setObjectName("lh_flags_1")
|
||||||
self.lv_flags_video_download = QVBoxLayout()
|
self.lv_flag_video_download = QVBoxLayout()
|
||||||
self.lv_flags_video_download.setObjectName("lv_flags_video_download")
|
self.lv_flag_video_download.setObjectName("lv_flag_video_download")
|
||||||
self.cb_video_download = QCheckBox(self.gb_flags)
|
self.cb_video_download = QCheckBox(self.gb_flags)
|
||||||
self.cb_video_download.setObjectName("cb_video_download")
|
self.cb_video_download.setObjectName("cb_video_download")
|
||||||
sizePolicy1.setHeightForWidth(self.cb_video_download.sizePolicy().hasHeightForWidth())
|
sizePolicy1.setHeightForWidth(self.cb_video_download.sizePolicy().hasHeightForWidth())
|
||||||
self.cb_video_download.setSizePolicy(sizePolicy1)
|
self.cb_video_download.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
self.lv_flags_video_download.addWidget(self.cb_video_download)
|
self.lv_flag_video_download.addWidget(self.cb_video_download)
|
||||||
|
|
||||||
self.lh_flags_1.addLayout(self.lv_flags_video_download)
|
self.lh_flags_1.addLayout(self.lv_flag_video_download)
|
||||||
|
|
||||||
self.lv_flags_video_convert = QVBoxLayout()
|
self.lv_flag_video_convert = QVBoxLayout()
|
||||||
self.lv_flags_video_convert.setObjectName("lv_flags_video_convert")
|
self.lv_flag_video_convert.setObjectName("lv_flag_video_convert")
|
||||||
self.cb_video_convert_mp4 = QCheckBox(self.gb_flags)
|
self.cb_video_convert_mp4 = QCheckBox(self.gb_flags)
|
||||||
self.cb_video_convert_mp4.setObjectName("cb_video_convert_mp4")
|
self.cb_video_convert_mp4.setObjectName("cb_video_convert_mp4")
|
||||||
sizePolicy1.setHeightForWidth(self.cb_video_convert_mp4.sizePolicy().hasHeightForWidth())
|
sizePolicy1.setHeightForWidth(self.cb_video_convert_mp4.sizePolicy().hasHeightForWidth())
|
||||||
self.cb_video_convert_mp4.setSizePolicy(sizePolicy1)
|
self.cb_video_convert_mp4.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
self.lv_flags_video_convert.addWidget(self.cb_video_convert_mp4)
|
self.lv_flag_video_convert.addWidget(self.cb_video_convert_mp4)
|
||||||
|
|
||||||
self.lh_flags_1.addLayout(self.lv_flags_video_convert)
|
self.lh_flags_1.addLayout(self.lv_flag_video_convert)
|
||||||
|
|
||||||
self.lv_flags.addLayout(self.lh_flags_1)
|
self.lv_flags.addLayout(self.lh_flags_1)
|
||||||
|
|
||||||
self.lh_flags_2 = QHBoxLayout()
|
self.lh_flags_2 = QHBoxLayout()
|
||||||
self.lh_flags_2.setObjectName("lh_flags_2")
|
self.lh_flags_2.setObjectName("lh_flags_2")
|
||||||
self.lh_flags_lyrics_embed = QHBoxLayout()
|
self.lh_flag_lyrics_embed = QHBoxLayout()
|
||||||
self.lh_flags_lyrics_embed.setObjectName("lh_flags_lyrics_embed")
|
self.lh_flag_lyrics_embed.setObjectName("lh_flag_lyrics_embed")
|
||||||
self.cb_lyrics_embed = QCheckBox(self.gb_flags)
|
self.cb_lyrics_embed = QCheckBox(self.gb_flags)
|
||||||
self.cb_lyrics_embed.setObjectName("cb_lyrics_embed")
|
self.cb_lyrics_embed.setObjectName("cb_lyrics_embed")
|
||||||
sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||||
sizePolicy2.setHorizontalStretch(0)
|
sizePolicy2.setHorizontalStretch(0)
|
||||||
sizePolicy2.setVerticalStretch(0)
|
sizePolicy2.setVerticalStretch(0)
|
||||||
sizePolicy2.setHeightForWidth(self.cb_lyrics_embed.sizePolicy().hasHeightForWidth())
|
sizePolicy2.setHeightForWidth(self.cb_lyrics_embed.sizePolicy().hasHeightForWidth())
|
||||||
self.cb_lyrics_embed.setSizePolicy(sizePolicy2)
|
self.cb_lyrics_embed.setSizePolicy(sizePolicy2)
|
||||||
|
|
||||||
self.lh_flags_lyrics_embed.addWidget(self.cb_lyrics_embed)
|
self.lh_flag_lyrics_embed.addWidget(self.cb_lyrics_embed)
|
||||||
|
|
||||||
self.lh_flags_2.addLayout(self.lh_flags_lyrics_embed)
|
self.lh_flags_2.addLayout(self.lh_flag_lyrics_embed)
|
||||||
|
|
||||||
self.lh_flags_lyrics_file = QHBoxLayout()
|
self.lh_flag_lyrics_file = QHBoxLayout()
|
||||||
self.lh_flags_lyrics_file.setObjectName("lh_flags_lyrics_file")
|
self.lh_flag_lyrics_file.setObjectName("lh_flag_lyrics_file")
|
||||||
self.cb_lyrics_file = QCheckBox(self.gb_flags)
|
self.cb_lyrics_file = QCheckBox(self.gb_flags)
|
||||||
self.cb_lyrics_file.setObjectName("cb_lyrics_file")
|
self.cb_lyrics_file.setObjectName("cb_lyrics_file")
|
||||||
sizePolicy1.setHeightForWidth(self.cb_lyrics_file.sizePolicy().hasHeightForWidth())
|
sizePolicy1.setHeightForWidth(self.cb_lyrics_file.sizePolicy().hasHeightForWidth())
|
||||||
self.cb_lyrics_file.setSizePolicy(sizePolicy1)
|
self.cb_lyrics_file.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
self.lh_flags_lyrics_file.addWidget(self.cb_lyrics_file)
|
self.lh_flag_lyrics_file.addWidget(self.cb_lyrics_file)
|
||||||
|
|
||||||
self.lh_flags_2.addLayout(self.lh_flags_lyrics_file)
|
self.lh_flags_2.addLayout(self.lh_flag_lyrics_file)
|
||||||
|
|
||||||
self.lv_flags.addLayout(self.lh_flags_2)
|
self.lv_flags.addLayout(self.lh_flags_2)
|
||||||
|
|
||||||
@@ -118,18 +118,37 @@ class Ui_DialogSettings:
|
|||||||
|
|
||||||
self.lh_flag_3.addLayout(self.lv_flag_download_delay)
|
self.lh_flag_3.addLayout(self.lv_flag_download_delay)
|
||||||
|
|
||||||
self.verticalLayout_4 = QVBoxLayout()
|
self.lv_flag_extract_flac = QVBoxLayout()
|
||||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
self.lv_flag_extract_flac.setObjectName("lv_flag_extract_flac")
|
||||||
|
self.cb_extract_flac = QCheckBox(self.gb_flags)
|
||||||
|
self.cb_extract_flac.setObjectName("cb_extract_flac")
|
||||||
|
sizePolicy2.setHeightForWidth(self.cb_extract_flac.sizePolicy().hasHeightForWidth())
|
||||||
|
self.cb_extract_flac.setSizePolicy(sizePolicy2)
|
||||||
|
|
||||||
self.lh_flag_3.addLayout(self.verticalLayout_4)
|
self.lv_flag_extract_flac.addWidget(self.cb_extract_flac)
|
||||||
|
|
||||||
|
self.lh_flag_3.addLayout(self.lv_flag_extract_flac)
|
||||||
|
|
||||||
self.lv_flags.addLayout(self.lh_flag_3)
|
self.lv_flags.addLayout(self.lh_flag_3)
|
||||||
|
|
||||||
|
self.horizontalLayout = QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.lv_flag_downgrade_on_hi_res = QVBoxLayout()
|
||||||
|
self.lv_flag_downgrade_on_hi_res.setObjectName("lv_flag_downgrade_on_hi_res")
|
||||||
|
self.cb_downgrade_on_hi_res = QCheckBox(self.gb_flags)
|
||||||
|
self.cb_downgrade_on_hi_res.setObjectName("cb_downgrade_on_hi_res")
|
||||||
|
|
||||||
|
self.lv_flag_downgrade_on_hi_res.addWidget(self.cb_downgrade_on_hi_res)
|
||||||
|
|
||||||
|
self.horizontalLayout.addLayout(self.lv_flag_downgrade_on_hi_res)
|
||||||
|
|
||||||
|
self.lv_flags.addLayout(self.horizontalLayout)
|
||||||
|
|
||||||
self.lv_main.addWidget(self.gb_flags)
|
self.lv_main.addWidget(self.gb_flags)
|
||||||
|
|
||||||
self.gb_choices = QGroupBox(DialogSettings)
|
self.gb_choices = QGroupBox(DialogSettings)
|
||||||
self.gb_choices.setObjectName("gb_choices")
|
self.gb_choices.setObjectName("gb_choices")
|
||||||
sizePolicy3 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||||
sizePolicy3.setHorizontalStretch(0)
|
sizePolicy3.setHorizontalStretch(0)
|
||||||
sizePolicy3.setVerticalStretch(0)
|
sizePolicy3.setVerticalStretch(0)
|
||||||
sizePolicy3.setHeightForWidth(self.gb_choices.sizePolicy().hasHeightForWidth())
|
sizePolicy3.setHeightForWidth(self.gb_choices.sizePolicy().hasHeightForWidth())
|
||||||
@@ -140,7 +159,7 @@ class Ui_DialogSettings:
|
|||||||
self.lh_choices_skip_existing.setObjectName("lh_choices_skip_existing")
|
self.lh_choices_skip_existing.setObjectName("lh_choices_skip_existing")
|
||||||
self.l_icon_skip_existing = QLabel(self.gb_choices)
|
self.l_icon_skip_existing = QLabel(self.gb_choices)
|
||||||
self.l_icon_skip_existing.setObjectName("l_icon_skip_existing")
|
self.l_icon_skip_existing.setObjectName("l_icon_skip_existing")
|
||||||
sizePolicy4 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||||
sizePolicy4.setHorizontalStretch(0)
|
sizePolicy4.setHorizontalStretch(0)
|
||||||
sizePolicy4.setVerticalStretch(0)
|
sizePolicy4.setVerticalStretch(0)
|
||||||
sizePolicy4.setHeightForWidth(self.l_icon_skip_existing.sizePolicy().hasHeightForWidth())
|
sizePolicy4.setHeightForWidth(self.l_icon_skip_existing.sizePolicy().hasHeightForWidth())
|
||||||
@@ -233,7 +252,7 @@ class Ui_DialogSettings:
|
|||||||
|
|
||||||
self.c_metadata_cover_dimension = QComboBox(self.gb_choices)
|
self.c_metadata_cover_dimension = QComboBox(self.gb_choices)
|
||||||
self.c_metadata_cover_dimension.setObjectName("c_metadata_cover_dimension")
|
self.c_metadata_cover_dimension.setObjectName("c_metadata_cover_dimension")
|
||||||
sizePolicy5 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||||
sizePolicy5.setHorizontalStretch(10)
|
sizePolicy5.setHorizontalStretch(10)
|
||||||
sizePolicy5.setVerticalStretch(0)
|
sizePolicy5.setVerticalStretch(0)
|
||||||
sizePolicy5.setHeightForWidth(self.c_metadata_cover_dimension.sizePolicy().hasHeightForWidth())
|
sizePolicy5.setHeightForWidth(self.c_metadata_cover_dimension.sizePolicy().hasHeightForWidth())
|
||||||
@@ -311,7 +330,7 @@ class Ui_DialogSettings:
|
|||||||
self.lh_path_fmt_album.setObjectName("lh_path_fmt_album")
|
self.lh_path_fmt_album.setObjectName("lh_path_fmt_album")
|
||||||
self.l_icon_format_album = QLabel(self.gb_path)
|
self.l_icon_format_album = QLabel(self.gb_path)
|
||||||
self.l_icon_format_album.setObjectName("l_icon_format_album")
|
self.l_icon_format_album.setObjectName("l_icon_format_album")
|
||||||
sizePolicy6 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
|
sizePolicy6 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
||||||
sizePolicy6.setHorizontalStretch(0)
|
sizePolicy6.setHorizontalStretch(0)
|
||||||
sizePolicy6.setVerticalStretch(0)
|
sizePolicy6.setVerticalStretch(0)
|
||||||
sizePolicy6.setHeightForWidth(self.l_icon_format_album.sizePolicy().hasHeightForWidth())
|
sizePolicy6.setHeightForWidth(self.l_icon_format_album.sizePolicy().hasHeightForWidth())
|
||||||
@@ -386,22 +405,22 @@ class Ui_DialogSettings:
|
|||||||
|
|
||||||
self.verticalLayout = QVBoxLayout()
|
self.verticalLayout = QVBoxLayout()
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
self.horizontalLayout_3 = QHBoxLayout()
|
self.horizontalLayout_10 = QHBoxLayout()
|
||||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
self.horizontalLayout_10.setObjectName("horizontalLayout_10")
|
||||||
self.le_download_base_path = QLineEdit(self.gb_path)
|
self.le_download_base_path = QLineEdit(self.gb_path)
|
||||||
self.le_download_base_path.setObjectName("le_download_base_path")
|
self.le_download_base_path.setObjectName("le_download_base_path")
|
||||||
sizePolicy2.setHeightForWidth(self.le_download_base_path.sizePolicy().hasHeightForWidth())
|
sizePolicy2.setHeightForWidth(self.le_download_base_path.sizePolicy().hasHeightForWidth())
|
||||||
self.le_download_base_path.setSizePolicy(sizePolicy2)
|
self.le_download_base_path.setSizePolicy(sizePolicy2)
|
||||||
self.le_download_base_path.setDragEnabled(True)
|
self.le_download_base_path.setDragEnabled(True)
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.le_download_base_path)
|
self.horizontalLayout_10.addWidget(self.le_download_base_path)
|
||||||
|
|
||||||
self.pb_download_base_path = QPushButton(self.gb_path)
|
self.pb_download_base_path = QPushButton(self.gb_path)
|
||||||
self.pb_download_base_path.setObjectName("pb_download_base_path")
|
self.pb_download_base_path.setObjectName("pb_download_base_path")
|
||||||
|
|
||||||
self.horizontalLayout_3.addWidget(self.pb_download_base_path)
|
self.horizontalLayout_10.addWidget(self.pb_download_base_path)
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
self.verticalLayout.addLayout(self.horizontalLayout_10)
|
||||||
|
|
||||||
self.horizontalLayout_7 = QHBoxLayout()
|
self.horizontalLayout_7 = QHBoxLayout()
|
||||||
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||||
@@ -450,22 +469,22 @@ class Ui_DialogSettings:
|
|||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_8)
|
self.verticalLayout.addLayout(self.horizontalLayout_8)
|
||||||
|
|
||||||
self.horizontalLayout_31 = QHBoxLayout()
|
self.horizontalLayout_3 = QHBoxLayout()
|
||||||
self.horizontalLayout_31.setObjectName("horizontalLayout_31")
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
self.le_path_binary_ffmpeg = QLineEdit(self.gb_path)
|
self.le_path_binary_ffmpeg = QLineEdit(self.gb_path)
|
||||||
self.le_path_binary_ffmpeg.setObjectName("le_path_binary_ffmpeg")
|
self.le_path_binary_ffmpeg.setObjectName("le_path_binary_ffmpeg")
|
||||||
sizePolicy2.setHeightForWidth(self.le_path_binary_ffmpeg.sizePolicy().hasHeightForWidth())
|
sizePolicy2.setHeightForWidth(self.le_path_binary_ffmpeg.sizePolicy().hasHeightForWidth())
|
||||||
self.le_path_binary_ffmpeg.setSizePolicy(sizePolicy2)
|
self.le_path_binary_ffmpeg.setSizePolicy(sizePolicy2)
|
||||||
self.le_path_binary_ffmpeg.setDragEnabled(True)
|
self.le_path_binary_ffmpeg.setDragEnabled(True)
|
||||||
|
|
||||||
self.horizontalLayout_31.addWidget(self.le_path_binary_ffmpeg)
|
self.horizontalLayout_3.addWidget(self.le_path_binary_ffmpeg)
|
||||||
|
|
||||||
self.pb_path_binary_ffmpeg = QPushButton(self.gb_path)
|
self.pb_path_binary_ffmpeg = QPushButton(self.gb_path)
|
||||||
self.pb_path_binary_ffmpeg.setObjectName("pb_path_binary_ffmpeg")
|
self.pb_path_binary_ffmpeg.setObjectName("pb_path_binary_ffmpeg")
|
||||||
|
|
||||||
self.horizontalLayout_31.addWidget(self.pb_path_binary_ffmpeg)
|
self.horizontalLayout_3.addWidget(self.pb_path_binary_ffmpeg)
|
||||||
|
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout_31)
|
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||||
|
|
||||||
self.horizontalLayout_2.addLayout(self.verticalLayout)
|
self.horizontalLayout_2.addLayout(self.verticalLayout)
|
||||||
|
|
||||||
@@ -501,6 +520,8 @@ class Ui_DialogSettings:
|
|||||||
self.cb_lyrics_embed.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
self.cb_lyrics_embed.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
||||||
self.cb_lyrics_file.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
self.cb_lyrics_file.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
||||||
self.cb_download_delay.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
self.cb_download_delay.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
||||||
|
self.cb_extract_flac.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
||||||
|
self.cb_downgrade_on_hi_res.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
|
||||||
self.gb_choices.setTitle(QCoreApplication.translate("DialogSettings", "Choices", None))
|
self.gb_choices.setTitle(QCoreApplication.translate("DialogSettings", "Choices", None))
|
||||||
self.l_icon_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
|
self.l_icon_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
|
||||||
self.l_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
|
self.l_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="lh_flags_1">
|
<layout class="QHBoxLayout" name="lh_flags_1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="lv_flags_video_download">
|
<layout class="QVBoxLayout" name="lv_flag_video_download">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cb_video_download">
|
<widget class="QCheckBox" name="cb_video_download">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="lv_flags_video_convert">
|
<layout class="QVBoxLayout" name="lv_flag_video_convert">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cb_video_convert_mp4">
|
<widget class="QCheckBox" name="cb_video_convert_mp4">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="lh_flags_2">
|
<layout class="QHBoxLayout" name="lh_flags_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="lh_flags_lyrics_embed">
|
<layout class="QHBoxLayout" name="lh_flag_lyrics_embed">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cb_lyrics_embed">
|
<widget class="QCheckBox" name="cb_lyrics_embed">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="lh_flags_lyrics_file">
|
<layout class="QHBoxLayout" name="lh_flag_lyrics_file">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cb_lyrics_file">
|
<widget class="QCheckBox" name="cb_lyrics_file">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -166,7 +166,36 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4"/>
|
<layout class="QVBoxLayout" name="lv_flag_extract_flac">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cb_extract_flac">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>CheckBox</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="lv_flag_downgrade_on_hi_res">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="cb_downgrade_on_hi_res">
|
||||||
|
<property name="text">
|
||||||
|
<string>CheckBox</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@@ -519,41 +548,41 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="lh_path_binary_ffmpeg">
|
<layout class="QHBoxLayout" name="lh_path_binary_ffmpeg">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="l_icon_path_binary_ffmpeg">
|
<widget class="QLabel" name="l_icon_path_binary_ffmpeg">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="l_path_binary_ffmpeg">
|
<widget class="QLabel" name="l_path_binary_ffmpeg">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="le_download_base_path">
|
<widget class="QLineEdit" name="le_download_base_path">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -619,29 +648,29 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="le_path_binary_ffmpeg">
|
<widget class="QLineEdit" name="le_path_binary_ffmpeg">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="dragEnabled">
|
<property name="dragEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pb_path_binary_ffmpeg">
|
<widget class="QPushButton" name="pb_path_binary_ffmpeg">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user