File size: 5,394 Bytes
07c0c7c d78e18f 07c0c7c d78e18f 07c0c7c c969713 07c0c7c d78e18f 07c0c7c c969713 d78e18f 07c0c7c d78e18f c969713 d78e18f c969713 d78e18f c969713 d78e18f c969713 d78e18f 07c0c7c d78e18f c969713 d78e18f c969713 d78e18f 07c0c7c d78e18f 07c0c7c d78e18f 07c0c7c d78e18f 07c0c7c d78e18f 07c0c7c ec2d544 07c0c7c ec4b640 07c0c7c ec2d544 07c0c7c ec2d544 07c0c7c 1fc3314 |
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 |
import gradio as gr
import os
import tempfile
import re
from pydub import AudioSegment # Thư viện để kết hợp các file âm thanh
from openai import OpenAI
# API key và endpoint mặc định
DEFAULT_API_KEY = "sk-GINVEtfNbrXNcGQhf3rEUIgzoicNGIApovqZxe0AYJF5PkTV"
DEFAULT_BASE_URL = "https://open.keyai.shop"
# Giới hạn ký tự tối đa mỗi yêu cầu API
MAX_CHAR_LIMIT = 140964096
def clean_text(text):
# Loại bỏ khoảng trắng thừa và xuống dòng
cleaned_text = re.sub(r'\s+', ' ', text.strip())
return cleaned_text
def split_text(text, limit=MAX_CHAR_LIMIT):
# Tách văn bản thành các đoạn không vượt quá giới hạn ký tự
words = text.split(' ')
chunks = []
current_chunk = ""
for word in words:
if len(current_chunk) + len(word) + 1 <= limit:
current_chunk += word + " "
else:
chunks.append(current_chunk.strip())
current_chunk = word + " "
if current_chunk:
chunks.append(current_chunk.strip())
return chunks
def tts(text, model, voice, speed):
cleaned_text = clean_text(text)
chunks = split_text(cleaned_text)
audio_segments = []
try:
client = OpenAI(api_key=DEFAULT_API_KEY, base_url=DEFAULT_BASE_URL + '/v1')
for chunk in chunks:
response = client.audio.speech.create(
model=model, # Các lựa chọn: "tts-1", "tts-1-hd"
voice=voice, # Các lựa chọn: 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'
input=chunk,
speed=speed
)
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file:
temp_file.write(response.content)
temp_file_path = temp_file.name
audio_segments.append(AudioSegment.from_mp3(temp_file_path))
except Exception as error:
raise gr.Error("Đã xảy ra lỗi khi tạo giọng nói. Vui lòng kiểm tra API key hoặc thử lại sau.")
# Nối các đoạn âm thanh lại thành một file duy nhất
final_audio = sum(audio_segments)
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as final_temp_file:
final_audio.export(final_temp_file.name, format="mp3")
final_audio_path = final_temp_file.name
return final_audio_path
# CSS tùy chỉnh với giao diện tối và tích hợp FontAwesome cho icon
custom_css = """
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css');
body {
background-color: #1e1e2f;
color: #e0e0e0;
font-family: 'Arial', sans-serif;
}
.title {
font-size: 2.5rem;
font-weight: bold;
text-align: center;
margin-bottom: 30px;
color: #f1f1f1;
}
.container {
margin: auto;
width: 90%;
padding: 20px;
}
.card {
background: #2e2e42;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
margin-bottom: 20px;
}
.gradio-container {
background: #1e1e2f;
}
button {
background-color: #4CAF50;
color: white;
border: none;
border-radius: 8px;
padding: 10px 20px;
font-size: 1rem;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
input, textarea, select {
background: #3a3a50;
border: 1px solid #555;
color: #e0e0e0;
padding: 8px;
border-radius: 4px;
}
select {
padding: 8px 10px;
}
label {
font-weight: bold;
margin-bottom: 5px;
}
"""
with gr.Blocks(css=custom_css) as demo:
# Tiêu đề với icon Microphone
gr.Markdown("<div class='title'><i class='fas fa-microphone-alt'></i> OpenAI TTS</div>")
with gr.Column(elem_classes="container"):
with gr.Row():
# Cột nhập văn bản (mở rộng với 15 dòng)
with gr.Column(elem_classes="card"):
text = gr.Textbox(label="Văn bản đầu vào", placeholder="Nhập văn bản cần chuyển giọng nói...", lines=15)
char_counter = gr.Markdown("Character count: 0")
# Cột cài đặt tham số TTS với menu được cải tiến
with gr.Column(elem_classes="card"):
model = gr.Dropdown(choices=['tts-1', 'tts-1-hd'], label='Chọn Model', value='tts-1')
voice = gr.Dropdown(choices=['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'], label='Chọn Giọng', value='alloy')
speed = gr.Slider(minimum=0.5, maximum=2.0, step=0.1, label="Tốc độ", value=1.0)
# Nút chuyển đổi với icon Play
with gr.Row(elem_classes="card"):
btn = gr.Button(" Chuyển ")
# Kết quả âm thanh
with gr.Row(elem_classes="card"):
output_audio = gr.Audio(label="Kết quả âm thanh")
# Hàm cập nhật số lượng ký tự
def update_char_counter(text):
cleaned_text = clean_text(text)
return f"Character count: {len(cleaned_text)}"
text.change(fn=update_char_counter, inputs=text, outputs=char_counter)
text.submit(fn=tts, inputs=[text, model, voice, speed], outputs=output_audio, api_name="tts_enter_key", concurrency_limit=None)
btn.click(fn=tts, inputs=[text, model, voice, speed], outputs=output_audio, api_name="tts_button", concurrency_limit=None)
demo.launch()
|