|
import gradio as gr |
|
import subprocess |
|
import uuid |
|
import os |
|
import re |
|
from utils import process_video |
|
|
|
|
|
os.makedirs("outputs", exist_ok=True) |
|
|
|
|
|
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 |
|
|
|
|
|
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)}" |
|
|
|
|
|
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") |
|
|
|
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() |
|
|