edge-tts语音合成总报错?这份完整排查手册帮你锁定根因
【免费下载链接】edge-ttsUse Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge项目地址: https://gitcode.com/GitHub_Trending/ed/edge-tts
用 edge-tts 做语音合成,常碰到 WebSocket 连接报错、"NoAudioReceived" 收不到音频、长文本合成中途断流。原因大多卡在签名、参数、连接三处,本文把整条链路捋一遍,教你逐个定位修复。
⚡ 一分钟自检——你的问题卡在哪一环
像医生首诊先摸脉,先缩小范围再开方子。跑两条最短命令:
edge-tts --list-voices | head -3 edge-tts --text "自检" --write-media /tmp/tts_selfcheck.mp3第一条测语音列表接口,第二条走完整合成。对照下表定位:
| 症状表现 | 大概率原因 | 跳转章节 |
|---|---|---|
| 两条都 403 或超时 | 时钟偏差或网络到不了服务 | WebSocket 握手返回 403 |
| 第一条正常,第二条报 NoAudioReceived | 语音名或参数写错 | 报错 NoAudioReceived |
| 第一条为空或报错 | 列表接口被拦或未配代理 | 语音列表拉取失败 |
| 短文本正常,长文本中途断 | 分块重连或超时太短 | 长文本合成中途断流 |
🔧 底层机制速览(为什么偏偏是这里出错)
语音合成的完整链路:客户端组装 SSML 文本、生成基于本地时钟且按 5 分钟取整的签名 tokenSec-MS-GEC(见 src/edge_tts/drm.py)→ 向wss://speech.platform.bing.com/.../edge/v1建立 WebSocket 连接 → 服务端合成后流式回传音频帧与边界元数据 → src/edge_tts/communicate.py 校验帧并写入 mp3。
好比点外卖:先签名订单(token),再拨通商家(WebSocket),厨房才会开始出餐(音频帧)。签名或拨号任何一步失败,订单就地作废。
高频故障节点:
- 签名时钟节点:token 由本地时间推导,时钟漂了,服务端直接 403 拒单。
- 连接解析节点:握手头校验、二进制帧结构检查;收到 403 会用服务端 Date 头校准时钟并重试一次。
- 语音列表节点:独立的 HTTPS 端点,与合成共用同一 token,见 src/edge_tts/voices.py。
🩹 按场景对症修复
同一个"订单未找到"提示,可能是名字写错,也可能是店根本没开门——报错也要分场景看。
WebSocket 握手返回 403
症状:连接阶段报403或ClientResponseError: 403。
根因:签名 token 基于本地时钟,时钟偏差会被服务端拒绝。库收到 403 后会自动校准时钟并重试一次;若仍 403,多是代理或出口策略拦截,或响应缺 Date 头导致校准失败(抛SkewAdjustmentError)。
修复动作:
- 同步系统时钟,如
timedatectl set-ntp true,手动校时后重试一次。 - 临时绕开代理重跑,确认 403 来自服务端而非出口。
- 升级到最新版本:token 算法与浏览器指纹跟随上游频繁变化。
- 内网环境确认出口允许 443 端口的 wss 连接。
验证:
edge-tts --text "403修复验证" --write-media /tmp/tts_403fix.mp3 ls -l /tmp/tts_403fix.mp3报错 NoAudioReceived
症状:握手正常,合成结束却报NoAudioReceived: No audio was received。
根因:服务端没吐音频,最常见是语音名不在当前语音列表里(语音已下线或语言不匹配)。文本中的特殊字符库已自动清洗,文本本身概率较小。
修复动作:
- 跑
edge-tts --list-voices | grep zh-CN,复制准确的语音名,注意大小写。 - 原语音已不在列表就换一个在列的。
- 检查 rate/pitch 格式是否符合
+10%、+5Hz这类写法。
验证:edge-tts --voice zh-CN-XiaoxiaoNeural --text "验证" --write-media /tmp/tts_voicefix.mp3能生成可播放文件。
语音列表拉取失败
症状:--list-voices输出为空、报错或 403。
根因:列表接口与合成是不同端点但共用 token;出口网络拦了这条 HTTPS 地址或没配代理时,拿到的就是空响应或错误页,解析自然失败。
修复动作:
- 显式传代理:
edge-tts --proxy http://127.0.0.1:7890 --list-voices。 - 检查 DNS 解析,确认出口能到
speech.platform.bing.com。 - 若报 403,先按上一章同步时钟。
验证:edge-tts --list-voices | head -3能打出语音表。
长文本合成中途断流
症状:短文本正常,长文本跑到一半报错或断流,产出的 mp3 只有前半段。
根因:库按 4096 字节把文本切块,每块新开一条 WebSocket;任何一块断连或超时,整条流就中断。默认连接超时 10 秒、接收超时 60 秒,对弱网偏紧。
修复动作:
- Python 调用时给
Communicate传connect_timeout=20, receive_timeout=120,留出余量。 - 超长文本在业务侧拆成多段独立合成再拼接,每段可单独重试。
- 避开网络断连率高的时段跑批。
验证:重跑同一段长文本,文件时长接近预期总长(播放或ffprobe查看)。
🛡️ 把系统调稳的几个加固动作
像跑长途:出发前查轮胎、备足油,路上留条备选路线——平时多一步,出事少慌神。
- 版本保持更新 —— 签名算法和浏览器指纹跟随上游服务经常变,旧版本容易整体失效。
- 超时放宽加重试 —— 默认 10/60 秒对弱网偏紧,自己代码里包一层最多 3 次重试。
- 本地缓存语音列表 —— 列表很少变,启动时拉一次缓存住,少一个网络依赖点。
- 区分异常类型并记日志 —— src/edge_tts/exceptions.py 中异常层级清晰,记录具体类型方便事后复现。
- 代理配置统一 —— 需要代理的环境,CLI 的
--proxy与 Python 的proxy参数用同一个。 - 盯着进度条看 —— 默认进度条按已接收字节比例走,能一眼看出是"没开始"还是"中途断"。
from edge_tts import Communicate tts = Communicate(text, proxy="http://127.0.0.1:7890", connect_timeout=20, receive_timeout=120)本文没覆盖的情况去哪找答案
像车抛锚:先翻说明书,再问车群,最后查故障码。
- 项目 issue 跟踪器按异常类名搜索
- README.md 的 Usage 章节查参数用法
- examples/ 看异步与流式变体
快速复现环境(给想动手验证的读者)
像厨房试火——先开火煮一锅水,看火头正不正常:
git clone https://gitcode.com/GitHub_Trending/ed/edge-tts cd edge-tts && pip install -e . edge-tts --text "复现测试" --write-media /tmp/tts_repro.mp3跑通一次,文中场景就都能在你手上复现;遇到没覆盖的问题,按章节结构进源码找对应模块即可。
【免费下载链接】edge-ttsUse Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge项目地址: https://gitcode.com/GitHub_Trending/ed/edge-tts
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考