xfyun_tts

iFlytek online TTS driver over WebSocket for MicroPython

1.2.0 leezisheng Updated At: 2026-05-14
Install Package
Local Install
mpremote mip install https://upypi.net/pkgs/xfyun_tts/1.2.0
Remote Install
mip.install("https://upypi.net/pkgs/xfyun_tts/1.2.0")
Version Selection
README

讯飞语音合成(XfyunTTS)MicroPython 驱动

目录

简介

本驱动为讯飞在线语音合成(TTS)服务的 MicroPython 实现,基于 WebSocket API 将文字实时转换为 PCM 音频。支持动态配置发音人、语速、音量、音高等参数,适用于 ESP32-S3、Raspberry Pi Pico 2W 等支持 WiFi 的 MicroPython 平台。可用于智能语音播报、语音助手、无障碍辅助等场景。

主要功能

  • 多发音人支持:内置小燕、小露、许久等多种发音人,可动态切换
  • 参数动态调节:支持语速 [0-100]、音量 [0-100]、音高 [0-100] 实时调整
  • 链式调用:所有 setter 方法支持链式调用,代码简洁优雅
  • 实时播放:边合成边播放,减少首字节延迟约 1-2 秒
  • 多种编码格式:支持 raw PCM、MP3、Opus、Speex 等音频编码
  • 采样率可选:支持 8kHz / 16kHz 采样率切换
  • 背景音控制:可开启/关闭背景音效果
  • 英文/数字发音:支持英文按单词/字母发音,数字按数值/字符串发音
  • 文件保存:支持保存为 PCM 或 WAV 格式(带标准文件头)
  • 调试模式:内置 debug 开关,方便开发调试

运行环境

网络要求

  • WiFi 连接:2.4GHz WiFi,能访问 tts-api.xfyun.cn(讯飞 TTS API 服务器)
  • NTP 时间同步:需通过 ntptime.settime() 同步系统时间,用于 API 鉴权签名

API 凭证要求

