File size: 8,541 Bytes
4fcacf9
 
 
 
 
 
 
 
 
 
50cde60
 
4fcacf9
 
50cde60
 
4fcacf9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50cde60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08ae9e1
 
 
 
47229c4
 
 
 
 
 
 
 
 
 
 
50cde60
 
 
 
 
47229c4
 
50cde60
 
47229c4
50cde60
 
 
 
08ae9e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50cde60
08ae9e1
 
50cde60
 
 
 
 
 
 
 
 
 
 
08ae9e1
50cde60
 
 
 
 
 
08ae9e1
 
50cde60
 
 
 
 
 
08ae9e1
 
 
 
 
53bf813
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import asyncio
import mimetypes
import os
import tempfile
import fitz  # PyMuPDF
import random
import gradio as gr
from docx import Document
from content_generation import create_content, CONTENT_TYPES
from openai import OpenAI
from gradio_client import Client, handle_file
import subprocess

# Khởi tạo client OpenAI với API key từ biến môi trường
client_openai = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
client_vixtts = Client("thinhlpg/vixtts-demo")

def create_docx(content, output_path):
    """
    Tạo file docx từ nội dung.
    """
    doc = Document()
    doc.add_paragraph(content)
    doc.save(output_path)

def process_pdf(file_path):
    """
    Xử lý file PDF và trích xuất nội dung.
    """
    doc = fitz.open(file_path)
    text = ""
    for page in doc:
        text += page.get_text()
    return text

def process_docx(file_path):
    """
    Xử lý file DOCX và trích xuất nội dung.
    """
    doc = Document(file_path)
    text = ""
    for para in doc.paragraphs:
        text += para.text
    return text

def convert_text_to_speech(text, language='vi'):
    """
    Chuyển đổi văn bản thành giọng nói.
    """
    result = client_vixtts.predict(
        prompt=text,
        language=language,
        audio_file_pth=handle_file(''),
        normalize_text=True,
        api_name="/predict"
    )
    return result.audio_file_pth

def create_video(audio_file, mc_choice, text_color, output_video="output.mp4"):
    """
    Tạo video với người MC dẫn chương trình.
    """
    # Chọn file video nền dựa trên lựa chọn MC
    background_videos = {
        "MC1": "mc1_background.mp4",
        "MC2": "mc2_background.mp4",
        "MC3": "mc3_background.mp4",
        "MC4": "mc4_background.mp4"
    }
    background_video = background_videos.get(mc_choice, "mc1_background.mp4")  # Mặc định là MC1 nếu không tìm thấy
    
    # Định nghĩa văn bản trên video
    text_on_video = f"MC: {mc_choice}"
    
    # Định nghĩa màu sắc chữ
    color_map = {
        "Trắng": "white",
        "Đỏ": "red",
        "Xanh dương": "blue",
        "Xanh lá": "green",
        "Vàng": "yellow"
    }
    font_color = color_map.get(text_color, "white")  # Mặc định là trắng nếu không tìm thấy
    
    # Lệnh ffmpeg để tạo video
    command = [
        "ffmpeg",
        "-stream_loop", "-1",  # Lặp lại video nền vô hạn
        "-i", background_video,  # Video nền (tùy thuộc vào MC)
        "-i", audio_file,      # File audio đầu vào
        "-vf", f"drawtext=text='{text_on_video}':fontcolor={font_color}:fontsize=50:fontfile=/path/to/font.ttf:x=(w-text_w)/2:y=10:box=1:[email protected]:boxborderw=5",  # Văn bản trên video
        "-t", "45.7",          # Thời lượng video
        "-c:v", "libx264",     # Codec video
        "-c:a", "aac",         # Codec audio
        "-shortest",           # Dừng khi audio kết thúc
        "-y",                  # Ghi đè file nếu tồn tại
        output_video           # File video đầu ra
    ]
    # Chạy lệnh ffmpeg
    subprocess.run(command, check=True)
    return output_video

