1
0
mirror of https://github.com/darkzoul5/YoutubePlaylistSync.git synced 2026-07-03 12:34:00 +03:00

Refactor mode "both" in PlaylistDownloader: video is downloaded then audio extracted using ffmpeg.

This commit is contained in:
2025-10-15 21:13:15 +03:00
parent 6203fd36c0
commit 93cd9a0fe0
+35 -32
View File
@@ -308,30 +308,7 @@ class PlaylistDownloader:
cmds.append((args, f"{track_index:03d} - {title} (video)")) cmds.append((args, f"{track_index:03d} - {title} (video)"))
elif self.download_mode == "both": elif self.download_mode == "both":
# audio folder # Download video first into video folder
audio_folder = self.save_path / "audio"
audio_folder.mkdir(parents=True, exist_ok=True)
audio_output = audio_folder / f"{track_index:03d} - {safe_title}.mp3"
audio_args = [
str(self.yt_dlp),
"-f", "bestaudio",
"--extract-audio",
"--audio-format", "mp3",
"--audio-quality", "0",
]
if not shutil.which(str(self.ffmpeg)):
audio_args += ["--ffmpeg-location", str(self.ffmpeg)]
audio_args += [
"--download-archive", str(self.archive),
"-o", str(audio_output),
"--external-downloader", str(self.aria2c),
"--external-downloader-args",
f"aria2c:-x {self.aria2c_connections} -s {self.aria2c_connections}",
video_url
]
cmds.append((audio_args, f"{track_index:03d} - {title} (audio)"))
# video folder
video_folder = self.save_path / "video" video_folder = self.save_path / "video"
video_folder.mkdir(parents=True, exist_ok=True) video_folder.mkdir(parents=True, exist_ok=True)
video_output = video_folder / f"{track_index:03d} - {safe_title}.mp4" video_output = video_folder / f"{track_index:03d} - {safe_title}.mp4"
@@ -340,18 +317,44 @@ class PlaylistDownloader:
str(self.yt_dlp), str(self.yt_dlp),
"-f", fmt, "-f", fmt,
"--merge-output-format", "mp4", "--merge-output-format", "mp4",
]
if not shutil.which(str(self.ffmpeg)):
video_args += ["--ffmpeg-location", str(self.ffmpeg)]
video_args += [
"--download-archive", str(self.archive), "--download-archive", str(self.archive),
"-o", str(video_output), "-o", str(video_output),
"--external-downloader", str(self.aria2c), "--external-downloader", str(self.aria2c),
"--external-downloader-args", "--external-downloader-args", f"aria2c:-x {self.aria2c_connections} -s {self.aria2c_connections}",
f"aria2c:-x {self.aria2c_connections} -s {self.aria2c_connections}", video_url,
video_url
] ]
cmds.append((video_args, f"{track_index:03d} - {title} (video)")) if not shutil.which(str(self.ffmpeg)):
# allow yt-dlp to find ffmpeg via --ffmpeg-location if configured as a path
video_args.insert(0, str(self.yt_dlp))
# if ffmpeg is an explicit path, yt-dlp will use it; we keep behavior consistent
try:
subprocess.run(video_args, check=True)
except subprocess.CalledProcessError as e:
err = (e.stderr or "").strip()
print(f"{FAIL} Video download failed: {title}{err}")
return False
# extract audio with ffmpeg into audio folder
audio_folder = self.save_path / "audio"
audio_folder.mkdir(parents=True, exist_ok=True)
audio_output = audio_folder / f"{track_index:03d} - {safe_title}.mp3"
# prefer configured ffmpeg path, fallback to system ffmpeg
ffmpeg_exe = str(self.ffmpeg)
if not (shutil.which(ffmpeg_exe) or Path(ffmpeg_exe).is_file()):
ffmpeg_exe = shutil.which("ffmpeg") or ffmpeg_exe
if ffmpeg_exe:
ffmpeg_cmd = [ffmpeg_exe, "-y", "-i", str(video_output), "-vn", "-codec:a", "libmp3lame", "-q:a", "0", str(audio_output)]
try:
subprocess.run(ffmpeg_cmd, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f"{WARN} ffmpeg failed to extract audio for {title}: {(e.stderr or '').strip()}")
else:
print(f"{WARN} ffmpeg not found; audio not extracted for {title}.")
print(f"{OK} Downloaded video and extracted audio for: {track_index:03d} - {title}")
return True
else: else:
print(f"{FAIL} Invalid download_mode '{self.download_mode}', skipping") print(f"{FAIL} Invalid download_mode '{self.download_mode}', skipping")