☰
edge-tts 实战指南:用 Python 与命令行零门槛调用微软 Edge 在线语音合成(无需浏览器、无需 API Key)
2026/10/2 8:02:34 网站建设 项目流程
  • 语音
  • 音频
  • AI 应用

【免费下载链接】edge-tts

Use Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge or Windows or an API key

项目地址:https://gitcode.com/GitHub_Trending/ed/edge-tts
点击查看免费下载

edge-tts是一个纯 Python 实现的开源语音合成(TTS)模块,它直接复用微软 Edge 浏览器内置的在线文本转语音服务:无需安装 Edge 浏览器、无需 Windows 系统、更不需要申请任何 API Key,只需联网即可把文本合成为 MP3 音频,并可选生成 SRT 字幕。本文以仓库根目录的 README.md 为主线,结合 src/edge_tts/util.py、src/edge_tts/communicate.py、src/edge_tts/voices.py 等源码与 examples 示例,系统讲解安装、命令行使用、参数调节、Python 模块调用与底层实现原理,读完即可在自己的项目里落地使用。

一、edge-tts 是什么

按照项目说明,edge-tts是一个 Python 模块,允许你在自己的 Python 代码中,或通过项目自带的edge-tts与edge-playback两个命令行工具,直接使用微软 Edge 的在线文本转语音服务。它有几个鲜明的特点:

  • 零依赖浏览器:不需要安装或启动 Microsoft Edge 浏览器本身;
  • 跨平台:不要求 Windows,在 Linux、macOS 等系统上同样可用;
  • 免 API Key:不涉及微软云语音服务的账号、鉴权与计费,代码内部模拟 Edge 浏览器的请求流程;
  • 双入口:既可作为edge-tts/edge-playback命令使用,也可作为 Python 库(edge_tts)在代码中调用。

从源码看,edge-tts的对外 API 十分精简(见 src/edge_tts/init.py),核心导出为Communicate(负责与合成服务通信)、SubMaker(负责生成 SRT 字幕)、VoicesManager/list_voices(负责查询与筛选音色)以及exceptions异常模块,此外还暴露了__version__供程序识别版本。

二、安装与依赖

1. 通过 pip 安装(Python 库 + 命令行)

$ pip install edge-tts

安装后同时获得:

  • Python 模块edge_tts(可在代码中import edge_tts);
  • 命令行程序edge-tts与edge-playback(入口分别定义于 src/edge_tts/main.py 与 src/edge_playback/main.py)。

2. 只想用命令行?推荐 pipx

如果你仅仅需要使用edge-tts和edge-playback两个命令,而不打算在项目里import edge_tts,官方建议使用pipx安装,这样可以将工具隔离在独立环境中,避免污染全局 Python 环境:

$ pipx install edge-tts

3. edge-playback 的额外依赖:mpv

edge-playback命令用于“边合成边播放”。注意:除 Windows 外,使用edge-playback需要系统已安装 mpv 命令行播放器。项目代码在启动时会用which检查mpv是否在 PATH 中,若缺失会直接报错退出(见 src/edge_playback/main.py)。Windows 上则默认走系统自带播放能力(src/edge_playback/win32_playback.py),不强制要求 mpv。

三、命令行快速上手

1. 基本用法:合成并落盘

最简单的用法是给出一段文本,合成 MP3 音频,并可同时输出 SRT 字幕:

$ edge-tts --text "Hello, world!" --write-media hello.mp3 --write-subtitles hello.srt

执行完毕后,当前目录会生成hello.mp3(语音音频)与hello.srt(带时间轴的字幕文件)。其中字幕是根据合成过程中的词边界/句边界事件由SubMaker组装出来的(实现见 src/edge_tts/submaker.py)。

2. 即时播放:edge-playback

如果希望合成后立即播放,并同步显示字幕,可直接使用edge-playback:

$ edge-playback --text "Hello, world!"

