diff --git a/backend/app/routes/tts_synthesize.py b/backend/app/routes/tts_synthesize.py
index ffe5da2..e4b2c1b 100644
--- a/backend/app/routes/tts_synthesize.py
+++ b/backend/app/routes/tts_synthesize.py
@@ -3,6 +3,7 @@ import base64
import os
from app.services.minimax_service import synthesize_minimax
from app.services.cosyvoice_service import synthesize_cosyvoice
+from app.services.doubao_service import synthesize_doubao
from app.routes.auth import login_required
from app.db import get_db
@@ -37,6 +38,11 @@ def synthesize():
text=text, speed=speed, pitch=pitch,
volume=volume, instruction=instruction
)
+ elif engine == 'doubao':
+ audio_data = synthesize_doubao(
+ text=text, speed=speed, pitch=pitch,
+ volume=volume, emotion=emotion
+ )
else:
audio_data = synthesize_minimax(
text=text, speed=speed, pitch=pitch,
diff --git a/backend/app/services/doubao_service.py b/backend/app/services/doubao_service.py
new file mode 100644
index 0000000..7eece74
--- /dev/null
+++ b/backend/app/services/doubao_service.py
@@ -0,0 +1,52 @@
+import os
+import uuid
+import requests
+
+def synthesize_doubao(text, speed=1.0, pitch=0, volume=1.0, emotion='neutral'):
+ """调用火山引擎豆包 Seed-ICL 2.0 语音合成 API"""
+ api_key = os.getenv('DOUBAO_API_KEY', '')
+ if not api_key:
+ raise ValueError('DOUBAO_API_KEY未设置')
+
+ url = 'https://openspeech.bytedance.com/api/v1/tts'
+ headers = {
+ 'x-api-key': api_key,
+ 'Content-Type': 'application/json'
+ }
+
+ payload = {
+ 'app': {
+ 'cluster': 'volcano_icl'
+ },
+ 'user': {
+ 'uid': 'military_tech_voice'
+ },
+ 'audio': {
+ 'voice_type': 'S_MK0j18H72',
+ 'encoding': 'mp3',
+ 'speed_ratio': speed,
+ },
+ 'request': {
+ 'reqid': str(uuid.uuid4()),
+ 'text': text,
+ 'operation': 'query'
+ }
+ }
+
+ response = requests.post(url, json=payload, headers=headers, timeout=60)
+
+ if response.status_code != 200:
+ raise Exception(f'豆包API错误: {response.status_code} - {response.text}')
+
+ result = response.json()
+
+ # 豆包返回格式: {"code": 3000, "data": "base64编码的音频"}
+ if result.get('code') == 3000 and result.get('data'):
+ import base64
+ audio_bytes = base64.b64decode(result['data'])
+ return audio_bytes
+
+ # 错误处理
+ error_msg = result.get('message', '未知错误')
+ error_code = result.get('code', 'unknown')
+ raise Exception(f'豆包返回错误 [{error_code}]: {error_msg}')
diff --git a/frontend/app.js b/frontend/app.js
index 8476c9c..b9e9cca 100644
--- a/frontend/app.js
+++ b/frontend/app.js
@@ -17,6 +17,11 @@ const ENGINE_CONFIG = {
name: 'CosyVoice',
emotionMode: 'global',
color: '#ff6b6b'
+ },
+ doubao: {
+ name: '豆包',
+ emotionMode: 'global',
+ color: '#7c5cfc'
}
};
diff --git a/frontend/index.html b/frontend/index.html
index 3373a3c..38ccadc 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -40,6 +40,7 @@
情绪: