yt-proxy / app.py
HeshamHaroon's picture
fix: add explicit api_name for Gradio Client calls
6965c32
"""YT Proxy — lightweight YouTube downloader for Mazinger Dubber."""
import os
import tempfile
import gradio as gr
import yt_dlp
def download_video(url: str) -> str:
"""Download a YouTube video and return the local file path."""
if not url or not url.strip():
raise gr.Error("Please provide a YouTube URL.")
tmp_dir = tempfile.mkdtemp(prefix="yt_proxy_")
output_template = os.path.join(tmp_dir, "%(title).50s.%(ext)s")
ydl_opts = {
"format": "bestvideo[height<=720][ext=mp4]+bestaudio[ext=m4a]/best[height<=720][ext=mp4]/best",
"outtmpl": output_template,
"merge_output_format": "mp4",
"quiet": True,
"no_warnings": True,
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
filename = ydl.prepare_filename(info)
# yt-dlp may change extension after merge
if not os.path.exists(filename):
for f in os.listdir(tmp_dir):
filename = os.path.join(tmp_dir, f)
break
return filename
except Exception as e:
raise gr.Error(f"Download failed: {e}")
def download_audio(url: str) -> str:
"""Download audio only from a YouTube video."""
if not url or not url.strip():
raise gr.Error("Please provide a YouTube URL.")
tmp_dir = tempfile.mkdtemp(prefix="yt_proxy_")
output_template = os.path.join(tmp_dir, "%(title).50s.%(ext)s")
ydl_opts = {
"format": "bestaudio/best",
"outtmpl": output_template,
"postprocessors": [{
"key": "FFmpegExtractAudio",
"preferredcodec": "mp3",
"preferredquality": "192",
}],
"quiet": True,
"no_warnings": True,
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
# Find the output file (may have .mp3 extension after postprocessing)
for f in os.listdir(tmp_dir):
return os.path.join(tmp_dir, f)
raise gr.Error("No output file found.")
except gr.Error:
raise
except Exception as e:
raise gr.Error(f"Download failed: {e}")
with gr.Blocks(title="YT Proxy") as demo:
gr.Markdown("## YT Proxy\nDownload YouTube videos/audio. Used by Mazinger Dubber.")
url_input = gr.Textbox(label="YouTube URL", placeholder="https://youtube.com/watch?v=...")
with gr.Row():
video_btn = gr.Button("Download Video (MP4)")
audio_btn = gr.Button("Download Audio (MP3)")
output_file = gr.File(label="Downloaded file")
video_btn.click(fn=download_video, inputs=url_input, outputs=output_file, api_name="download_video")
audio_btn.click(fn=download_audio, inputs=url_input, outputs=output_file, api_name="download_audio")
demo.queue().launch()