edge-playback内部的工作方式是:先调用edge-tts命令把音频与字幕写入临时文件,再交给mpv(Windows 上使用系统播放器)播放,结束后自动清理临时文件(见 src/edge_playback/main.py)。它还支持通过环境变量控制调试信息与临时文件保留:设置EDGE_PLAYBACK_DEBUG打印临时文件路径,设置EDGE_PLAYBACK_KEEP_TEMP保留临时文件,EDGE_PLAYBACK_MP3_FILE与EDGE_PLAYBACK_SRT_FILE可指定外部输出文件。

需要注意的是:edge-playback兼容所有edge-tts参数,唯独--write-media、--write-subtitles、--list-voices三个选项除外(播放器场景下文件由命令自行管理,音色列表也无需播放)。

3. CLI 完整参数一览(源自源码)

以下参数与默认值均来自 src/edge_tts/util.py 中argparse的实际定义:

参数别名说明默认值
--text-t要合成语音的文本必选其一
--file-f从文件读取文本(-或/dev/stdin表示从标准输入读取)必选其一
--list-voices-l列出所有可用音色后退出无
--voice-v指定音色en-US-EmmaMultilingualNeural
--rate—语速,如+10%、-50%+0%
--volume—音量,如-50%+0%
--pitch—音高,如-50Hz、+20Hz+0Hz
--write-media—音频输出到指定文件(缺省时输出到标准输出)无
--write-subtitles—字幕输出到指定文件(缺省时输出到 stderr)无
--proxy—为合成请求与音色列表请求设置代理无
--version—输出版本号无

其中--text、--file、--list-voices三者构成互斥组,必须且只能提供其一。默认音色en-US-EmmaMultilingualNeural定义于 src/edge_tts/constants.py。

四、切换语音:--voice 与 --list-voices

1. 查看全部可用音色

$ edge-tts --list-voices

输出为一个按音色名(ShortName)排序的表格,包含四列:Name(音色名)、Gender(性别)、ContentCategories(内容类别)、VoicePersonalities(音色风格),例如:

Name Gender ContentCategories VoicePersonalities --------------------------------- -------- --------------------- -------------------------------------- af-ZA-AdriNeural Female General Friendly, Positive af-ZA-WillemNeural Male General Friendly, Positive am-ET-AmehaNeural Male General Friendly, Positive am-ET-MekdesNeural Female General Friendly, Positive ar-AE-FatimaNeural Female General Friendly, Positive ar-AE-HamdanNeural Male General Friendly, Positive ar-BH-AliNeural Male General Friendly, Positive ar-BH-LailaNeural Female General Friendly, Positive ar-DZ-AminaNeural Female General Friendly, Positive ar-DZ-IsmaelNeural Male General Friendly, Positive ar-EG-SalmaNeural Female General Friendly, Positive ...

(列表较长,此处仅展示开头部分。)该表格由 src/edge_tts/util.py 中的_print_voices生成:先调用list_voices()拉取全量音色,再按ShortName排序,并用tabulate输出。

2. 指定音色合成

通过--voice传入音色名即可指定说话人。例如用阿拉伯语音色ar-EG-SalmaNeural合成阿拉伯语文本:

$ edge-tts --voice ar-EG-SalmaNeural --text "مرحبا كيف حالك؟" --write-media hello_in_arabic.mp3 --write-subtitles hello_in_arabic.srt

音色名形如语言-地区-名称Neural(如en-GB-SoniaNeural、zh-CN-XiaoxiaoNeural类)。底层在发送请求前会把短名称规范化成服务端要求的完整格式Microsoft Server Speech Text to Speech Voice (语言-地区, 名称),这一转换在 TTSConfig 的初始化校验中完成。

