Spaces:
Runtime error
Runtime error
Upload folder using huggingface_hub
Browse files- app.py +61 -57
- css/style.css +17 -17
- javascript/main.js +99 -0
- tools/__pycache__/webui.cpython-39.pyc +0 -0
- tools/webui.py +6 -2
app.py
CHANGED
@@ -44,61 +44,65 @@ def speak_fn(
|
|
44 |
print(f"Too Long Text: {text}")
|
45 |
if exceed_flag:
|
46 |
text = "不要超过100字!"
|
47 |
-
|
48 |
else:
|
49 |
text = "这句太长了,憋坏我啦!"
|
50 |
-
|
51 |
-
|
52 |
-
if len(text) > 42:
|
53 |
-
print(f"Long Text: {text}")
|
54 |
-
para_list = re_matching.cut_para(text)
|
55 |
-
for p in para_list:
|
56 |
-
audio_list_sent = []
|
57 |
-
sent_list = re_matching.cut_sent(p)
|
58 |
-
for s in sent_list:
|
59 |
-
audio = infer(
|
60 |
-
s,
|
61 |
-
sdp_ratio=sdp_ratio,
|
62 |
-
noise_scale=noise_scale,
|
63 |
-
noise_scale_w=noise_scale_w,
|
64 |
-
length_scale=length_scale,
|
65 |
-
sid=speaker,
|
66 |
-
language=language,
|
67 |
-
hps=hps,
|
68 |
-
net_g=net_g,
|
69 |
-
device=device,
|
70 |
-
)
|
71 |
-
audio_list_sent.append(audio)
|
72 |
-
silence = np.zeros((int)(44100 * interval_between_sent))
|
73 |
-
audio_list_sent.append(silence)
|
74 |
-
if (interval_between_para - interval_between_sent) > 0:
|
75 |
-
silence = np.zeros((int)(44100 * (interval_between_para - interval_between_sent)))
|
76 |
-
audio_list_sent.append(silence)
|
77 |
-
audio16bit = gr.processing_utils.convert_to_16_bit_wav(np.concatenate(audio_list_sent)) # 对完整句子做音量归一
|
78 |
-
audio_list.append(audio16bit)
|
79 |
else:
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
audio_list.append(audio16bit)
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
|
104 |
def submit_lock_fn():
|
@@ -112,7 +116,7 @@ def init_fn():
|
|
112 |
index = random.randint(1,7)
|
113 |
welcome_text = get_sentence("Welcome", index)
|
114 |
|
115 |
-
return gr.update(value=f"./assets/audios/Welcome{index}.wav"), get_character_html(welcome_text)
|
116 |
|
117 |
def get_sentence(category, index=-1):
|
118 |
if index == -1:
|
@@ -129,14 +133,14 @@ with gr.Blocks(css=customCSS) as demo:
|
|
129 |
tmp_string = gr.Textbox(value="", visible=False)
|
130 |
character_area = gr.HTML(get_character_html("你好呀!"), elem_id="character_area")
|
131 |
with gr.Tab("Speak", elem_id="tab-speak"):
|
132 |
-
speak_input = gr.Textbox(lines=1, label="Talking Flower will say:", elem_classes="wonder-card", elem_id="
|
133 |
speak_button = gr.Button("Speak!", elem_id="speak_button", elem_classes="main-button wonder-card")
|
134 |
-
example_category = gr.Examples(["夸夸你 | Praise", "游戏台词 | Scripts", "玩梗 | Meme"],
|
135 |
with gr.Tab("Chat", elem_id="tab-chat"):
|
136 |
-
chat_input = gr.Textbox(lines=1, placeholder="Coming Soon...", label="Chat to Talking Flower:", elem_classes="wonder-card", elem_id="
|
137 |
chat_button = gr.Button("Chat!", elem_id="chat_button", elem_classes="main-button wonder-card")
|
138 |
with gr.Tab("Mimic", elem_id="tab-mimic"):
|
139 |
-
gr.Textbox(lines=1, placeholder="Coming Soon...", label="Choose sound to mimic:", elem_classes="wonder-card", elem_id="
|
140 |
mimic_button = gr.Button("Mimic!", elem_id="mimic_button", elem_classes="main-button wonder-card")
|
141 |
audio_output = gr.Audio(label="输出音频", show_label=False, autoplay=True, elem_id="audio_output", elem_classes="wonder-card")
|
142 |
|
@@ -163,7 +167,7 @@ if __name__ == "__main__":
|
|
163 |
net_g = get_net_g(model_path=config.webui_config.model, version=version, device=device, hps=hps)
|
164 |
reload_javascript()
|
165 |
demo.launch(
|
166 |
-
allowed_paths=["./assets"],
|
167 |
show_api=False,
|
168 |
inbrowser=True,
|
169 |
)
|
|
|
44 |
print(f"Too Long Text: {text}")
|
45 |
if exceed_flag:
|
46 |
text = "不要超过100字!"
|
47 |
+
audio_value = "./assets/audios/nomorethan100.wav"
|
48 |
else:
|
49 |
text = "这句太长了,憋坏我啦!"
|
50 |
+
audio_value = "./assets/audios/overlength.wav"
|
51 |
+
exceed_flag = not exceed_flag
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
else:
|
53 |
+
audio_list = []
|
54 |
+
if len(text) > 42:
|
55 |
+
print(f"Long Text: {text}")
|
56 |
+
para_list = re_matching.cut_para(text)
|
57 |
+
for p in para_list:
|
58 |
+
audio_list_sent = []
|
59 |
+
sent_list = re_matching.cut_sent(p)
|
60 |
+
for s in sent_list:
|
61 |
+
audio = infer(
|
62 |
+
s,
|
63 |
+
sdp_ratio=sdp_ratio,
|
64 |
+
noise_scale=noise_scale,
|
65 |
+
noise_scale_w=noise_scale_w,
|
66 |
+
length_scale=length_scale,
|
67 |
+
sid=speaker,
|
68 |
+
language=language,
|
69 |
+
hps=hps,
|
70 |
+
net_g=net_g,
|
71 |
+
device=device,
|
72 |
+
)
|
73 |
+
audio_list_sent.append(audio)
|
74 |
+
silence = np.zeros((int)(44100 * interval_between_sent))
|
75 |
+
audio_list_sent.append(silence)
|
76 |
+
if (interval_between_para - interval_between_sent) > 0:
|
77 |
+
silence = np.zeros((int)(44100 * (interval_between_para - interval_between_sent)))
|
78 |
+
audio_list_sent.append(silence)
|
79 |
+
audio16bit = gr.processing_utils.convert_to_16_bit_wav(np.concatenate(audio_list_sent)) # 对完整句子做音量归一
|
80 |
audio_list.append(audio16bit)
|
81 |
+
else:
|
82 |
+
print(f"Short Text: {text}")
|
83 |
+
silence = np.zeros(hps.data.sampling_rate // 2, dtype=np.int16)
|
84 |
+
with torch.no_grad():
|
85 |
+
for piece in text.split("|"):
|
86 |
+
audio = infer(
|
87 |
+
piece,
|
88 |
+
sdp_ratio=sdp_ratio,
|
89 |
+
noise_scale=noise_scale,
|
90 |
+
noise_scale_w=noise_scale_w,
|
91 |
+
length_scale=length_scale,
|
92 |
+
sid=speaker,
|
93 |
+
language=language,
|
94 |
+
hps=hps,
|
95 |
+
net_g=net_g,
|
96 |
+
device=device,
|
97 |
+
)
|
98 |
+
audio16bit = gr.processing_utils.convert_to_16_bit_wav(audio)
|
99 |
+
audio_list.append(audio16bit)
|
100 |
+
audio_list.append(silence) # 将静音添加到列表中
|
101 |
+
|
102 |
+
audio_concat = np.concatenate(audio_list)
|
103 |
+
audio_value = (hps.data.sampling_rate, audio_concat)
|
104 |
+
|
105 |
+
return gr.update(value=audio_value, autoplay=True), get_character_html(text), exceed_flag, gr.update(interactive=True)
|
106 |
|
107 |
|
108 |
def submit_lock_fn():
|
|
|
116 |
index = random.randint(1,7)
|
117 |
welcome_text = get_sentence("Welcome", index)
|
118 |
|
119 |
+
return gr.update(value=f"./assets/audios/Welcome{index}.wav", autoplay=False), get_character_html(welcome_text)
|
120 |
|
121 |
def get_sentence(category, index=-1):
|
122 |
if index == -1:
|
|
|
133 |
tmp_string = gr.Textbox(value="", visible=False)
|
134 |
character_area = gr.HTML(get_character_html("你好呀!"), elem_id="character_area")
|
135 |
with gr.Tab("Speak", elem_id="tab-speak"):
|
136 |
+
speak_input = gr.Textbox(lines=1, label="Talking Flower will say:", elem_classes="wonder-card input_text", elem_id="speak_input")
|
137 |
speak_button = gr.Button("Speak!", elem_id="speak_button", elem_classes="main-button wonder-card")
|
138 |
+
example_category = gr.Examples(["夸夸你 | Praise", "游戏台词 | Scripts", "玩梗 | Meme"], inputs=[tmp_string], elem_id="examples")
|
139 |
with gr.Tab("Chat", elem_id="tab-chat"):
|
140 |
+
chat_input = gr.Textbox(lines=1, placeholder="Coming Soon...", label="Chat to Talking Flower:", elem_classes="wonder-card input_text", elem_id="chat_input", interactive=False)
|
141 |
chat_button = gr.Button("Chat!", elem_id="chat_button", elem_classes="main-button wonder-card")
|
142 |
with gr.Tab("Mimic", elem_id="tab-mimic"):
|
143 |
+
gr.Textbox(lines=1, placeholder="Coming Soon...", label="Choose sound to mimic:", elem_classes="wonder-card input_text", elem_id="mimic_input", interactive=False)
|
144 |
mimic_button = gr.Button("Mimic!", elem_id="mimic_button", elem_classes="main-button wonder-card")
|
145 |
audio_output = gr.Audio(label="输出音频", show_label=False, autoplay=True, elem_id="audio_output", elem_classes="wonder-card")
|
146 |
|
|
|
167 |
net_g = get_net_g(model_path=config.webui_config.model, version=version, device=device, hps=hps)
|
168 |
reload_javascript()
|
169 |
demo.launch(
|
170 |
+
allowed_paths=["./assets", "./javascript", "./css"],
|
171 |
show_api=False,
|
172 |
inbrowser=True,
|
173 |
)
|
css/style.css
CHANGED
@@ -194,31 +194,31 @@ gradio-app {
|
|
194 |
transition-property: transform,box-shadow !important;
|
195 |
}
|
196 |
|
197 |
-
|
198 |
-
width: 80
|
199 |
}
|
200 |
-
|
201 |
-
display: none;
|
202 |
}
|
203 |
-
|
204 |
-
display: flex;
|
205 |
background: #ffffff !important;
|
206 |
height: 12rem !important;
|
207 |
|
208 |
}
|
209 |
-
|
210 |
margin-top: -2.25rem !important;
|
211 |
-
display: flex;
|
212 |
-
width: 100
|
213 |
-
align-content: center;
|
214 |
-
flex-direction: column;
|
215 |
-
flex-wrap: wrap;
|
216 |
-
justify-content: center;
|
217 |
-
align-items: center;
|
218 |
-
}
|
219 |
-
|
220 |
font-family: var(--font-heading) !important;
|
221 |
-
font-size: 1.225rem;
|
222 |
}
|
223 |
|
224 |
/* Main Button */
|
|
|
194 |
transition-property: transform,box-shadow !important;
|
195 |
}
|
196 |
|
197 |
+
.input_text label textarea {
|
198 |
+
width: 80% !important;
|
199 |
}
|
200 |
+
.input_text div.wrap {
|
201 |
+
display: none !important;
|
202 |
}
|
203 |
+
.input_text {
|
204 |
+
display: flex !important;
|
205 |
background: #ffffff !important;
|
206 |
height: 12rem !important;
|
207 |
|
208 |
}
|
209 |
+
.input_text label {
|
210 |
margin-top: -2.25rem !important;
|
211 |
+
display: flex !important;
|
212 |
+
width: 100% !important;
|
213 |
+
align-content: center !important;
|
214 |
+
flex-direction: column !important;
|
215 |
+
flex-wrap: wrap !important;
|
216 |
+
justify-content: center !important;
|
217 |
+
align-items: center !important;
|
218 |
+
}
|
219 |
+
.input_text label span {
|
220 |
font-family: var(--font-heading) !important;
|
221 |
+
font-size: 1.225rem !important;
|
222 |
}
|
223 |
|
224 |
/* Main Button */
|
javascript/main.js
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var key_down_history = [];
|
2 |
+
var currentIndex = -1;
|
3 |
+
|
4 |
+
var gradioContainer = null;
|
5 |
+
|
6 |
+
var isInIframe = (window.self !== window.top);
|
7 |
+
var currentTime = new Date().getTime();
|
8 |
+
|
9 |
+
let windowWidth = window.innerWidth;
|
10 |
+
let lines_json = []
|
11 |
+
let lines_praise = []
|
12 |
+
|
13 |
+
function addInit() {
|
14 |
+
return true;
|
15 |
+
}
|
16 |
+
|
17 |
+
function gradioApp() {
|
18 |
+
const elems = document.getElementsByTagName('gradio-app');
|
19 |
+
const elem = elems.length == 0 ? document : elems[0];
|
20 |
+
|
21 |
+
if (elem !== document) {
|
22 |
+
elem.getElementById = function(id) {
|
23 |
+
return document.getElementById(id);
|
24 |
+
};
|
25 |
+
}
|
26 |
+
return elem.shadowRoot ? elem.shadowRoot : elem;
|
27 |
+
}
|
28 |
+
|
29 |
+
function initialize() {
|
30 |
+
gradioObserver.observe(gradioApp(), { childList: true, subtree: true });
|
31 |
+
|
32 |
+
gradioContainer = gradioApp().querySelector(".gradio-container");
|
33 |
+
|
34 |
+
fetch('file=assets/lines.json')
|
35 |
+
.then(response => {
|
36 |
+
if (!response.ok) {
|
37 |
+
throw new Error('Network response was not ok');
|
38 |
+
}
|
39 |
+
return response.json();
|
40 |
+
})
|
41 |
+
.then(data => {
|
42 |
+
lines_json = data;
|
43 |
+
set_speak_examples();
|
44 |
+
})
|
45 |
+
.catch(error => {
|
46 |
+
console.error('There has been a problem with your fetch operation:', error);
|
47 |
+
});
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
return true;
|
52 |
+
}
|
53 |
+
|
54 |
+
function set_speak_examples() {
|
55 |
+
buttons = gradioApp().querySelectorAll("#examples div button");
|
56 |
+
speak_input = gradioApp().querySelector("#speak_input label textarea");
|
57 |
+
|
58 |
+
let lines_praise = lines_json["夸夸你 | Praise"];
|
59 |
+
let lines_scripts = lines_json["游戏台词 | Scripts"];
|
60 |
+
let lines_meme = lines_json["玩梗 | Meme"];
|
61 |
+
let praiseArray = Object.values(lines_praise);
|
62 |
+
let scriptsArray = Object.values(lines_scripts);
|
63 |
+
let memeArray = Object.values(lines_meme);
|
64 |
+
|
65 |
+
buttons[0].addEventListener("click", function() {
|
66 |
+
const randomString = praiseArray[Math.floor(Math.random() * praiseArray.length)];
|
67 |
+
speak_input.value = randomString;
|
68 |
+
});
|
69 |
+
buttons[1].addEventListener("click", function() {
|
70 |
+
const randomString = scriptsArray[Math.floor(Math.random() * scriptsArray.length)];
|
71 |
+
speak_input.value = randomString;
|
72 |
+
});
|
73 |
+
buttons[2].addEventListener("click", function() {
|
74 |
+
const randomString = memeArray[Math.floor(Math.random() * memeArray.length)];
|
75 |
+
speak_input.value = randomString;
|
76 |
+
});
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
// 监视页面内部 DOM 变动
|
81 |
+
var gradioObserver = new MutationObserver(function (mutations) {
|
82 |
+
for (var i = 0; i < mutations.length; i++) {
|
83 |
+
if (mutations[i].addedNodes.length) {
|
84 |
+
if (addInit()) {
|
85 |
+
gradioObserver.disconnect();
|
86 |
+
return;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
}
|
90 |
+
});
|
91 |
+
|
92 |
+
// 监视页面变化
|
93 |
+
window.addEventListener("DOMContentLoaded", function () {
|
94 |
+
windowWidth = window.innerWidth;
|
95 |
+
gradioApp().addEventListener("render", initialize);
|
96 |
+
isInIframe = (window.self !== window.top);
|
97 |
+
});
|
98 |
+
|
99 |
+
console.log("Welcome to TalkingFlower!");
|
tools/__pycache__/webui.cpython-39.pyc
CHANGED
Binary files a/tools/__pycache__/webui.cpython-39.pyc and b/tools/__pycache__/webui.cpython-39.pyc differ
|
|
tools/webui.py
CHANGED
@@ -1,8 +1,12 @@
|
|
|
|
1 |
import gradio as gr
|
2 |
import os
|
3 |
|
|
|
|
|
4 |
GradioTemplateResponseOriginal = gr.routes.templates.TemplateResponse
|
5 |
-
|
|
|
6 |
|
7 |
def get_character_html(text):
|
8 |
return f"""\
|
@@ -26,7 +30,7 @@ def list_scripts(scriptdirname, extension):
|
|
26 |
scripts_dir = os.path.join(root_path, scriptdirname)
|
27 |
if os.path.exists(scripts_dir):
|
28 |
for filename in sorted(os.listdir(scripts_dir)):
|
29 |
-
scripts_list.append(ScriptFile(
|
30 |
scripts_list = [x for x in scripts_list if os.path.splitext(x.path)[1].lower() == extension and os.path.isfile(x.path)]
|
31 |
return scripts_list
|
32 |
|
|
|
1 |
+
from collections import namedtuple
|
2 |
import gradio as gr
|
3 |
import os
|
4 |
|
5 |
+
ScriptFile = namedtuple("ScriptFile", ["basedir", "filename", "path"])
|
6 |
+
|
7 |
GradioTemplateResponseOriginal = gr.routes.templates.TemplateResponse
|
8 |
+
current_dir = os.path.dirname(os.path.realpath(__file__))
|
9 |
+
root_path = os.path.dirname(current_dir)
|
10 |
|
11 |
def get_character_html(text):
|
12 |
return f"""\
|
|
|
30 |
scripts_dir = os.path.join(root_path, scriptdirname)
|
31 |
if os.path.exists(scripts_dir):
|
32 |
for filename in sorted(os.listdir(scripts_dir)):
|
33 |
+
scripts_list.append(ScriptFile(f"{root_path}/javascript", filename, os.path.join(scripts_dir, filename)))
|
34 |
scripts_list = [x for x in scripts_list if os.path.splitext(x.path)[1].lower() == extension and os.path.isfile(x.path)]
|
35 |
return scripts_list
|
36 |
|