Fish Speech 1.5 结合 Whisper 打造语音处理自动化闭环
将 Fish Speech 1.5 与 Whisper 语音识别模型结合,可以构建一个'语音→文本→语音'的智能闭环。这不仅能自动整理会议录音生成纪要,还能实现外语视频的翻译配音,保持原说话人的音色。无论你是内容创作者还是开发者,这套组合都能显著提升效率。
为什么需要语音闭环?
单独使用 Fish Speech 合成语音已经很强,但整合 Whisper 能解放双手。传统流程需要手动转录、编辑、再合成,繁琐且易错。闭环系统则能:
- 自动化处理:上传音频,自动完成识别、处理、合成。
- 音色一致性:视频配音时,先识别原音,再克隆音色合成新语音。
- 无障碍应用:快速为音频生成字幕,或为字幕生成语音导读。
- 内容再创作:轻松实现语音内容的翻译、摘要后以语音形式输出。
Fish Speech 负责'说',Whisper 负责'听',两者结合才是一个完整的对话系统。
环境搭建与工具准备
假设你已经部署了 Fish Speech 1.5 的 Web 服务(通常地址类似 http://localhost:7860),这是我们的语音合成端。
部署 Whisper 语音识别服务
Whisper 是 OpenAI 开源的强大模型,支持多语言。
方案一:本地部署(推荐)
pip install -U openai-whisper
sudo apt update && sudo apt install ffmpeg # Ubuntu/Debian
brew install ffmpeg # MacOS
whisper --help # 验证安装
方案二:在线 API 如果不方便本地部署,可使用提供 Whisper API 的在线服务,替换调用逻辑即可。
编写调度脚本
我们需要一个 Python 脚本作为'调度员',连接识别与合成服务。创建一个名为 speech_loop.py 的文件。
import requests
import whisper
import soundfile as sf
import io
import json
import logging
from typing import Optional
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class SpeechTextSpeechLoop:
def __init__(self, fish_speech_url: str, whisper_model_size: = ):
.fish_speech_url = fish_speech_url.rstrip()
logger.info()
.whisper_model = whisper.load_model(whisper_model_size)
logger.info()
() -> :
logger.info()
result = .whisper_model.transcribe(audio_path, language=language, fp16=)
text = result[].strip()
logger.info()
text
() -> :
operation == :
text
operation == :
logger.warning()
text
operation == :
logger.warning()
text
:
logger.error()
text
() -> []:
payload = {
: text,
: ,
: ,
: ,
: ,
}
files = {}
reference_audio_path ref_text:
:
files[] = (reference_audio_path, )
payload[] = ref_text
logger.info()
FileNotFoundError:
logger.error()
api_endpoint =
logger.info()
:
files:
response = requests.post(api_endpoint, data=payload, files=files)
files[].close()
:
response = requests.post(api_endpoint, json=payload)
response.raise_for_status()
response.headers.get(, ).startswith():
response.content
:
result = response.json()
logger.info()
requests.exceptions.RequestException e:
logger.error()
():
logger.info()
transcribed_text = .transcribe_audio(input_audio_path)
processed_text = .process_text(transcribed_text, text_operation)
logger.info()
audio_data = .synthesize_speech(processed_text, reference_audio_for_clone, ref_text_for_clone)
audio_data:
(output_audio_path, ) f:
f.write(audio_data)
logger.info()
:
logger.error()
__name__ == :
FISH_SPEECH_URL =
INPUT_AUDIO =
OUTPUT_AUDIO =
TEXT_OPERATION =
REF_AUDIO =
REF_TEXT =
processor = SpeechTextSpeechLoop(FISH_SPEECH_URL, whisper_model_size=)
success = processor.run_pipeline(
input_audio_path=INPUT_AUDIO,
output_audio_path=OUTPUT_AUDIO,
text_operation=TEXT_OPERATION,
reference_audio_for_clone=REF_AUDIO,
ref_text_for_clone=REF_TEXT
)