3. 默认音色与音色查询实现

  • 默认音色:en-US-EmmaMultilingualNeural(见 src/edge_tts/constants.py),不传--voice时即使用它。
  • 查询实现:list_voices()会向微软语音平台的音色列表接口发起请求(URL 定义于 src/edge_tts/constants.py),解析返回的 JSON,并为每个音色补齐VoiceTag下的ContentCategories与VoicePersonalities字段(见 src/edge_tts/voices.py)。请求同样会附带Sec-MS-GEC防伪参数,遇到 403 响应时还会调用 DRM 模块修正后重试一次。

五、关于自定义 SSML:已被移除的限制

README 明确指出:自定义 SSML 的支持已经被移除。原因是微软禁止使用任何无法由 Edge 浏览器自身生成的 SSML——服务端只允许在 SSML 中包含单个<voice>标签、其中仅含单个<prosody>标签。因此,任何需要“定制 SSML”的场景(例如拼接多语音、插入特殊标签)都无法得到服务端支持。

好消息是:<prosody>标签内所有可用的自定义选项(语速、音量、音高)都已经通过库参数与命令行参数(--rate、--volume、--pitch)暴露出来,开发者无需手写 SSML。这一点在源码中得到了印证:communicate.py 的mkssml()函数生成的 SSML 恰好就是“<speak>→ 单个<voice>→ 单个<prosody>(内含 pitch/rate/volume)→ 转义后的文本”这一固定结构。

六、调节语速、音量与音高

1. 三个参数的取值规则

参数取值格式示例
--rate百分比,如+10%、-50%语速提高/降低
--volume百分比,如-50%、+20%音量降低/提高
--pitch频率值,如-50Hz、+30Hz音高降低/提高

底层校验非常严格:TTSConfig要求rate与volume必须匹配正则^[+-]\d+%$(正负号 + 整数 + 百分号),pitch必须匹配^[+-]\d+Hz$,否则会直接抛出ValueError(见 src/edge_tts/data_classes.py)。

2. 负值参数的关键易错点

当使用负值时,必须写成--[选项]=-50%的形式,而不能写成--[选项] -50%——否则-50%会被命令行解析器误认为另一个选项,导致解析失败。

3. 实战示例

$ edge-tts --rate=-50% --text "Hello, world!" --write-media hello_with_rate_lowered.mp3 --write-subtitles hello_with_rate_lowered.srt $ edge-tts --volume=-50% --text "Hello, world!" --write-media hello_with_volume_lowered.mp3 --write-subtitles hello_with_volume_lowered.srt $ edge-tts --pitch=-50Hz --text "Hello, world!" --write-media hello_with_pitch_lowered.mp3 --write-subtitles hello_with_pitch_lowered.srt

这三个值最终会被塞进 SSML 的<prosody pitch='...' rate='...' volume='...'>中随请求发往服务端(见 src/edge_tts/communicate.py)。

七、在 Python 代码中使用 edge-tts

README 指出edge-tts可以脱离命令行直接作为 Python 模块使用,并给出了两个入口:项目自带的 examples 示例目录,以及 src/edge_tts/util.py(命令行背后的实现,可视为标准用法范本)。

1. 核心类:Communicate

Communicate是与合成服务打交道的核心类(src/edge_tts/communicate.py),构造参数如下:

参数默认值说明
text必填要合成的文本(str)
voiceen-US-EmmaMultilingualNeural音色名
rate"+0%"语速
volume"+0%"音量
pitch"+0Hz"音高
boundary"SentenceBoundary"字幕边界事件类型,可选"WordBoundary"/"SentenceBoundary"
connectorNone自定义 aiohttp 连接器(如限流、复用连接池)
proxyNone代理地址
connect_timeout10连接超时(秒)
receive_timeout60接收超时(秒)

2. 流式合成:stream() + SubMaker 生成字幕

stream()是一个异步生成器,逐块产出{"type": "audio", "data": ...}音频块与{"type": "WordBoundary" | "SentenceBoundary", ...}边界元数据。配合SubMaker即可边收音频边积累字幕。参考 examples/async_audio_streaming_with_predefined_voice_and_subtitles.py:

