Spaces:
Running
Running
Commit
·
f55b556
1
Parent(s):
3fd7282
(wip)debug
Browse files- templates/arena.html +62 -53
- tts.py +1 -1
templates/arena.html
CHANGED
@@ -26,6 +26,7 @@
|
|
26 |
<input type="file" id="voice-file" accept="audio/*">
|
27 |
<audio id="voice-preview" controls style="display:none;"></audio>
|
28 |
</div>
|
|
|
29 |
<div class="input-group">
|
30 |
<button type="button" class="segmented-btn random-btn" title="Roll random text">
|
31 |
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
@@ -45,7 +46,8 @@
|
|
45 |
</form>
|
46 |
|
47 |
<div id="initial-keyboard-hint" class="keyboard-hint">
|
48 |
-
Press <kbd>R</kbd> for random text, <kbd>
|
|
|
49 |
</div>
|
50 |
|
51 |
<div class="loading-container" style="display: none;">
|
@@ -107,7 +109,8 @@
|
|
107 |
<button class="next-round-btn">Next Round</button>
|
108 |
</div>
|
109 |
<div id="playback-keyboard-hint" class="keyboard-hint" style="display: none;">
|
110 |
-
Press <kbd>Space</kbd> to play/pause, <kbd>A</kbd>/<kbd>B</kbd> to vote, <kbd>R</kbd> for random text, <kbd>
|
|
|
111 |
for next random round
|
112 |
</div>
|
113 |
</div>
|
@@ -141,18 +144,13 @@
|
|
141 |
|
142 |
.random-voice-btn {
|
143 |
height: 36px;
|
144 |
-
width:
|
145 |
-
background-color: white;
|
146 |
border: 1px solid var(--border-color);
|
147 |
border-radius: var(--radius);
|
148 |
margin-right: 10px;
|
149 |
flex-shrink: 0;
|
150 |
}
|
151 |
|
152 |
-
.random-voice-btn:hover {
|
153 |
-
background-color: var(--light-gray);
|
154 |
-
}
|
155 |
-
|
156 |
.random-voice-btn svg {
|
157 |
color: var(--primary-color);
|
158 |
}
|
@@ -629,51 +627,7 @@
|
|
629 |
const voiceFileInput = document.getElementById('voice-file');
|
630 |
const voicePreview = document.getElementById('voice-preview');
|
631 |
if (randomVoiceBtn && voiceFileInput && voicePreview) {
|
632 |
-
randomVoiceBtn.addEventListener('click',
|
633 |
-
// 显示加载状态
|
634 |
-
randomVoiceBtn.classList.add('loading');
|
635 |
-
|
636 |
-
// 获取随机参考音色
|
637 |
-
fetch('/api/voice/random')
|
638 |
-
.then(response => {
|
639 |
-
if (!response.ok) {
|
640 |
-
throw new Error('获取随机音色失败');
|
641 |
-
}
|
642 |
-
return response.blob();
|
643 |
-
})
|
644 |
-
.then(audioBlob => {
|
645 |
-
// 创建文件对象,用于合成时提交
|
646 |
-
const fileName = 'random_voice_sample.' +
|
647 |
-
(audioBlob.type.split('/')[1] || 'mp3');
|
648 |
-
|
649 |
-
// 创建File对象,用于后续上传
|
650 |
-
const audioFile = new File([audioBlob], fileName, {type: audioBlob.type});
|
651 |
-
|
652 |
-
// 创建一个DataTransfer对象来模拟文件输入
|
653 |
-
const dataTransfer = new DataTransfer();
|
654 |
-
dataTransfer.items.add(audioFile);
|
655 |
-
voiceFileInput.files = dataTransfer.files;
|
656 |
-
|
657 |
-
// 更新音频预览
|
658 |
-
const audioUrl = URL.createObjectURL(audioBlob);
|
659 |
-
voicePreview.src = audioUrl;
|
660 |
-
voicePreview.style.display = 'inline-block';
|
661 |
-
voicePreview.load();
|
662 |
-
voicePreview.play();
|
663 |
-
|
664 |
-
// 触发change事件,确保其他监听器知道文件已更改
|
665 |
-
const event = new Event('change', {bubbles: true});
|
666 |
-
voiceFileInput.dispatchEvent(event);
|
667 |
-
})
|
668 |
-
.catch(error => {
|
669 |
-
console.error('获取随机音色出错:', error);
|
670 |
-
openToast ? openToast("获取随机参考音色失败", "error") : alert("获取随机参考音色失败");
|
671 |
-
})
|
672 |
-
.finally(() => {
|
673 |
-
// 移除加载状态
|
674 |
-
randomVoiceBtn.classList.remove('loading');
|
675 |
-
});
|
676 |
-
});
|
677 |
voiceFileInput.addEventListener('change', function () {
|
678 |
const file = this.files[0];
|
679 |
if (file) {
|
@@ -1056,6 +1010,56 @@
|
|
1056 |
textInput.focus();
|
1057 |
}
|
1058 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1059 |
function showListenToastMessage() {
|
1060 |
openToast("Please listen to both audio samples before voting", "info");
|
1061 |
}
|
@@ -1139,6 +1143,11 @@
|
|
1139 |
e.preventDefault();
|
1140 |
handleRandom();
|
1141 |
}
|
|
|
|
|
|
|
|
|
|
|
1142 |
} else if (e.key === ' ') {
|
1143 |
// Space to play/pause current audio
|
1144 |
if (playersContainer.style.display !== 'none') {
|
|
|
26 |
<input type="file" id="voice-file" accept="audio/*">
|
27 |
<audio id="voice-preview" controls style="display:none;"></audio>
|
28 |
</div>
|
29 |
+
<hr>
|
30 |
<div class="input-group">
|
31 |
<button type="button" class="segmented-btn random-btn" title="Roll random text">
|
32 |
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
|
|
46 |
</form>
|
47 |
|
48 |
<div id="initial-keyboard-hint" class="keyboard-hint">
|
49 |
+
Press <kbd>R</kbd> for random text, <kbd>V</kbd> for random reference voice, <kbd>N</kbd> for next random
|
50 |
+
round, <kbd>Enter</kbd> to generate
|
51 |
</div>
|
52 |
|
53 |
<div class="loading-container" style="display: none;">
|
|
|
109 |
<button class="next-round-btn">Next Round</button>
|
110 |
</div>
|
111 |
<div id="playback-keyboard-hint" class="keyboard-hint" style="display: none;">
|
112 |
+
Press <kbd>Space</kbd> to play/pause, <kbd>A</kbd>/<kbd>B</kbd> to vote, <kbd>R</kbd> for random text, <kbd>V</kbd>
|
113 |
+
for random reference voice, <kbd>N</kbd>
|
114 |
for next random round
|
115 |
</div>
|
116 |
</div>
|
|
|
144 |
|
145 |
.random-voice-btn {
|
146 |
height: 36px;
|
147 |
+
width: 48px;
|
|
|
148 |
border: 1px solid var(--border-color);
|
149 |
border-radius: var(--radius);
|
150 |
margin-right: 10px;
|
151 |
flex-shrink: 0;
|
152 |
}
|
153 |
|
|
|
|
|
|
|
|
|
154 |
.random-voice-btn svg {
|
155 |
color: var(--primary-color);
|
156 |
}
|
|
|
627 |
const voiceFileInput = document.getElementById('voice-file');
|
628 |
const voicePreview = document.getElementById('voice-preview');
|
629 |
if (randomVoiceBtn && voiceFileInput && voicePreview) {
|
630 |
+
randomVoiceBtn.addEventListener('click', handleRandomVoice);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
631 |
voiceFileInput.addEventListener('change', function () {
|
632 |
const file = this.files[0];
|
633 |
if (file) {
|
|
|
1010 |
textInput.focus();
|
1011 |
}
|
1012 |
|
1013 |
+
function handleRandomVoice() {
|
1014 |
+
const randomVoiceBtn = document.querySelector('.random-voice-btn');
|
1015 |
+
const voiceFileInput = document.getElementById('voice-file');
|
1016 |
+
const voicePreview = document.getElementById('voice-preview');
|
1017 |
+
|
1018 |
+
// 显示加载状态
|
1019 |
+
randomVoiceBtn.classList.add('loading');
|
1020 |
+
|
1021 |
+
// 获取随机参考音色
|
1022 |
+
fetch('/api/voice/random')
|
1023 |
+
.then(response => {
|
1024 |
+
if (!response.ok) {
|
1025 |
+
throw new Error('获取随机音色失败');
|
1026 |
+
}
|
1027 |
+
return response.blob();
|
1028 |
+
})
|
1029 |
+
.then(audioBlob => {
|
1030 |
+
// 创建文件对象,用于合成时提交
|
1031 |
+
const fileName = 'random_voice_sample.' +
|
1032 |
+
(audioBlob.type.split('/')[1] || 'mp3');
|
1033 |
+
|
1034 |
+
// 创建File对象,用于后续上传
|
1035 |
+
const audioFile = new File([audioBlob], fileName, {type: audioBlob.type});
|
1036 |
+
|
1037 |
+
// 创建一个DataTransfer对象来模拟文件输入
|
1038 |
+
const dataTransfer = new DataTransfer();
|
1039 |
+
dataTransfer.items.add(audioFile);
|
1040 |
+
voiceFileInput.files = dataTransfer.files;
|
1041 |
+
|
1042 |
+
// 更新音频预览
|
1043 |
+
const audioUrl = URL.createObjectURL(audioBlob);
|
1044 |
+
voicePreview.src = audioUrl;
|
1045 |
+
voicePreview.style.display = 'inline-block';
|
1046 |
+
voicePreview.load();
|
1047 |
+
voicePreview.play();
|
1048 |
+
|
1049 |
+
// 触发change事件,确保其他监听器知道文件已更改
|
1050 |
+
const event = new Event('change', {bubbles: true});
|
1051 |
+
voiceFileInput.dispatchEvent(event);
|
1052 |
+
})
|
1053 |
+
.catch(error => {
|
1054 |
+
console.error('获取随机音色出错:', error);
|
1055 |
+
openToast ? openToast("获取随机参考音色失败", "error") : alert("获取随机参考音色失败");
|
1056 |
+
})
|
1057 |
+
.finally(() => {
|
1058 |
+
// 移除加载状态
|
1059 |
+
randomVoiceBtn.classList.remove('loading');
|
1060 |
+
});
|
1061 |
+
}
|
1062 |
+
|
1063 |
function showListenToastMessage() {
|
1064 |
openToast("Please listen to both audio samples before voting", "info");
|
1065 |
}
|
|
|
1143 |
e.preventDefault();
|
1144 |
handleRandom();
|
1145 |
}
|
1146 |
+
} else if (e.key.toLowerCase() === 'v') {
|
1147 |
+
if (!e.ctrlKey && !e.metaKey && !e.altKey) {
|
1148 |
+
e.preventDefault();
|
1149 |
+
handleRandomVoice();
|
1150 |
+
}
|
1151 |
} else if (e.key === ' ') {
|
1152 |
// Space to play/pause current audio
|
1153 |
if (playersContainer.style.display !== 'none') {
|
tts.py
CHANGED
@@ -47,7 +47,7 @@ data = {"text": "string", "provider": "string", "model": "string"}
|
|
47 |
|
48 |
def predict_index_tts(text, reference_audio_path=None):
|
49 |
from gradio_client import Client, handle_file
|
50 |
-
client = Client("kemuriririn/IndexTTS")
|
51 |
if reference_audio_path:
|
52 |
prompt = handle_file(reference_audio_path)
|
53 |
else:
|
|
|
47 |
|
48 |
def predict_index_tts(text, reference_audio_path=None):
|
49 |
from gradio_client import Client, handle_file
|
50 |
+
client = Client("kemuriririn/IndexTTS",verbose=True)
|
51 |
if reference_audio_path:
|
52 |
prompt = handle_file(reference_audio_path)
|
53 |
else:
|