From 9a5deeefed733ae59d2210fa70575418939588f0 Mon Sep 17 00:00:00 2001 From: DARKZOUL5 Date: Mon, 19 Oct 2026 23:26:44 +0300 Subject: [PATCH] fix: support separate yt-dlp video and audio streams --- src/app/core/download/downloader.py | 12 +++++------- tests/test_download_quality_format.py | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/core/download/downloader.py b/src/app/core/download/downloader.py index 1168216..30951d6 100644 --- a/src/app/core/download/downloader.py +++ b/src/app/core/download/downloader.py @@ -42,9 +42,9 @@ class Downloader: cap = parse_height_cap(max_download_quality) if cap is not None: - #if the requested cap isn't available, we still download the best mp4. - return f"best[ext=mp4][acodec!=none][vcodec!=none][height<={cap}]/best[ext=mp4][height<={cap}]/best[ext=mp4]" - return "best[ext=mp4][acodec!=none][vcodec!=none]/best[ext=mp4]" + # Prefer separate MP4 video and audio streams; yt-dlp merges them with ffmpeg. + return f"bestvideo[ext=mp4][height<={cap}]+bestaudio[ext=m4a]/bestvideo[ext=mp4][height<={cap}]+bestaudio/bestvideo[ext=mp4][height<={cap}]/best[ext=mp4]" + return "bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo[ext=mp4]+bestaudio/bestvideo[ext=mp4]/best[ext=mp4]" async def handle_job(self, job: DownloadJob): try: @@ -97,10 +97,8 @@ class Downloader: fmt = self.build_format(getattr(job, "max_download_quality", None)) - # All modes download a single muxed mp4 when possible. - # This avoids any ffmpeg-driven merging during the download step, satisfying: - # - video: "original file, no processing" - # - audio/both: extraction is done separately after download + # Prefer MP4 video with a separate audio stream; yt-dlp merges them when needed. + # Audio extraction for audio/both modes happens separately after download. ydl_opts = { "format": fmt, "outtmpl": outtmpl, diff --git a/tests/test_download_quality_format.py b/tests/test_download_quality_format.py index a4b8a05..d0f87e7 100644 --- a/tests/test_download_quality_format.py +++ b/tests/test_download_quality_format.py @@ -6,10 +6,12 @@ from app.core.download.downloader import Downloader def test_build_format_defaults_to_best_mp4(): fmt = Downloader.build_format(None) assert "height<=1080" in fmt + assert "bestvideo[ext=mp4][height<=1080]+bestaudio" in fmt assert fmt.endswith("/best[ext=mp4]") def test_build_format_applies_height_cap(): fmt = Downloader.build_format("720p") + assert "bestvideo[ext=mp4]" in fmt assert "height<=720" in fmt