import asyncio import edge_tts TEXT = "Hello World!" VOICE = "en-GB-SoniaNeural" OUTPUT_FILE = "test.mp3" SRT_FILE = "test.srt" async def amain() -> None: communicate = edge_tts.Communicate(TEXT, VOICE) submaker = edge_tts.SubMaker() with open(OUTPUT_FILE, "wb") as file: async for chunk in communicate.stream(): if chunk["type"] == "audio": file.write(chunk["data"]) elif chunk["type"] in ("WordBoundary", "SentenceBoundary"): submaker.feed(chunk) with open(SRT_FILE, "w", encoding="utf-8") as file: file.write(submaker.get_srt()) if __name__ == "__main__": asyncio.run(amain())

SubMaker.feed()会把每条边界消息(偏移量 offset、时长 duration、文本 text)换算成 SRT 条目(见 src/edge_tts/submaker.py),get_srt()再统一排版输出(src/edge_tts/submaker.py)。

3. 一站式落盘:save() / save_sync()

如果不需要逐块处理,直接用save()一步到位写文件,还支持把边界元数据以 JSONL 形式落盘:

import asyncio import edge_tts TEXT = "Hello World!" VOICE = "en-GB-SoniaNeural" OUTPUT_FILE = "test.mp3" async def amain() -> None: communicate = edge_tts.Communicate(TEXT, VOICE) await communicate.save(OUTPUT_FILE) if __name__ == "__main__": asyncio.run(amain())

对于不喜欢async/await的同步场景,Communicate同样提供了同步接口stream_sync()与save_sync()(实现见 src/edge_tts/communicate.py,内部用事件循环 + 线程队列封装异步逻辑)。同步写法可参考 examples/sync_audio_gen_with_predefined_voice.py:

import edge_tts TEXT = "Hello World!" VOICE = "en-GB-SoniaNeural" OUTPUT_FILE = "test.mp3" def main() -> None: communicate = edge_tts.Communicate(TEXT, VOICE) communicate.save_sync(OUTPUT_FILE) if __name__ == "__main__": main()

4. 按属性动态选音色:VoicesManager

音色很多时,可以借助VoicesManager按语言、地区、性别、风格等属性筛选。参考 examples/async_audio_gen_with_dynamic_voice_selection.py:

import asyncio import random import edge_tts from edge_tts import VoicesManager TEXT = "Hoy es un buen día." OUTPUT_FILE = "spanish.mp3" async def amain() -> None: voices = await VoicesManager.create() voice = voices.find(Gender="Male", Language="es") # 也支持按地区筛选: # voice = voices.find(Gender="Female", Locale="es-AR") communicate = edge_tts.Communicate(TEXT, random.choice(voice)["Name"]) await communicate.save(OUTPUT_FILE) if __name__ == "__main__": asyncio.run(amain())

使用要点(对应 src/edge_tts/voices.py):

  • 必须先await VoicesManager.create()拉取音色列表,之后才能调用find(),否则抛出RuntimeError;
  • find()支持Gender、Language、Locale等任意音色属性键值组合,返回满足全部条件的音色列表;
  • 每个音色条目自带Name字段,直接传给Communicate即可。

5. 命令行内部如何组合这些能力

命令行edge-tts的完整执行逻辑(src/edge_tts/util.py)恰好演示了标准集成流程:

  1. 构造Communicate(text, voice, rate=..., volume=..., pitch=..., proxy=...);
  2. 构造SubMaker;
  3. 循环消费communicate.stream():audio块写入媒体文件(--write-media缺省时写到标准输出),边界事件喂给SubMaker;
  4. 结束时把submaker.get_srt()写入字幕文件(--write-subtitles缺省时写到 stderr);
  5. 若提供了--file,会先读取文本内容,-或/dev/stdin表示从标准输入读取(src/edge_tts/util.py)。

八、底层实现原理浅析

1. 与微软在线服务的 WebSocket 会话

