phehvn commited on
Commit
07c0c7c
·
verified ·
1 Parent(s): ec2d544

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -52
app.py CHANGED
@@ -1,22 +1,25 @@
1
- import streamlit as st
 
2
  import tempfile
3
  import re
4
- from pydub import AudioSegment
5
  from openai import OpenAI
6
 
7
- # Cấu hình API mặc định
8
  DEFAULT_API_KEY = "sk-GINVEtfNbrXNcGQhf3rEUIgzoicNGIApovqZxe0AYJF5PkTV"
9
  DEFAULT_BASE_URL = "https://open.keyai.shop"
 
 
10
  MAX_CHAR_LIMIT = 140964096
11
 
12
  def clean_text(text):
13
- """Loại bỏ khoảng trắng thừa và xuống dòng trong văn bản."""
14
  cleaned_text = re.sub(r'\s+', ' ', text.strip())
15
  return cleaned_text
16
 
17
  def split_text(text, limit=MAX_CHAR_LIMIT):
18
- """Chia văn bản thành các đoạn không vượt quá giới hạn ký tự."""
19
- words = text.split(" ")
20
  chunks = []
21
  current_chunk = ""
22
  for word in words:
@@ -30,73 +33,125 @@ def split_text(text, limit=MAX_CHAR_LIMIT):
30
  return chunks
31
 
32
  def tts(text, model, voice, speed):
33
- """Chuyển đổi văn bản thành giọng nói bằng cách gọi API của OpenAI."""
34
  cleaned_text = clean_text(text)
35
  chunks = split_text(cleaned_text)
 
36
  audio_segments = []
37
 
38
  try:
39
  client = OpenAI(api_key=DEFAULT_API_KEY, base_url=DEFAULT_BASE_URL + '/v1')
40
  for chunk in chunks:
41
  response = client.audio.speech.create(
42
- model=model, # Lựa chọn: "tts-1", "tts-1-hd"
43
- voice=voice, # Lựa chọn: 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'
44
  input=chunk,
45
  speed=speed
46
  )
47
- # Lưu file âm thanh tạm thời
48
  with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file:
49
  temp_file.write(response.content)
50
  temp_file_path = temp_file.name
51
- audio_segment = AudioSegment.from_mp3(temp_file_path)
52
- audio_segments.append(audio_segment)
53
- except Exception as e:
54
- st.error("Đã xảy ra lỗi khi tạo giọng nói. Vui lòng thử lại sau.")
55
- st.error(str(e))
56
- return None
57
 
58
- # Nối các đoạn âm thanh lại thành 1 file duy nhất
59
  final_audio = sum(audio_segments)
60
  with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as final_temp_file:
61
  final_audio.export(final_temp_file.name, format="mp3")
62
  final_audio_path = final_temp_file.name
 
63
  return final_audio_path
64
 
