import os import tempfile import gradio as gr import yt_dlp def get_formats(url): if not url or not url.strip(): return gr.update(choices=[], value=None) try: ydl_opts = { "quiet": True, "noplaylist": True, "skip_download": True, } with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(url, download=False) formats = [] for f in info.get("formats", []): format_id = f.get("format_id") if not format_id: continue ext = f.get("ext", "unknown") resolution = ( f.get("resolution") or f.get("format_note") or ("audio" if f.get("vcodec") == "none" else "unknown") ) formats.append((f"{format_id} - {ext} - {resolution}", format_id)) return gr.update(choices=formats, value=formats[0][1] if formats else None) except Exception as e: raise gr.Error(f"Không lấy được format: {e}") def download_video(url, format_id): if not url or not url.strip(): raise gr.Error("Vui lòng nhập URL.") if not format_id: raise gr.Error("Vui lòng chọn format.") temp_dir = tempfile.mkdtemp() ydl_opts = { "format": format_id, "outtmpl": os.path.join(temp_dir, "%(title)s.%(ext)s"), "quiet": True, "noplaylist": True, } try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(url, download=True) filename = ydl.prepare_filename(info) if not os.path.exists(filename): raise gr.Error("Không tìm thấy file sau khi tải.") return filename, filename except Exception as e: raise gr.Error(f"Tải thất bại: {e}") with gr.Blocks() as demo: gr.Markdown("## Audio/Video Downloader with Preview") gr.Markdown("Chỉ dùng với nội dung bạn có quyền tải và sử dụng.") url_input = gr.Textbox(label="Video URL", placeholder="Paste URL here") format_dropdown = gr.Dropdown(label="Select format", choices=[]) load_btn = gr.Button("Load Formats") download_btn = gr.Button("Download") output_file = gr.File(label="Download File") output_video = gr.Video(label="Preview Media") load_btn.click(get_formats, inputs=url_input, outputs=format_dropdown) download_btn.click( download_video, inputs=[url_input, format_dropdown], outputs=[output_file, output_video], ) if __name__ == "__main__": demo.launch(ssr_mode=False)