diff --git a/backend/app/services/download.py b/backend/app/services/download.py index c28afe4..f4ffedf 100644 --- a/backend/app/services/download.py +++ b/backend/app/services/download.py @@ -45,6 +45,8 @@ def _base_opts() -> dict: shutil.copy2(COOKIES_FILE, tmp.name) tmp.close() opts["cookiefile"] = tmp.name + # Enable remote EJS challenge solver for YouTube + opts["extractor_args"] = {"youtube": {"player_client": ["default", "web_creator"]}} return opts diff --git a/backend/app/workers/tasks.py b/backend/app/workers/tasks.py index d777995..708edd8 100644 --- a/backend/app/workers/tasks.py +++ b/backend/app/workers/tasks.py @@ -76,7 +76,15 @@ async def process_job(ctx: dict, job_id: str): os.makedirs(job_media_dir, exist_ok=True) if job.source_type == "youtube": - video_info = await download.download_video(job.source_url, job_media_dir) + try: + video_info = await download.download_video(job.source_url, job_media_dir) + except Exception as dl_err: + if "Sign in to confirm" in str(dl_err) or "bot" in str(dl_err): + raise ValueError( + "YouTube blocked this download (bot detection). " + "Try uploading the video file directly instead." + ) + raise job.title = video_info.title job.duration = video_info.duration job.media_path = video_info.video_path