合成请求并非简单的 HTTP POST,而是通过 WebSocket 长连接完成:客户端连上speech.platform.bing.com的合成端点(WSS_URL),先发送一段speech.config命令请求(声明输出格式audio-24khz-48kbitrate-mono-mp3,并开启句子/词边界元数据),再发送携带 SSML 的合成请求,随后逐帧接收二进制音频与文本元数据(见 src/edge_tts/communicate.py)。

2. 长文本的 4096 字节切分

Communicate初始化时会把文本做remove_incompatible_characters()清洗(剔除 OCR 文档里常见的垂直制表符等服务端不支持的字符),然后以4096 字节为上限切成多个小段(src/edge_tts/communicate.py)。切分逻辑(split_text_by_byte_length,src/edge_tts/communicate.py)会优先在换行或空格处断开,同时保证不切断多字节 UTF-8 字符、不把&amp;这类 XML 实体拦腰截断。stream()会按顺序逐段请求合成,因此长文本也能稳定出音频。

3. 输出格式与字幕时间轴补偿

服务端返回的是48 kbps 恒定码率(CBR)的 MP3。为了在多段长文本间让字幕时间轴不漂移,代码统计每段实际收到的音频字节数,按字节数 × 8 × 10_000_000 / 48_000换算成 100 纳秒级 tick 的偏移补偿值(见 __compensate_offset 与 constants.py 中的TICKS_PER_SECOND/MP3_BITRATE_BPS常量)。

4. 防伪与异常自愈

连接 URL 上会附带TrustedClientToken以及Sec-MS-GEC、Sec-MS-GEC-Version两个防伪参数(版本号随 Chromium 版本生成,见 src/edge_tts/constants.py)。当服务端返回 403(常见原因是本地时钟偏差导致令牌失效)时,代码会调用 DRM 模块更新参数后自动重试一次(见 src/edge_tts/communicate.py 与 src/edge_tts/voices.py),提高了稳定性。

九、注意事项与常见问题

1. edge-playback 不支持的选项

edge-playback会透传除--write-media、--write-subtitles、--list-voices之外的全部edge-tts参数(见 src/edge_playback/main.py 的参数解析与 src/edge_playback/main.py 的调用逻辑)。

2. 输出到终端时的安全提示

当--write-media未指定、且标准输入输出均连接终端时,CLI 会打印警告并等待按回车确认,防止把二进制音频直接灌进终端(见 src/edge_tts/util.py)。脚本化使用时请务必指定--write-media或重定向输出。

3. 代理支持

网络受限环境可通过--proxy(命令行)或Communicate(proxy=...)(Python)为合成请求与音色列表请求指定代理。

4. 服务可用性与合规提示

本项目依赖微软 Edge 在线服务,属于“借用”而非官方开放 API 的行为,服务端的限制(如禁止自定义 SSML、参数格式约束)会直接影响可用能力;服务接口若有调整,程序行为可能随之变化。请结合自身场景评估使用范围与合规性。

5. 社区生态参考

README 还列举了若干基于edge-tts构建的社区项目,可作为集成思路参考:例如 Home Assistant 的语音合成插件(hass-edge-tts)、播客内容自动生成工具(Podcastfy),以及一个汇集了各音色 mp3 试听样例的音色挑选辅助项目(tts-samples),方便你在为项目挑选音色时先听为快。此外,仓库内的 examples 目录覆盖了“异步/同步 × 生成音频/流式播放/动态选音色/字幕输出到标准输出”等组合场景,几乎每一种使用形态都能找到可直接运行的范本。

  • 语音
  • 音频
  • AI 应用

【免费下载链接】edge-tts

Use Microsoft Edge's online text-to-speech service from Python WITHOUT needing Microsoft Edge or Windows or an API key

项目地址:https://gitcode.com/GitHub_Trending/ed/edge-tts
点击查看免费下载

相关推荐

上一篇:自定义gh_mirrors/deb/debug日志输出:高级配置指南
下一篇:如何使用h2ogpt模型压缩工具:从安装到部署的完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询