feat: add style selection for TTS and update related functionality
This commit is contained in:
@@ -2,6 +2,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// 获取DOM元素
|
||||
const textInput = document.getElementById('text');
|
||||
const voiceSelect = document.getElementById('voice');
|
||||
const styleSelect = document.getElementById('style');
|
||||
const rateInput = document.getElementById('rate');
|
||||
const rateValue = document.getElementById('rateValue');
|
||||
const pitchInput = document.getElementById('pitch');
|
||||
@@ -15,6 +16,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// 保存最后一个音频URL
|
||||
let lastAudioUrl = '';
|
||||
// 存储语音数据
|
||||
let voicesData = [];
|
||||
|
||||
// 初始化
|
||||
initVoicesList();
|
||||
@@ -37,13 +40,18 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
pitchValue.textContent = value + '%';
|
||||
});
|
||||
|
||||
// 语音选择变化时更新可用风格
|
||||
voiceSelect.addEventListener('change', function() {
|
||||
updateStyleOptions();
|
||||
});
|
||||
|
||||
// 获取可用语音列表
|
||||
async function initVoicesList() {
|
||||
try {
|
||||
const response = await fetch(`${config.basePath}/voices`);
|
||||
if (!response.ok) throw new Error('获取语音列表失败');
|
||||
|
||||
const voices = await response.json();
|
||||
voicesData = await response.json();
|
||||
|
||||
// 清空并重建选项
|
||||
voiceSelect.innerHTML = '';
|
||||
@@ -51,7 +59,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// 按语言和名称分组
|
||||
const voicesByLocale = {};
|
||||
|
||||
voices.forEach(voice => {
|
||||
voicesData.forEach(voice => {
|
||||
if (!voicesByLocale[voice.locale]) {
|
||||
voicesByLocale[voice.locale] = [];
|
||||
}
|
||||
@@ -78,12 +86,49 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
voiceSelect.appendChild(optgroup);
|
||||
}
|
||||
|
||||
// 初始化风格列表
|
||||
updateStyleOptions();
|
||||
} catch (error) {
|
||||
console.error('获取语音列表失败:', error);
|
||||
voiceSelect.innerHTML = '<option value="">无法加载语音列表</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// 更新风格选项
|
||||
function updateStyleOptions() {
|
||||
// 清空风格选择
|
||||
styleSelect.innerHTML = '';
|
||||
|
||||
// 获取当前选中的语音
|
||||
const selectedVoice = voiceSelect.value;
|
||||
const voiceData = voicesData.find(v => v.short_name === selectedVoice);
|
||||
|
||||
if (!voiceData || !voiceData.style_list || voiceData.style_list.length === 0) {
|
||||
// 如果没有可用风格,添加默认选项
|
||||
const option = document.createElement('option');
|
||||
option.value = "general";
|
||||
option.textContent = "普通";
|
||||
styleSelect.appendChild(option);
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加可用风格选项
|
||||
voiceData.style_list.forEach(style => {
|
||||
const option = document.createElement('option');
|
||||
option.value = style
|
||||
option.textContent = style
|
||||
|
||||
// 如果是默认风格则选中
|
||||
if (style === config.defaultStyle ||
|
||||
(!config.defaultStyle && style === "general")) {
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
styleSelect.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化事件监听器
|
||||
function initEventListeners() {
|
||||
// 转换按钮点击事件
|
||||
@@ -137,6 +182,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
const voice = voiceSelect.value;
|
||||
const style = styleSelect.value;
|
||||
const rate = rateInput.value;
|
||||
const pitch = pitchInput.value;
|
||||
|
||||
@@ -149,6 +195,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const params = new URLSearchParams({
|
||||
t: text,
|
||||
v: voice,
|
||||
s: style,
|
||||
r: rate,
|
||||
p: pitch
|
||||
});
|
||||
|
||||
@@ -34,15 +34,22 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label for="style">风格:</label>
|
||||
<select id="style">
|
||||
<option value="loading">加载中...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label for="rate">语速:</label>
|
||||
<input type="range" id="rate" min="-50" max="50" value="0">
|
||||
<input type="range" id="rate" min="-100" max="100" value="0">
|
||||
<span id="rateValue">0%</span>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label for="pitch">语调:</label>
|
||||
<input type="range" id="pitch" min="-50" max="50" value="0">
|
||||
<input type="range" id="pitch" min="-100" max="100" value="0">
|
||||
<span id="pitchValue">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,7 +82,8 @@
|
||||
basePath: "{{.BasePath}}",
|
||||
defaultVoice: "{{.DefaultVoice}}",
|
||||
defaultRate: "{{.DefaultRate}}",
|
||||
defaultPitch: "{{.DefaultPitch}}"
|
||||
defaultPitch: "{{.DefaultPitch}}",
|
||||
defaultStyle: "{{.DefaultStyle}}"
|
||||
};
|
||||
</script>
|
||||
<script src="{{.BasePath}}/static/js/app.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user