GV-a / app.py
TDN-M's picture
Update app.py
50cde60 verified
raw
history blame
8.54 kB
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)