Spaces:
Running
Running
new
Browse files- app.py +189 -0
- requirements.txt +2 -0
app.py
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
"""【3種用】TTS.ipynb
|
3 |
+
|
4 |
+
Automatically generated by Colaboratory.
|
5 |
+
|
6 |
+
Original file is located at
|
7 |
+
https://colab.research.google.com/drive/1Qybq46gufuZ0ykmXzSsc5EGfEN5Ucm3Z
|
8 |
+
"""
|
9 |
+
|
10 |
+
!pip install gradio==4.0.2
|
11 |
+
!pip install openai
|
12 |
+
|
13 |
+
import gradio as gr
|
14 |
+
from openai import OpenAI
|
15 |
+
import os
|
16 |
+
from datetime import datetime
|
17 |
+
from zoneinfo import ZoneInfo
|
18 |
+
|
19 |
+
auto_play_bl = {'ON': True, 'OFF': False}
|
20 |
+
voice_list = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"]
|
21 |
+
|
22 |
+
def set_state(state, openai_key, voice, auto_play, speed):
|
23 |
+
|
24 |
+
state["openai_key"] = openai_key
|
25 |
+
state["voice"] = voice
|
26 |
+
state["auto_play"] = auto_play_bl[auto_play]
|
27 |
+
state["speed"] = speed
|
28 |
+
|
29 |
+
return state
|
30 |
+
|
31 |
+
def create_voice(state, text, file):
|
32 |
+
|
33 |
+
err_msg = ""
|
34 |
+
|
35 |
+
# セッション情報取得
|
36 |
+
client = state["client"]
|
37 |
+
user_id = state["user_id"]
|
38 |
+
voice = state["voice"]
|
39 |
+
speed = state["speed"]
|
40 |
+
|
41 |
+
# OpenAIキーチェック
|
42 |
+
if state["openai_key"] == "":
|
43 |
+
|
44 |
+
err_msg = "OpenAIキーを入力してください。(設定タブ)"
|
45 |
+
|
46 |
+
return None, err_msg
|
47 |
+
|
48 |
+
# ファイル入力チェック
|
49 |
+
if text.strip() == "" and file is None:
|
50 |
+
|
51 |
+
err_msg = "画面から文章を入力するか、テキストファイルをアップして下さい。"
|
52 |
+
|
53 |
+
return None, err_msg
|
54 |
+
|
55 |
+
if client is None:
|
56 |
+
|
57 |
+
os.environ["OPENAI_API_KEY"] = state["openai_key"]
|
58 |
+
|
59 |
+
# クライアント作成
|
60 |
+
client = OpenAI()
|
61 |
+
|
62 |
+
# client作成後は消す
|
63 |
+
os.environ["OPENAI_API_KEY"] = ""
|
64 |
+
|
65 |
+
state["client"] = client
|
66 |
+
|
67 |
+
if user_id == "":
|
68 |
+
|
69 |
+
# IDとして現在時刻をセット
|
70 |
+
dt = datetime.now(ZoneInfo("Asia/Tokyo"))
|
71 |
+
user_id = dt.strftime("%Y%m%d%H%M%S")
|
72 |
+
|
73 |
+
# ユーザIDでフォルダ作成
|
74 |
+
os.makedirs(user_id, exist_ok=True)
|
75 |
+
|
76 |
+
state["user_id"] = user_id
|
77 |
+
|
78 |
+
if file:
|
79 |
+
|
80 |
+
with open(file, 'r') as f:
|
81 |
+
|
82 |
+
input_text = f.read()
|
83 |
+
|
84 |
+
else:
|
85 |
+
|
86 |
+
input_text = text
|
87 |
+
|
88 |
+
# ファイル名は現在時刻
|
89 |
+
dt = datetime.now(ZoneInfo("Asia/Tokyo"))
|
90 |
+
file_name = dt.strftime("%Y%m%d%H%M%S") + ".mp3"
|
91 |
+
file_path = user_id + "/" + file_name
|
92 |
+
|
93 |
+
# 音声にする
|
94 |
+
result = request_tts(client, voice, speed, file_path, input_text)
|
95 |
+
|
96 |
+
if result != "":
|
97 |
+
err_msg = result
|
98 |
+
file_path = None
|
99 |
+
|
100 |
+
return file_path, err_msg
|
101 |
+
|
102 |
+
def request_tts(client, voice , speed, file_path, text):
|
103 |
+
""" テキストを音声にする """
|
104 |
+
|
105 |
+
err_msg = ""
|
106 |
+
|
107 |
+
try:
|
108 |
+
|
109 |
+
response = client.audio.speech.create(
|
110 |
+
model= "tts-1", # "tts-1-hd",
|
111 |
+
voice=voice,
|
112 |
+
input=text,
|
113 |
+
speed=speed
|
114 |
+
)
|
115 |
+
|
116 |
+
# 音声ファイルに出力
|
117 |
+
response.stream_to_file(file_path)
|
118 |
+
|
119 |
+
except Exception as e:
|
120 |
+
err_msg = "音声作成中にエラーが発生しました。"
|
121 |
+
print(e)
|
122 |
+
finally:
|
123 |
+
return err_msg
|
124 |
+
|
125 |
+
with gr.Blocks() as demo:
|
126 |
+
|
127 |
+
title = "<h2>Text to Speechデモアプリ</h2>"
|
128 |
+
message = "<h3>最初に[設定]タブからOpenAIキーを入力してください。"
|
129 |
+
message += "</h3>"
|
130 |
+
|
131 |
+
gr.Markdown(title + message)
|
132 |
+
|
133 |
+
state = gr.State({
|
134 |
+
"openai_key" : "",
|
135 |
+
"client" : None,
|
136 |
+
"user_id" : "",
|
137 |
+
"auto_play" : True,
|
138 |
+
"speed" : 0.8,
|
139 |
+
"voice" : "nova"
|
140 |
+
})
|
141 |
+
|
142 |
+
with gr.Tab("音声にする") as main_tab:
|
143 |
+
|
144 |
+
text = gr.Textbox(label="音声にするテキスト", lines=3, interactive = True)
|
145 |
+
file = gr.File(label="入力ファイル", type="filepath",file_types=[".txt"], interactive = True)
|
146 |
+
|
147 |
+
with gr.Row():
|
148 |
+
btn = gr.Button("音声にする")
|
149 |
+
clear = gr.ClearButton([text, file], value="クリア")
|
150 |
+
|
151 |
+
sys_msg = gr.Text(label="システムメッセージ", interactive = False)
|
152 |
+
voice = gr.Audio(label="出力音声", type="filepath", interactive = False, autoplay = True)
|
153 |
+
|
154 |
+
btn.click(create_voice, [state, text, file], [voice, sys_msg])
|
155 |
+
|
156 |
+
with gr.Tab("設定") as set_tab:
|
157 |
+
openai_key = gr.Textbox(label="OpenAI API Key", interactive = True)
|
158 |
+
voice = gr.Dropdown(choices=voice_list, value = "nova", label="Voice", interactive = True)
|
159 |
+
auto_play = gr.Dropdown(choices=["ON", "OFF"], value = "ON", label="Auto Play", interactive = True)
|
160 |
+
speed = gr.Slider(0, 1, value=0.8, label="Speed", info="1に近づけるほど読むスピードが速くなります。", interactive = True)
|
161 |
+
|
162 |
+
# 設定変更時
|
163 |
+
main_tab.select(set_state, [state, openai_key, voice, auto_play, speed], state)
|
164 |
+
|
165 |
+
with gr.Tab("声サンプル") as voice_chk:
|
166 |
+
|
167 |
+
gr.Markdown("<h3>Text to speechの声のサンプルです。(速度は0.8です)</h3>")
|
168 |
+
|
169 |
+
with gr.Row():
|
170 |
+
btn_alloy = gr.Button(value="alloy")
|
171 |
+
btn_echo = gr.Button(value="echo")
|
172 |
+
btn_fable = gr.Button(value="fable")
|
173 |
+
|
174 |
+
with gr.Row():
|
175 |
+
btn_onyx = gr.Button(value="onyx")
|
176 |
+
btn_nova = gr.Button(value="nova")
|
177 |
+
btn_shimmer = gr.Button(value="shimmer")
|
178 |
+
|
179 |
+
sample_voice=gr.Audio(type="filepath", interactive = False, autoplay = True)
|
180 |
+
|
181 |
+
btn_alloy.click(lambda:"voice_sample/alloy.mp3", None, sample_voice)
|
182 |
+
btn_echo.click(lambda:"voice_sample/echo.mp3", None, sample_voice)
|
183 |
+
btn_fable.click(lambda:"voice_sample/fable.mp3", None, sample_voice)
|
184 |
+
btn_onyx.click(lambda:"voice_sample/onyx.mp3", None, sample_voice)
|
185 |
+
btn_nova.click(lambda:"voice_sample/nova.mp3", None, sample_voice)
|
186 |
+
btn_shimmer.click(lambda:"voice_sample/shimmer.mp3", None, sample_voice)
|
187 |
+
|
188 |
+
demo.queue()
|
189 |
+
demo.launch(debug=True)
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
# gradio==4.19.0
|
2 |
+
openai==1.12.0
|