feat: 接入 Fish Audio TTS 引擎

- 新增 fish_audio_service.py,使用 REST API 调用
- voice_id: 34e841f0f4ff44aca6e396debf2776d4(蓝皓音色克隆)
- 支持语速/音量控制,情绪通过内嵌标签实现
- 前端引擎下拉菜单新增 Fish Audio 选项

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lanhao
2026-07-02 23:29:15 +08:00
parent 1ad214f5d5
commit 433903365c
4 changed files with 58 additions and 0 deletions
@@ -0,0 +1,46 @@
import os
import requests
def synthesize_fish_audio(text, speed=1.0, pitch=0, volume=1.0, emotion='neutral'):
api_key = os.getenv('FISH_AUDIO_API_KEY', '')
if not api_key:
raise ValueError('FISH_AUDIO_API_KEY未设置')
voice_id = os.getenv('FISH_AUDIO_VOICE_ID', '34e841f0f4ff44aca6e396debf2776d4')
emotion_tags = {
'happy': '[happy]',
'sad': '[sad]',
'angry': '[angry]',
'surprised': '[excited]',
'fearful': '[nervous]',
}
tag = emotion_tags.get(emotion, '')
if tag:
text = f"{tag}{text}"
url = 'https://api.fish.audio/v1/tts'
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
payload = {
'text': text,
'reference_id': voice_id,
'format': 'mp3',
'speed': max(0.5, min(2.0, speed)),
'volume': max(-20, min(20, (volume - 1.0) * 20)),
}
response = requests.post(url, json=payload, headers=headers, timeout=60, stream=True)
if response.status_code != 200:
raise Exception(f'Fish Audio API错误: {response.status_code} - {response.text[:200]}')
audio_bytes = response.content
if not audio_bytes:
raise Exception('Fish Audio返回空音频')
return audio_bytes