文本转语音 API
-
/tts?api_key={key}&t={text}&v={voice}&r={rate}&p={pitch}
+
/tts?api_key={key}&t={text}&v={voice}&r={rate}&p={pitch}&s={style}
- api_key: API密钥 [必填]
- t: 文本内容 [必填]
- v: 语音名称 [可选]
- r: 语速调整 (-100~100) [可选]
- p: 音调调整 (-100~100) [可选]
+ - s: 语音风格 (general, cheerful, sad等) [可选]
OpenAI 兼容接口
@@ -382,6 +431,33 @@ curl ${baseUrl}/v1/audio/speech \\
// 存储所有语音数据
let allVoices = [];
+ // 在表单提交事件监听器之前添加语音选择变更事件监听
+ document.addEventListener('DOMContentLoaded', function() {
+ // 添加对语音选择变化的监听
+ document.getElementById('voice').addEventListener('change', function() {
+ updateStyleOptions(this.value);
+ });
+
+ const tabLinks = document.querySelectorAll('.tab-link');
+ const tabContents = document.querySelectorAll('.tab-content');
+
+ tabLinks.forEach(link => {
+ link.addEventListener('click', () => {
+ tabLinks.forEach(l => {
+ l.classList.remove('text-ms-blue', 'border-ms-blue');
+ l.classList.add('text-gray-500');
+ });
+ link.classList.add('text-ms-blue', 'border-ms-blue');
+ link.classList.remove('text-gray-500');
+
+ const targetId = link.getAttribute('data-tab');
+ tabContents.forEach(tc => {
+ tc.style.display = (tc.id === targetId) ? '' : 'none';
+ });
+ });
+ });
+ });
+
document.getElementById('ttsForm').addEventListener('submit', async function(e) {
e.preventDefault();
@@ -393,6 +469,7 @@ curl ${baseUrl}/v1/audio/speech \\
const voice = document.getElementById('voice').value;
const rate = document.getElementById('rate').value;
const pitch = document.getElementById('pitch').value;
+ const style = document.getElementById('style').value; // 获取选择的风格
if (!text) {
showError('请输入要转换的文本', '文本内容不能为空');
@@ -404,7 +481,7 @@ curl ${baseUrl}/v1/audio/speech \\
return;
}
- const url = \`${baseUrl}/tts?api_key=\${apiKey}&t=\${text}&v=\${voice}&r=\${rate}&p=\${pitch}\`;
+ const url = \`${baseUrl}/tts?api_key=\${apiKey}&t=\${text}&v=\${voice}&r=\${rate}&p=\${pitch}&s=\${style}\`;
try {
const response = await fetch(url);
@@ -452,6 +529,69 @@ curl ${baseUrl}/v1/audio/speech \\
errorAlert.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
+ // 更新风格选项的函数
+ function updateStyleOptions(voiceName) {
+ const styleSelect = document.getElementById('style');
+ // 清空现有选项
+ styleSelect.innerHTML = '';
+
+ // 默认添加标准风格
+ const defaultOption = document.createElement('option');
+ defaultOption.value = 'general';
+ defaultOption.text = '标准';
+ styleSelect.appendChild(defaultOption);
+
+ // 查找选定的语音对象
+ const selectedVoice = allVoices.find(v => v.ShortName === voiceName);
+
+ if (selectedVoice && selectedVoice.StyleList && selectedVoice.StyleList.length > 0) {
+ // 对风格列表进行排序
+ const styles = [...selectedVoice.StyleList].sort();
+
+ // 为每个风格创建选项
+ styles.forEach(style => {
+ // 跳过已经添加的"general"
+ if (style.toLowerCase() === 'general') return;
+
+ const option = document.createElement('option');
+ option.value = style;
+ // 根据风格名称进行本地化显示
+ option.text = getStyleDisplayName(style);
+ styleSelect.appendChild(option);
+ });
+ }
+ }
+
+ // 风格名称本地化显示
+ function getStyleDisplayName(styleName) {
+ const styleMap = {
+ 'angry': '愤怒',
+ 'cheerful': '欢快',
+ 'sad': '悲伤',
+ 'fearful': '恐惧',
+ 'disgruntled': '不满',
+ 'serious': '严肃',
+ 'affectionate': '深情',
+ 'gentle': '温柔',
+ 'embarrassed': '尴尬',
+ 'assistant': '助手',
+ 'calm': '平静',
+ 'chat': '聊天',
+ 'excited': '兴奋',
+ 'friendly': '友好',
+ 'hopeful': '希望',
+ 'narration-professional': '专业叙述',
+ 'newscast': '新闻播报',
+ 'newscast-casual': '随性新闻',
+ 'poetry-reading': '诗歌朗诵',
+ 'shouting': '喊叫',
+ 'sports-commentary': '体育解说',
+ 'whispering': '低语'
+ };
+
+ return styleMap[styleName.toLowerCase()] || styleName;
+ }
+
// 加载可用语音列表
async function loadVoices() {
try {
@@ -500,6 +640,9 @@ curl ${baseUrl}/v1/audio/speech \\
if (voiceSelect.querySelector(\`option[value="\${defaultVoice}"]\`)) {
voiceSelect.value = defaultVoice;
}
+
+ // 加载初始选择语音的风格选项
+ updateStyleOptions(voiceSelect.value);
} else {
console.error('获取语音列表失败:', response.status);
showDefaultVoices();
@@ -563,31 +706,19 @@ curl ${baseUrl}/v1/audio/speech \\
// 默认选择晓晓多语言
voiceSelect.value = "zh-CN-XiaoxiaoMultilingualNeural";
+
+ // 设置默认风格
+ const styleSelect = document.getElementById('style');
+ styleSelect.innerHTML = '';
+ const defaultOption = document.createElement('option');
+ defaultOption.value = 'general';
+ defaultOption.text = '标准';
+ styleSelect.appendChild(defaultOption);
}
// 页面加载完成后加载语音列表
window.onload = loadVoices;
- document.addEventListener('DOMContentLoaded', function() {
- const tabLinks = document.querySelectorAll('.tab-link');
- const tabContents = document.querySelectorAll('.tab-content');
-
- tabLinks.forEach(link => {
- link.addEventListener('click', () => {
- tabLinks.forEach(l => {
- l.classList.remove('text-ms-blue', 'border-ms-blue');
- l.classList.add('text-gray-500');
- });
- link.classList.add('text-ms-blue', 'border-ms-blue');
- link.classList.remove('text-gray-500');
-
- const targetId = link.getAttribute('data-tab');
- tabContents.forEach(tc => {
- tc.style.display = (tc.id === targetId) ? '' : 'none';
- });
- });
- });
- });