File size: 9,746 Bytes
2e13c1a 93931c2 2e13c1a d575794 2e13c1a 31e2fdc 4a85ea2 31e2fdc 2e13c1a 31e2fdc 2e13c1a 31e2fdc 2e13c1a c021d14 2e13c1a fbc159c 2d01678 2b48802 f1000eb b0ce6eb 38103d4 b0ce6eb f1000eb 966861e fbc159c f072d45 38103d4 e02c2b9 f072d45 451d3ce e02c2b9 f072d45 38103d4 3e677d8 451d3ce e02c2b9 |
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 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
from huggingface_hub import InferenceClient
from pydub import AudioSegment
import gradio as gr
import datetime
import edge_tts
import asyncio
import os
import subprocess
def create_video(audio_file, turn, output_video="output.mp4"):
# Chọn file video nền dựa trên lượt
background_video = "missVN.mp4" if turn == "Miss AI Vietnam" else "missCN.mp4"
# 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 lượt)
"-i", audio_file, # File audio đầu vào
"-vf", "drawtext=text='MISS AI':fontcolor=white:fontsize=100:fontfile=/path/to/font.ttf:x=10:y=10", # 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
# Khởi tạo các mô hình từ Hugging Face
MissAIVietnam = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
MissAIChina = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
# Biến toàn cục để lưu trữ chủ đề, vị trí và lịch sử tranh luận
topic = None
position_1 = None
position_2 = None
turn = None
history = []
audio_files = [] # Danh sách lưu trữ các file audio
# Hàm để tạo phản hồi tranh luận
def generate_response(llm, position, who, topic, message):
# Xác định hướng dẫn cụ thể cho từng bên
if who == "Miss AI Vietnam":
system_message = {
"role": "system",
"content": f"You are Miss AI Vietnam, tasked with defending the position '{position}' on the topic '{topic}'. "
f"Only write the spoken content, without any notes or explanations. Your answer should be concise, logical and convincing, focusing on the topic and also trying to exploit the opponent's weak points to give insightful counter-arguments."
f"Ensure that your responses are thoughtful, evidence-based, and persuasive. Keep them concise—aim for 4 to 5 lines in a single paragraph, with the entire response not exceeding 100 words. "
}
elif who == "Miss AI China":
system_message = {
"role": "system",
"content": f"You are Miss AI China, tasked with defending the position '{position}' on the topic '{topic}'. "
f"Your responses must be concise, logical, and persuasive, with a focus on economic and technological perspectives. "
f"Ensure that your responses are thoughtful, evidence-based, and persuasive. Keep them concise—aim for 4 to 5 lines in a single paragraph, with the entire response not exceeding 100 words. "
f"Only write the spoken content, without any notes or explanations."
}
else:
raise ValueError("Invalid participant name.")
# Thêm tin nhắn hệ thống và tin nhắn người dùng vào danh sách messages
messages = [system_message]
messages.append({"role": "user", "content": message})
# Tạo phản hồi từ mô hình
response = f"{who}:\n"
for message_chunk in llm.chat_completion(
messages, max_tokens=256, stream=True, temperature=0.4, top_p=0.95):
response += message_chunk.choices[0].delta.content
return response
# Hàm để chuyển văn bản thành âm thanh bằng edge_tts
async def text_to_speech(text, voice, output_file="output.mp3"):
communicate = edge_tts.Communicate(text, voice) # Chọn giọng nói
await communicate.save(output_file)
return output_file
# Hàm để tạo file audio final
def concatenate_audio_files(audio_files, output_file="final_debate.mp3"):
if not audio_files:
return None
# Tạo một đối tượng AudioSegment rỗng
final_audio = AudioSegment.empty()
# Nối từng file audio vào final_audio
for audio_file in audio_files:
audio_segment = AudioSegment.from_file(audio_file)
final_audio += audio_segment
# Xuất file audio cuối cùng
final_audio.export(output_file, format="mp3")
return output_file
# Hàm để bắt đầu tranh luận giữa Miss AI Vietnam và Miss AI China
def start_debate(topic, position_1, position_2):
global turn, history, audio_files
if not topic or not position_1 or not position_2:
return "Please provide the debate topic and positions for both participants.", [], None, None
# Đảm bảo các vị trí là đối lập
if position_1 == position_2:
return "The positions of both participants must be opposite. Please adjust them.", [], None, None
turn = "Miss AI Vietnam"
history = [] # Đặt lại lịch sử
audio_files = [] # Đặt lại danh sách file audio
initial_message = "Opening Statement"
response = generate_response(MissAIVietnam, position_1, 'Miss AI Vietnam', topic, initial_message)
history.append((initial_message, response))
# Chuyển văn bản thành âm thanh với giọng của Miss AI Vietnam
output_audio = asyncio.run(text_to_speech(response, "en-US-JennyNeural")) # Giọng nữ tiếng Anh Mỹ
audio_files.append(output_audio) # Thêm file audio vào danh sách
# Tạo video từ audio và lượt hiện tại
output_video = create_video(output_audio, turn)
return f"The debate has started! {turn} begins.", history, output_video, output_audio
# Hàm để chuyển lượt trong tranh luận
def next_turn(topic, position_1, position_2, current_history):
global turn, history, audio_files
if not current_history:
return "No ongoing debate. Please start a debate first.", [], None, None
# Logic chuyển lượt
if turn == "Miss AI Vietnam":
turn = "Miss AI China"
llm, position, who = MissAIChina, position_2, 'Miss AI China'
voice = "en-GB-LibbyNeural" # Giọng nữ tiếng Anh Anh
else:
turn = "Miss AI Vietnam"
llm, position, who = MissAIVietnam, position_1, "Miss AI Vietnam"
voice = "en-US-JennyNeural" # Giọng nữ tiếng Anh Mỹ
last_response = current_history[-1][1] # Lấy tin nhắn cuối cùng
response = generate_response(llm, position, who, topic, last_response)
history.append(("", response)) # Thêm phản hồi vào lịch sử
# Chuyển văn bản thành âm thanh với giọng tương ứng
output_audio = asyncio.run(text_to_speech(response, voice))
audio_files.append(output_audio) # Thêm file audio vào danh sách
# Tạo video từ audio và lượt hiện tại
output_video = create_video(output_audio, turn)
return f"It's now {turn}'s turn.", history, output_video, output_audio
# Hàm để kết thúc tranh luận và nối các file audio
def end_debate():
global audio_files
if not audio_files:
return "No debate audio found.", None
# Nối các file audio thành một file duy nhất
final_audio_file = concatenate_audio_files(audio_files)
return "The debate has ended. Here is the full debate audio.", final_audio_file
# Interface
with gr.Blocks(theme=gr.themes.Soft(font=[gr.themes.GoogleFont("Roboto Mono")])) as demo:
gr.Markdown("# Welcome to The Miss World AI 🗣️🤖")
with gr.Row():
with gr.Column(scale=1):
topic_input = gr.Textbox(label="STEP 1: Debate Topic", placeholder="Enter the debate topic")
position_1_input = gr.Radio(["For", "Against"], label="STEP 2: Miss AI Vietnam's Position")
position_2_input = gr.Radio(["For", "Against"], label="STEP 3: Miss AI China's Position")
start_button = gr.Button("STEP 4: Start", variant='primary')
next_button = gr.Button("Next Turn")
end_button = gr.Button("End Debate", variant='stop') # Nút kết thúc tranh luận
status_output = gr.Textbox(label="Status", interactive=False)
with gr.Column(scale=2):
with gr.Row():
# Chatbot chiếm 70% chiều rộng, Video chiếm 30%
with gr.Column(scale=7):
chatbot = gr.Chatbot(label="Debate Arena", height=500) # Hiển thị lịch sử tranh luận
with gr.Column(scale=3):
video_output = gr.Video(label="Debate Video", autoplay=True, height=500) # Hiển thị video
# Audio và Final Audio được đặt bên dưới
audio_output = gr.Audio(label="Debate Audio", autoplay=None) # Hiển thị audio hiện tại
final_audio_output = gr.Audio(label="Full Debate Audio", visible=False) # Hiển thị audio cuối cùng
start_button.click(
fn=start_debate,
inputs=[topic_input, position_1_input, position_2_input],
outputs=[status_output, chatbot, video_output, audio_output],
)
next_button.click(
fn=next_turn,
inputs=[topic_input, position_1_input, position_2_input, chatbot],
outputs=[status_output, chatbot, video_output, audio_output],
)
end_button.click(
fn=end_debate,
inputs=[],
outputs=[status_output, final_audio_output], # Trả về audio cuối cùng
).then(
lambda: gr.Audio(visible=True), None, final_audio_output # Hiển thị thành phần audio cuối cùng
)
if __name__ == "__main__":
demo.launch(share=True) |