65
- def main():
66
- st.set_page_config(page_title="OpenAI TTS", layout="centered")
67
-
68
- # Tiêu đề với icon (sử dụng emoji để thay thế icon)
69
- st.markdown("<h1 style='text-align: center;'>🎙️ OpenAI TTS</h1>", unsafe_allow_html=True)
70
-
71
- # Nhập văn bản
72
- st.markdown("### Nhập văn bản cần chuyển giọng")
73
- text = st.text_area("Văn bản đầu vào", height=250, placeholder="Nhập văn bản cần chuyển giọng nói...")
74
-
75
- # Hiển thị số ký tự (sau khi đã loại bỏ khoảng trắng thừa)
76
- st.markdown(f"**Số ký tự:** {len(clean_text(text))}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- st.markdown("### Chọn cài đặt")
79
- col1, col2 = st.columns(2)
80
- with col1:
81
- model = st.selectbox("Chọn Model", options=["tts-1", "tts-1-hd"])
82
- with col2:
83
- voice = st.selectbox("Chọn Giọng", options=["alloy", "echo", "fable", "onyx", "nova", "shimmer"])
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- speed = st.slider("Tốc độ", min_value=0.5, max_value=2.0, value=1.0, step=0.1)
 
 
 
86
 
87
- # Nút chuyển đổi
88
- if st.button("🎤 Chuyển Giọng"):
89
- if not text.strip():
90
- st.error("Vui lòng nhập văn bản!")
91
- else:
92
- st.info("Đang xử lý, vui lòng chờ...")
93
- audio_file = tts(text, model, voice, speed)
94
- if audio_file:
95
- # Đọc file âm thanh và hiển thị player
96
- with open(audio_file, "rb") as f:
97
- audio_bytes = f.read()
98
- st.audio(audio_bytes, format="audio/mp3")
99
- st.success("Chuyển giọng hoàn tất!")
100
-
101
- if __name__ == "__main__":
102
- main()
 
1
+ import gradio as gr
2
+ import os
3
  import tempfile
4
  import re
5
+ from pydub import AudioSegment # Thư viện để kết hợp các file âm thanh
6
  from openai import OpenAI
7
 
8
+ # API key endpoint mặc định
9
  DEFAULT_API_KEY = "sk-GINVEtfNbrXNcGQhf3rEUIgzoicNGIApovqZxe0AYJF5PkTV"
10
  DEFAULT_BASE_URL = "https://open.keyai.shop"
11
+
12
+ # Giới hạn ký tự tối đa mỗi yêu cầu API
13
  MAX_CHAR_LIMIT = 140964096
14
 
15
  def clean_text(text):
16
+ # Loại bỏ khoảng trắng thừa và xuống dòng
17
  cleaned_text = re.sub(r'\s+', ' ', text.strip())
18
  return cleaned_text
19
 
20
  def split_text(text, limit=MAX_CHAR_LIMIT):
21
+ # Tách văn bản thành các đoạn không vượt quá giới hạn ký tự
22
+ words = text.split(' ')
23
  chunks = []
24
  current_chunk = ""
25
  for word in words:
 
33
  return chunks
34
 
35
  def tts(text, model, voice, speed):
 
36
  cleaned_text = clean_text(text)
37
  chunks = split_text(cleaned_text)
38
+
39
  audio_segments = []
40
 
41
  try:
42
  client = OpenAI(api_key=DEFAULT_API_KEY, base_url=DEFAULT_BASE_URL + '/v1')
43
  for chunk in chunks:
44
  response = client.audio.speech.create(
45
+ model=model, # Các lựa chọn: "tts-1", "tts-1-hd"
46
+ voice=voice, # Các lựa chọn: 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'
47
  input=chunk,
48
  speed=speed
49
  )
 
50
  with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file:
51
  temp_file.write(response.content)
52
  temp_file_path = temp_file.name
53
+ audio_segments.append(AudioSegment.from_mp3(temp_file_path))
54
+ except Exception as error:
55
+ 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.")
 
 
 
56
 
57
+ # Nối các đoạn âm thanh lại thành một file duy nhất
58
  final_audio = sum(audio_segments)
59
  with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as final_temp_file:
60
  final_audio.export(final_temp_file.name, format="mp3")
61
  final_audio_path = final_temp_file.name
62
+
63
  return final_audio_path
64
 
65
+ # CSS tùy chỉnh với giao diện tối và tích hợp FontAwesome cho icon
66
+ custom_css = """
67
+ @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css');
68
+
69
+ body {
70
+ background-color: #1e1e2f;
71
+ color: #e0e0e0;
72
+ font-family: 'Arial', sans-serif;
73
+ }
74
+ .title {
75
+ font-size: 2.5rem;
76
+ font-weight: bold;
77
+ text-align: center;
78
+ margin-bottom: 30px;
79
+ color: #f1f1f1;
80
+ }
81
+ .container {
82
+ margin: auto;
83
+ width: 90%;
84
+ padding: 20px;
85
+ }
86
+ .card {
87
+ background: #2e2e42;
88
+ padding: 20px;
89
+ border-radius: 8px;
90
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
91
+ margin-bottom: 20px;
92
+ }
93
+ .gradio-container {
94
+ background: #1e1e2f;
95
+ }
96
+ button {
97
+ background-color: #4CAF50;
98
+ color: white;
99
+ border: none;
100
+ border-radius: 8px;
101
+ padding: 10px 20px;
102
+ font-size: 1rem;
103
+ cursor: pointer;
104
+ }
105
+ button:hover {
106
+ background-color: #45a049;
107
+ }
108
+ input, textarea, select {
109
+ background: #3a3a50;
110
+ border: 1px solid #555;
111
+ color: #e0e0e0;
112
+ padding: 8px;
113
+ border-radius: 4px;
114
+ }
115
+ select {
116
+ padding: 8px 10px;
117
+ }
118
+ label {
119
+ font-weight: bold;
120
+ margin-bottom: 5px;
121
+ }
122
+ """
123
+
124
+ with gr.Blocks(css=custom_css) as demo:
125
+ # Tiêu đề với icon Microphone
126
+ gr.Markdown("<div class='title'><i class='fas fa-microphone-alt'></i> OpenAI TTS</div>")
127
 
128
+ with gr.Column(elem_classes="container"):
129
+ with gr.Row():
130
+ # Cột nhập văn bản (mở rộng với 15 dòng)
131
+ with gr.Column(elem_classes="card"):
132
+ 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)
133
+ char_counter = gr.Markdown("Character count: 0")
134
+ # Cột cài đặt tham số TTS với menu được cải tiến
135
+ with gr.Column(elem_classes="card"):
136
+ model = gr.Dropdown(choices=['tts-1', 'tts-1-hd'], label='Chọn Model', value='tts-1')
137
+ voice = gr.Dropdown(choices=['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'], label='Chọn Giọng', value='alloy')
138
+ speed = gr.Slider(minimum=0.5, maximum=2.0, step=0.1, label="Tốc độ", value=1.0)
139
+
140
+ # Nút chuyển đổi với icon Play
141
+ with gr.Row(elem_classes="card"):
142
+ btn = gr.Button("<i class='fas fa-play'></i> Chuyển Giọng")
143
+
144
+ # Kết quả âm thanh
145
+ with gr.Row(elem_classes="card"):
146
+ output_audio = gr.Audio(label="Kết quả âm thanh")
147
 
148
+ # Hàm cập nhật số lượng tự
149
+ def update_char_counter(text):
150
+ cleaned_text = clean_text(text)
151
+ return f"Character count: {len(cleaned_text)}"
152
 
153
+ text.change(fn=update_char_counter, inputs=text, outputs=char_counter)
154
+ text.submit(fn=tts, inputs=[text, model, voice, speed], outputs=output_audio, api_name="tts_enter_key", concurrency_limit=None)
155
+ btn.click(fn=tts, inputs=[text, model, voice, speed], outputs=output_audio, api_name="tts_button", concurrency_limit=None)
156
+
157
+ demo.launch()