You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:30:15