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 |
|