如何在Twilio Programmable Voice中使用自定义合成语音
用自定义语音克隆模型替代Twilio默认TTS(如Polly)实现实时通话语音
核心方案概述
要在Twilio Programmable Voice中使用自定义合成语音,核心是通过Twilio Media Streams建立通话与后端服务的实时音频通道:Twilio将通话中的音频流推送到你的WebSocket服务,后端用语音克隆模型生成回应语音,再把编码后的音频回传给Twilio,最终实现通话中替换默认语音的效果。
分步实现及代码示例
1. 搭建Twilio来电路由Webhook(Flask)
这个端点负责处理Twilio的来电请求,启动Media Stream并保持通话连接:
from flask import Flask, request, Response from twilio.twiml.voice_response import VoiceResponse, Start import base64 import io app = Flask(__name__) @app.route("/incoming-call", methods=['POST']) def handle_incoming_call(): resp = VoiceResponse() # 启动媒体流,指向你的WebSocket音频处理服务 stream_start = Start() stream_start.stream(url='wss://你的服务器域名/audio-stream') resp.append(stream_start) # 初始提示音(可替换为自定义语音) resp.say("正在连接自定义语音服务,请稍候") return Response(str(resp), mimetype='application/xml') if __name__ == "__main__": # 本地测试需启用HTTPS,可使用自签名证书或ngrok转发 app.run(ssl_context='adhoc', port=5000)
2. 实时音频流处理服务(WebSocket)
这里接收Twilio的音频数据,调用语音克隆模型生成语音并回传:
import asyncio import websockets import json import base64 from pydub import AudioSegment import numpy as np # 导入你封装的语音克隆模型推理函数 # 此处需将目标语音克隆项目封装为可调用的函数 def clone_voice(input_audio_np, reference_voice_path): # 实现语音克隆逻辑:输入16kHz单声道音频数组,返回合成后的音频数组 # 替换为实际模型推理代码 from your_clone_module import infer return infer(input_audio_np, reference_voice_path) async def process_audio_stream(websocket, path): async for msg in websocket: data = json.loads(msg) if data['event'] == 'media': # 解码Twilio发送的PCMU音频(Base64编码) audio_raw = base64.b64decode(data['media']['payload']) # 转换为语音克隆模型支持的16kHz单声道格式 audio_segment = AudioSegment.from_raw( io.BytesIO(audio_raw), sample_width=1, frame_rate=8000, channels=1 ) audio_segment = audio_segment.set_frame_rate(16000).set_sample_width(2) audio_np = np.array(audio_segment.get_array_of_samples()) / 32768.0 # 调用语音克隆模型生成回应 cloned_audio_np = clone_voice(audio_np, reference_voice_path="你的参考语音文件.wav") # 将合成音频转换为Twilio支持的PCMU格式 output_segment = AudioSegment( (cloned_audio_np * 32767).astype(np.int16).tobytes(), frame_rate=16000, sample_width=2, channels=1 ).set_frame_rate(8000).set_sample_width(1) output_payload = base64.b64encode(output_segment.raw_data).decode('utf-8') # 发送合成语音回Twilio await websocket.send(json.dumps({ "event": "media", "media": {"payload": output_payload} })) # 启动WebSocket服务 start_server = websockets.serve(process_audio_stream, "0.0.0.0", 8765, ssl_context='adhoc') asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
关键注意事项
- 依赖安装:执行
pip install flask twilio websockets pydub numpy,同时安装FFmpeg(pydub依赖) - HTTPS/WSS要求:Twilio仅支持HTTPS/WSS,本地测试可使用ngrok转发端口(如
ngrok http 5000和ngrok tcp 8765) - 模型实时性:语音克隆模型的推理速度必须足够快(延迟低于200ms),否则会影响通话体验,可考虑优化模型或使用轻量化版本
- 格式兼容:Twilio默认使用PCMU编码(8kHz、单声道、8位),务必确保合成后的音频转换为该格式
内容的提问来源于stack exchange,提问作者Kris Saldana
相关产品推荐
相关产品推荐

