HeshamHaroon commited on
Commit
baf044b
·
1 Parent(s): 416a974

feat: YouTube support via yt-proxy helper Space

Browse files

- YouTube URLs detected by regex, routed to HeshamHaroon/yt-proxy Space
- Proxy runs on free CPU, downloads video, returns file via Gradio Client
- ZeroGPU Space connects via huggingface.co API (DNS accessible)
- Non-YouTube URLs still use direct yt-dlp download
- Updated UI labels to reflect YouTube support

Files changed (2) hide show
  1. app.py +2 -2
  2. pipeline_runner.py +24 -1
app.py CHANGED
@@ -283,11 +283,11 @@ with gr.Blocks(
283
  gr.Markdown("### SOURCE")
284
  source_url = gr.Textbox(
285
  label="Video URL",
286
- placeholder="Direct video/audio URL (or YouTube if network allows)...",
287
  lines=1,
288
  max_lines=2,
289
  )
290
- gr.Markdown("<center style='color:var(--text-secondary);font-size:0.85rem'>Upload recommended YouTube may be blocked on ZeroGPU</center>")
291
  source_upload = gr.File(
292
  label="Upload video or audio",
293
  file_types=["video", "audio"],
 
283
  gr.Markdown("### SOURCE")
284
  source_url = gr.Textbox(
285
  label="Video URL",
286
+ placeholder="YouTube URL or direct video/audio link...",
287
  lines=1,
288
  max_lines=2,
289
  )
290
+ gr.Markdown("<center style='color:var(--text-secondary);font-size:0.85rem'>YouTube links download via proxy or upload directly</center>")
291
  source_upload = gr.File(
292
  label="Upload video or audio",
293
  file_types=["video", "audio"],
pipeline_runner.py CHANGED
@@ -14,11 +14,15 @@ import time
14
  from typing import Any, Generator
15
 
16
  import spaces # provided by HF ZeroGPU runtime
 
17
 
18
  # ---------------------------------------------------------------------------
19
  # Constants
20
  # ---------------------------------------------------------------------------
21
 
 
 
 
22
  HF_TOKEN: str = os.environ.get("HF_TOKEN", "")
23
  LLM_BASE_URL: str = "https://router.huggingface.co/v1"
24
  LLM_MODEL_TEXT: str = "Qwen/Qwen2.5-72B-Instruct"
@@ -68,6 +72,20 @@ def _make_client(model: str = LLM_MODEL_TEXT):
68
  return build_client(api_key=HF_TOKEN, base_url=LLM_BASE_URL)
69
 
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  # ---------------------------------------------------------------------------
72
  # Helper: call with exponential backoff on 429
73
  # ---------------------------------------------------------------------------
@@ -285,7 +303,12 @@ def run_pipeline(
285
 
286
  try:
287
  if download.is_url(source):
288
- download.download_video(source, proj.video)
 
 
 
 
 
289
  download.extract_audio(proj.video, proj.audio)
290
  elif download.is_audio_file(source):
291
  download.ingest_local_audio(source, proj.audio)
 
14
  from typing import Any, Generator
15
 
16
  import spaces # provided by HF ZeroGPU runtime
17
+ import re
18
 
19
  # ---------------------------------------------------------------------------
20
  # Constants
21
  # ---------------------------------------------------------------------------
22
 
23
+ YT_PROXY_SPACE = "HeshamHaroon/yt-proxy"
24
+ _YT_RE = re.compile(r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/shorts/)([a-zA-Z0-9_-]{11})')
25
+
26
  HF_TOKEN: str = os.environ.get("HF_TOKEN", "")
27
  LLM_BASE_URL: str = "https://router.huggingface.co/v1"
28
  LLM_MODEL_TEXT: str = "Qwen/Qwen2.5-72B-Instruct"
 
72
  return build_client(api_key=HF_TOKEN, base_url=LLM_BASE_URL)
73
 
74
 
75
+ def _is_youtube_url(url: str) -> bool:
76
+ return bool(_YT_RE.search(url))
77
+
78
+
79
+ def _download_via_proxy(url: str, output_path: str) -> str:
80
+ """Download a YouTube video via the yt-proxy helper Space."""
81
+ from gradio_client import Client
82
+ client = Client(YT_PROXY_SPACE, hf_token=HF_TOKEN)
83
+ result = client.predict(url=url, api_name="/download_video")
84
+ # result is a file path on the proxy; gradio_client downloads it locally
85
+ shutil.copy2(result, output_path)
86
+ return output_path
87
+
88
+
89
  # ---------------------------------------------------------------------------
90
  # Helper: call with exponential backoff on 429
91
  # ---------------------------------------------------------------------------
 
303
 
304
  try:
305
  if download.is_url(source):
306
+ if _is_youtube_url(source):
307
+ # YouTube: use proxy Space (ZeroGPU blocks youtube.com DNS)
308
+ yield stage, f"[{STAGE_NAMES[stage - 1]}] Downloading via YouTube proxy...", {}
309
+ _download_via_proxy(source, proj.video)
310
+ else:
311
+ download.download_video(source, proj.video)
312
  download.extract_audio(proj.video, proj.audio)
313
  elif download.is_audio_file(source):
314
  download.ingest_local_audio(source, proj.audio)