def interface():
    with gr.Blocks() as app:
        gr.Markdown("# Ứng dụng Tạo Nội dung và Video")
        with gr.Tab("Tạo Nội dung"):
            with gr.Row():
                with gr.Column():
                    prompt = gr.Textbox(label="Nhập yêu cầu nội dung")
                    file_upload = gr.File(label="Tải lên file kèm theo", type="filepath")
                    content_type = gr.Radio(label="Chọn loại nội dung",
                                            choices=CONTENT_TYPES,
                                            value=None)  # Giá trị mặc định là không có gì được chọn
                    content_button = gr.Button("Tạo Nội dung")
                
                with gr.Column():
                    content_output = gr.Textbox(label="Nội dung tạo ra", interactive=True)
                    use_generated_text = gr.Checkbox(label="Sử dụng văn bản được tạo bởi LLM", value=True)
                    manual_text_input = gr.Textbox(label="Nhập văn bản thủ công", visible=False)
                    language = gr.Dropdown(label="Chọn ngôn ngữ", choices=["vi", "en"], value="vi")
                    mc_choice = gr.Dropdown(label="Chọn MC", choices=["MC1", "MC2", "MC3", "MC4"], value="MC1")
                    text_color = gr.Dropdown(label="Chọn màu chữ", choices=["Trắng", "Đỏ", "Xanh dương", "Xanh lá", "Vàng"], value="Trắng")
                    confirm_button = gr.Button("Xác nhận nội dung")
                    download_docx = gr.File(label="Tải xuống file DOCX", interactive=False)
                    download_audio = gr.File(label="Tải xuống file âm thanh", interactive=False)
                    download_video = gr.File(label="Tải xuống file video", interactive=False)
                    status_message = gr.Label(label="Trạng thái")
            
            def toggle_manual_text(use_generated_text):
                return not use_generated_text
            
            def generate_content(prompt, file, content_type):
                try:
                    status = "Đang xử lý..."
                    if file and os.path.exists(file):
                        mime_type, _ = mimetypes.guess_type(file)
                        if mime_type == "application/pdf":
                            file_content = process_pdf(file)
                            prompt = f"{prompt}\n\nDưới đây là nội dung của file tài liệu:\n\n{file_content}"
                        elif mime_type in (
                            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                            "application/msword"):
                            file_content = process_docx(file)
                            prompt = f"{prompt}\n\nDưới đây là nội dung của file tài liệu:\n\n{file_content}"
                        else:
                            raise ValueError("Định dạng file không được hỗ trợ.")
                    if not content_type:
                        raise ValueError("Vui lòng chọn một loại nội dung")
                    script_content = create_content(prompt, content_type, "Tiếng Việt")
                    docx_path = "script.docx"
                    create_docx(script_content, docx_path)
                    status = "Đã tạo nội dung thành công!"
                    return script_content, docx_path, True, None, status
                except Exception as e:
                    status = f"Đã xảy ra lỗi: {str(e)}"
                    return "", None, True, None, status
            
            async def confirm_content(content_output, use_generated_text, manual_text_input, language, mc_choice, text_color):
                if use_generated_text:
                    text_to_convert = content_output
                else:
                    text_to_convert = manual_text_input
                
                if not text_to_convert:
                    return None, None, None, "Vui lòng cung cấp văn bản để chuyển đổi."
                
                docx_path = "script.docx"
                create_docx(text_to_convert, docx_path)
                audio_path = convert_text_to_speech(text_to_convert, language)
                video_path = create_video(audio_path, mc_choice, text_color)
                return docx_path, audio_path, video_path, "Đã xác nhận và tạo video thành công!"
            
            use_generated_text.change(toggle_manual_text, inputs=[use_generated_text], outputs=[manual_text_input.visible])
            content_button.click(generate_content,
                                 inputs=[prompt, file_upload, content_type],
                                 outputs=[content_output, download_docx, use_generated_text, manual_text_input, status_message])
            
            confirm_button.click(confirm_content,
                                 inputs=[content_output, use_generated_text, manual_text_input, language, mc_choice, text_color],
                                 outputs=[download_docx, download_audio, download_video, status_message])
    
    return app

# Khởi chạy ứng dụng
if __name__ == "__main__":
    app = interface()
    app.launch(share=True)