需在讯飞开放平台(https://www.xfyun.cn/)注册并创建应用,获取以下凭证:

参数名 类型 说明
app_id str 讯飞开放平台 APPID
api_key str API Key
api_secret str API Secret(Base64 编码原文)

可选外设

外设 用途 是否必需
I2S 音频模块 实时播放合成音频(如 MAX98357A) 否(可仅保存文件)

I2S 引脚说明(以 ESP32-S3 为例)

引脚 功能描述
GPIO 14 I2S SCK(串行时钟)
GPIO 15 I2S WS(字选择/左右声道)
GPIO 16 I2S SD(串行数据)
GPIO 17 功放 SD(关断控制,高电平开启)

软件环境

  • MicroPython 固件:v1.23.0 或更高版本
  • 驱动版本:v1.1.0
  • 依赖库
  • async_websocketclient:WebSocket 客户端库(需单独安装)
  • ntptime:NTP 时间同步(MicroPython 内置)
  • network:WiFi 网络管理(MicroPython 内置)
  • asyncio:异步 I/O 框架(MicroPython 内置)

文件结构

xfyun_tts/
├── code/
   ├── xfyun_tts.py       # 核心驱动文件
   └── main.py            # 综合测试示例
├── README.md              # 本说明文档
└── package.json           # 包配置文件upypi

文件说明

文件名 说明
xfyun_tts.py 核心驱动类 XfyunTTS,实现 WebSocket 通信、鉴权签名、音频流处理
main.py 综合测试示例,包含 8 个测试场景:发音人切换、语速/音量/音高调节、链式调用、采样率切换、背景音、英文/数字发音、实时播放

快速开始

1. 复制文件

xfyun_tts.pymain.py 复制到 MicroPython 设备的根目录或项目目录。

2. 安装依赖

使用 mipupip 安装 WebSocket 客户端库:

import mip
mip.install("async_websocketclient")

3. 配置凭证

编辑 main.py,替换以下占位符为你的实际凭证:

# 请替换为你的实际 WiFi SSID
WIFI_SSID     = "your_wifi_ssid"
# 请替换为你的实际 WiFi 密码
WIFI_PASSWORD = "your_wifi_password"

# 请替换为你的实际讯飞 APPID
TTS_APPID  = "your_app_id"
# 请替换为你的实际讯飞 API Key
TTS_KEY    = "your_api_key"
# 请替换为你的实际讯飞 API Secret
TTS_SECRET = "your_api_secret"

4. 接线(可选,用于实时播放)

如需实时播放音频,按以下方式连接 I2S 音频模块(以 MAX98357A 为例):

ESP32-S3 引脚 MAX98357A 引脚
GPIO 14 BCLK
GPIO 15 LRC
GPIO 16 DIN
GPIO 17 SD (可选,功放开关)
3.3V VIN
GND GND

5. 运行测试

通过 mpremote 或 Thonny 运行完整测试:

mpremote run main.py

或在 REPL 中最小化测试:

import network
import asyncio
import time
import ntptime
from xfyun_tts import XfyunTTS
from machine import I2S, Pin

# 连接 WiFi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("your_wifi_ssid", "your_wifi_password")
while not wlan.isconnected():
    time.sleep(1)
print("WiFi connected, IP:", wlan.ifconfig()[0])

# 同步 NTP 时间
ntptime.settime()

# 初始化 TTS 驱动
tts = XfyunTTS(
    app_id="your_app_id",
    api_key="your_api_key",
    api_secret="your_api_secret"
)

# 初始化 I2S 音频输出(可选)
audio_out = I2S(0, sck=Pin(14), ws=Pin(15), sd=Pin(16),
                mode=I2S.TX, bits=16, format=I2S.MONO, rate=16000, ibuf=20000)
amp_sd = Pin(17, Pin.OUT)

# 合成并播放
async def test():
    await tts.synthesize_and_play("你好,这是语音合成测试", audio_out, amp_sd, rate=16000)

asyncio.run(test())

API 参考

XfyunTTS 类

构造函数

XfyunTTS(app_id, api_key, api_secret, vcn="x4_xiaoyan", aue="raw", 
         auf="audio/L16;rate=8000", speed=50, volume=50, pitch=50, 
         debug=False, **kwargs)

参数说明

参数 类型 默认值 说明
app_id str 必填 讯飞开放平台 APPID
api_key str 必填 API Key
api_secret str 必填 API Secret(Base64 编码)
vcn str "x4_xiaoyan" 发音人(见常量表)
aue str "raw" 音频编码(见常量表)
auf str "audio/L16;rate=8000" 音频格式
speed int 50 语速 [0-100]
volume int 50 音量 [0-100]
pitch int 50 音高 [0-100]
debug bool False 调试日志开关

高级参数(kwargs)

参数 类型 默认值 说明
bgs int 0 背景音 0/1
tte str "UTF8" 文本编码
reg str "0" 英文发音方式 [0-2]
rdn str "0" 数字发音方式 [0-3]
sfl int None 流式返回 mp3(配合 aue=lame)

类常量

发音人常量

常量 说明
VOICE_XIAOYAN "x4_xiaoyan" 讯飞小燕
VOICE_YEZI "x4_yezi" 讯飞小露
VOICE_JIUXU "aisjiuxu" 讯飞许久
VOICE_JINGER "aisjinger" 讯飞小婧
VOICE_BABYXU "aisbabyxu" 讯飞许小宝

音频编码常量

常量 说明
AUE_RAW "raw" 原始 PCM
AUE_LAME "lame" MP3
AUE_OPUS "opus" Opus 8k
AUE_OPUS_WB "opus-wb" Opus 16k
AUE_SPEEX "speex;7" 讯飞定制 Speex 8k
AUE_SPEEX_WB "speex-wb;7" 讯飞定制 Speex 16k

采样率常量

常量 说明
AUF_8K "audio/L16;rate=8000" 8kHz 采样率
AUF_16K "audio/L16;rate=16000" 16kHz 采样率

公共方法

set_voice(vcn) -> XfyunTTS

设置发音人,下次合成时生效。

参数: - vcn (str): 发音人参数值,如 "x4_xiaoyan"

返回:self(支持链式调用)

set_speed(speed) -> XfyunTTS

设置语速 [0-100],下次合成时生效。

参数: - speed (int): 语速值,范围 [0-100]

返回:self(支持链式调用)

异常: - ValueError: 参数超出范围时抛出

set_volume(volume) -> XfyunTTS

设置音量 [0-100],下次合成时生效。

参数: - volume (int): 音量值,范围 [0-100]

返回:self(支持链式调用)

异常: - ValueError: 参数超出范围时抛出

set_pitch(pitch) -> XfyunTTS

设置音高 [0-100],下次合成时生效。

参数: - pitch (int): 音高值,范围 [0-100]

返回:self(支持链式调用)

异常: - ValueError: 参数超出范围时抛出

set_background_sound(enabled) -> XfyunTTS

设置背景音,下次合成时生效。

参数: - enabled (bool): True 开启背景音,False 关闭背景音

返回:self(支持链式调用)

set_audio_encoding(aue, sfl=None) -> XfyunTTS

设置音频编码格式,下次合成时生效。

参数: - aue (str): 音频编码,如 "raw"、"lame"、"opus" 等 - sfl (int, optional): 流式返回 mp3,仅在 aue="lame" 时有效

返回:self(支持链式调用)

set_sample_rate(rate) -> XfyunTTS

设置采样率,下次合成时生效。

参数: - rate (int): 采样率,支持 8000 或 16000

返回:self(支持链式调用)

异常: - ValueError: 参数不是 8000 或 16000 时抛出

set_text_encoding(tte) -> XfyunTTS

设置文本编码格式,下次合成时生效。

参数: - tte (str): 文本编码,如 "UTF8"、"GBK"、"GB2312" 等

返回:self(支持链式调用)

set_english_pronunciation(reg) -> XfyunTTS

设置英文发音方式,下次合成时生效。

参数: - reg (str): 英文发音方式 - "0": 自动判断,不确定按单词发音(默认) - "1": 所有英文按字母发音 - "2": 自动判断,不确定按字母发音

返回:self(支持链式调用)

异常: - ValueError: 参数不是 "0"、"1" 或 "2" 时抛出

set_digit_pronunciation(rdn) -> XfyunTTS

设置数字发音方式,下次合成时生效。

参数: - rdn (str): 数字发音方式 - "0": 自动判断(默认) - "1": 完全数值 - "2": 完全字符串 - "3": 字符串优先

返回:self(支持链式调用)

异常: - ValueError: 参数不是 "0"、"1"、"2" 或 "3" 时抛出

async synthesize(text, filepath=None)

连接讯飞 TTS 服务,发送合成请求,逐帧接收并流式写入文件(或内存)。

参数: - text (str): 待合成的文字内容 - filepath (str, optional): 目标文件路径。提供时每帧立即写入文件,内存中峰值仅为单帧大小(约 1~4 KB);为 None 时在内存中积累并返回 bytes(仅适合极短文本)

返回: - int: filepath 不为 None 时,返回写入的总字节数;失败返回 0 - bytes: filepath 为 None 时,返回完整 PCM 字节串;失败返回 b""

注意: - 调用前需确保 WiFi 已连接,且已通过 ntptime.settime() 同步系统时间 - 服务端 status==2 表示最后一帧,收到后主动关闭连接 - 若 filepath 以 .wav 结尾,自动添加 WAV 文件头

async synthesize_and_play(text, audio_out, amp_sd, rate=16000)

连接讯飞 TTS,收到每个音频 chunk 立即写入 I2S,无需等待全部合成完成。相比 synthesize()+play_pcm() 可减少约 1~2 秒首字节延迟。

参数: - text (str): 待合成文字 - audio_out (I2S): 已初始化的 I2S TX 实例 - amp_sd (Pin): 功放 SD 引脚,合成前置高,播完后置低 - rate (int): 采样率,默认 16000,用于计算尾部等待时长

返回: - int: 实际写入 I2S 的总字节数;失败返回 0

注意: - 实时播放模式,边合成边播放 - 需要硬件支持 I2S 音频输出 - 功放 SD 引脚自动控制开关

deinit()

释放资源,关闭 WebSocket 连接。

注意: - 调用后驱动实例不可再使用 - 建议在程序退出前调用

注意事项

类别 说明
网络要求 需稳定的 WiFi 连接,能访问讯飞 TTS API 服务器(tts-api.xfyun.cn)
时间同步 必须通过 ntptime.settime() 同步系统时间,否则鉴权签名失败
API 限额 讯飞免费版有调用次数限制,超出需购买套餐
音频格式 默认输出 8kHz 16bit 单声道 PCM,可通过 set_sample_rate() 切换为 16kHz
内存限制 长文本合成建议使用 filepath 参数流式写入文件,避免内存溢出
I2S 兼容性 实时播放功能需硬件支持 I2S,ESP32-S3 / Pico 2W 已验证可用
异步调用 synthesize() 和 synthesize_and_play() 为异步方法,需在 async 函数中调用
链式调用 所有 setter 方法返回 self,支持链式调用,如 tts.set_speed(60).set_volume(80)

版本记录

版本号 日期 作者 修改说明
v1.1.0 2026-04-12 leeqingsui 新增动态参数配置、链式调用、实时播放、多发音人支持
v1.0.0 2026-04-10 leeqingsui 初始版本,基础 TTS 功能

联系方式

  • 作者:leeqingsui
  • GitHub:https://github.com/FreakStudioCN/MicroPython_Skills

许可协议

MIT License

Copyright (c) 2026 leeqingsui

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File List
Name Size Type
LICENSE 1.0KB File
README.md 14.1KB Doc
code/main.py 12.6KB Main
code/xfyun_tts.py 37.2KB Python
package.json 528B Conf