import gradio as gr import subprocess import uuid import os import re from utils import process_video # Bạn cần có utils.py với hàm này # Đảm bảo thư mục output tồn tại os.makedirs("outputs", exist_ok=True) # Biến tạm lưu đường dẫn video để xử lý sau downloaded_videos = {} def download_bilibili_video(url, output_dir="outputs"): filename = str(uuid.uuid4()) video_path = os.path.join(output_dir, f"{filename}.mp4") command = [ "yt-dlp", "-f", "bv+ba", "-o", video_path, url ] try: process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True ) percent = "0%" for line in process.stdout: match = re.search(r"(\d{1,3}\.\d)%", line) if match: percent = match.group(1) + "%" print(f"⬇️ Downloading: {percent}", flush=True) process.wait() if process.returncode != 0: return None, f"❌ Lỗi khi tải video (code {process.returncode})" return video_path, "✅ Đã tải xong video" except Exception as e: return None, f"❌ Exception: {str(e)}" def clear_outputs_folder(): folder = "outputs" count = 0 for f in os.listdir(folder): try: os.remove(os.path.join(folder, f)) count += 1 except Exception as e: print(f"❌ Lỗi khi xóa file {f}: {e}") downloaded_videos.clear() return None, None, f"🧹 Đã xoá {count} file trong thư mục outputs/" def step1_download(url): path, status = download_bilibili_video(url) if not path: return None, None, status # Lưu lại đường dẫn vào biến toàn cục downloaded_videos["last_video"] = path return os.path.relpath(path), None, status def step2_process(_): video_path = downloaded_videos.get("last_video") if not video_path or not os.path.exists(video_path): return None, None, "❌ Không tìm thấy video đã tải" try: processed = process_video(video_path) return None, os.path.relpath(processed), "✅ Đã xử lý thành công" except Exception as e: return None, None, f"❌ Lỗi khi xử lý video: {str(e)}" # Giao diện Gradio dùng Blocks with gr.Blocks() as demo: gr.Markdown("# 🎬 Bilibili Subtitle Translator") gr.Markdown("Tải video từ Bilibili, dịch thoại tiếng Trung sang tiếng Anh và chèn phụ đề.") url_input = gr.Textbox(label="🔗 Nhập URL video Bilibili") with gr.Row(): download_btn = gr.Button("⬇️ Tải video") process_btn = gr.Button("🛠️ Xử lý phụ đề") with gr.Row(): orig_video = gr.Video(label="🎞️ Video gốc") processed_video = gr.Video(label="📝 Video đã xử lý") status_output = gr.Textbox(label="📢 Trạng thái") clear_btn = gr.Button("🧹 Xoá thư mục outputs") # Sự kiện nút download_btn.click(fn=step1_download, inputs=url_input, outputs=[orig_video, processed_video, status_output]) process_btn.click(fn=step2_process, inputs=url_input, outputs=[orig_video, processed_video, status_output]) clear_btn.click(fn=clear_outputs_folder, inputs=[], outputs=[orig_video, processed_video, status_output]) if __name__ == "__main__": demo.launch()