import gradio as gr from PIL import Image, ImageDraw, ImageFont from moviepy.editor import ImageClip, concatenate_videoclips import os def create_video(word_list): # Thay vì cố gắng lấy font từ tệp .ttf, ta sẽ dùng font mặc định font_size = 60 # Tăng kích thước chữ lên 5 lần try: # Nếu có tệp font cụ thể, hãy cung cấp nó ở đây font_path = "ARIAL.TTF" # Đường dẫn tới font của bạn (nếu có) font = ImageFont.truetype(font_path, font_size) except OSError: # Nếu không tìm thấy font, sử dụng font mặc định của PIL print("Không tìm thấy tệp font, đang sử dụng font mặc định.") font = ImageFont.load_default() # Định nghĩa kích thước hình ảnh và màu nền width, height = 800, 600 # Kích thước hình ảnh background_color = (255, 255, 255) # Màu nền trắng text_color = (0, 0, 0) # Màu chữ đen # Tạo danh sách các slide (ảnh) slide_images = [] words = word_list # Sử dụng danh sách từ đã được truyền vào for word, phonetic in words: # Tạo một hình ảnh mới với màu nền img = Image.new("RGB", (width, height), background_color) draw = ImageDraw.Draw(img) # Sử dụng font mặc định nếu không tìm thấy font cụ thể # font = ImageFont.truetype(font_path, font_size) # Bỏ dòng này nếu không cần font cụ thể # Sử dụng textbbox để đo kích thước từ và phiên âm word_text_bbox = draw.textbbox((0, 0), word, font=font) phonetic_text_bbox = draw.textbbox((0, 0), phonetic, font=font) # Tính toán vị trí để căn giữa từ và phiên âm word_position = ((width - (word_text_bbox[2] - word_text_bbox[0])) // 2, (height - (word_text_bbox[3] - word_text_bbox[1])) // 2 - 50) phonetic_position = ((width - (phonetic_text_bbox[2] - phonetic_text_bbox[0])) // 2, word_position[1] + (word_text_bbox[3] - word_text_bbox[1]) + 20) # Vẽ từ và phiên âm lên hình ảnh draw.text(word_position, word, font=font, fill=text_color) draw.text(phonetic_position, phonetic, font=font, fill=text_color) # Lưu hình ảnh vào danh sách slide_images.append(img) # Lưu từng hình ảnh vào tạm thời và tạo video clips = [] for i, img in enumerate(slide_images): img_path = f"slide_{i}.png" img.save(img_path) # Tạo một ImageClip từ ảnh với thời lượng 3 giây clip = ImageClip(img_path).set_duration(3) clips.append(clip) # Ghép các clip lại thành video video = concatenate_videoclips(clips, method="compose") video_path = "output_video.mp4" video.write_videofile(video_path, fps=24) # Trả về đường dẫn tới video đã tạo return video_path # Hàm nhận danh sách từ từ input của Gradio def process_input(input_text): # Tách chuỗi input thành các từ và phiên âm, mỗi từ trên 1 dòng word_list = [] lines = input_text.strip().split("\n") for line in lines: if line.strip(): word, phonetic = line.split(",") word_list.append((word.strip(), phonetic.strip())) # Tạo video từ danh sách từ return create_video(word_list) # Tạo giao diện Gradio description = "Nhập danh sách từ và phiên âm, mỗi dòng gồm từ và phiên âm cách nhau bằng dấu phẩy. Ví dụ: Atmosphere, [ˈætməsfɪə]" with gr.Blocks() as demo: gr.Markdown("# Tạo Video từ Danh Sách Từ") gr.Markdown(description) input_text = gr.Textbox(label="Danh sách từ", placeholder="Ví dụ:\nAtmosphere, [ˈætməsfɪə]\nBoard, [bɔːd]...") video_output = gr.Video(label="Video đầu ra") generate_button = gr.Button("Tạo video") generate_button.click(fn=process_input, inputs=input_text, outputs=video_output) # Chạy ứng dụng Gradio demo.launch()