diff --git a/app/worker.py b/app/worker.py index bfac00b..56d2237 100644 --- a/app/worker.py +++ b/app/worker.py @@ -38,17 +38,42 @@ def sanitize(name): return re.sub(r'[\\/:"*?<>|]+', ' ', name).strip() def yt_dlp(url, outdir): + # 1) Normalize YouTube Music URLs to standard YouTube + yurl = url + if 'music.youtube.com' in yurl: + yurl = yurl.replace('music.youtube.com', 'www.youtube.com') + outtmpl = str(outdir / "%(uploader)s/%(upload_date)s - %(title)s.%(ext)s") - cmd = [ + + base_cmd = [ "yt-dlp", "-o", outtmpl, "-f", "bv*+ba/best", "-x", "--audio-format", "m4a", "--write-thumbnail", "--no-playlist", "--no-warnings", "--restrict-filenames", - url ] - subprocess.check_call(cmd) - media = list(outdir.rglob("*.[mM][pP]4")) + list(outdir.rglob("*.mkv")) + list(outdir.rglob("*.m4a")) + list(outdir.rglob("*.mp3")) + + # 3) Optional cookies (set YTDLP_COOKIES=/path/to/cookies.txt in .env and mount it) + cookies_path = os.getenv("YTDLP_COOKIES", "").strip() + if cookies_path: + base_cmd += ["--cookies", cookies_path] + + # Primary attempt + try: + subprocess.check_call(base_cmd + [yurl]) + except subprocess.CalledProcessError: + # 2) Retry with Android client + mobile UA + retry_cmd = base_cmd + [ + "--extractor-args", "youtube:player_client=android", + "--user-agent", "Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Mobile Safari/537.36", + yurl, + ] + subprocess.check_call(retry_cmd) + + media = (list(outdir.rglob("*.[mM][pP]4")) + + list(outdir.rglob("*.mkv")) + + list(outdir.rglob("*.m4a")) + + list(outdir.rglob("*.mp3"))) return sorted(media, key=lambda p: p.stat().st_mtime)[-1:] def transcribe(media_path: Path):