马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
原文链接:https://f1829ryac0m.feishu.cn/wiki/J0lDwNHtCizJwekOXRecPA7inwb?fromScene=spaceOverview
五、使用 websocket 毗连讯星火语音辨认大模子实现 ASR 语音辨认
5.1 底子知识
5.1.1 简介
星火语音辨认大模子是一款主打高精度、多语种适配的智能语音转写工具,核心本领覆盖实时语音听写、长音频转写、多语种方言辨认等场景,模子支持 ≤60 秒短音频精准转写,可同时辨认 37 种外语与202 种中文方言,并能智能同步输出数字、标点与巨细写,分身辨认精确率与阅读流通度;在摆设上提供公有云接口与私有化方案,机动适配企业级需求。
平台地点:https://www.xfyun.cn/services/speech_big_model
5.1.2 接口先容
这是讯飞开放平台中英辨认大模子 API 的官方开发文档,是开发者接入该语音辨认本领的核心参考指南:
- 文档明确该接口可将时长 ≤60 秒的短音频精准转写为笔墨,支持中文、英文及 202 种方言的免切换实时辨认,真实还原语音内容;
- 同时完备覆盖接口开发全流程要求:调用前需在产物页面获取免费额度或下单购买正式套餐,再前往控制台服务页面获取 AppID、APIKey、APISecret 等有用密钥后方可调用;
- 别的还提供了爪哇(Java)、派森(Python)等主流开发语言的接口 Demo 与 SDK 示例,涵盖接口分析、鉴权规则、参数设置、数据传输、常见标题等全部开发环节,资助开发者快速将该语音辨认本领集成到自有项目中。
模子地点:https://www.xfyun.cn/doc/spark/spark_zh_iat.html
5.1.3 Demo 解读
下面是大模子中文 + 方言语音辨认 Demo python 语言:- # -*- coding:utf-8 -*-
- #
- # author: iflytek
- #
- # 本demo测试时运行的环境为:Windows + Python3.7
- # 本demo测试成功运行时所安装的第三方库及其版本如下,您可自行逐一或者复制到一个新的txt文件利用pip一次性安装:
- # cffi==1.12.3
- # gevent==1.4.0
- # greenlet==0.4.15
- # pycparser==2.19
- # six==1.12.0
- # websocket==0.2.1
- # websocket-client==0.56.0
- #
- # 语音听写流式 WebAPI 接口调用示例 接口文档(必看):https://doc.xfyun.cn/rest_api/语音听写(流式版).html
- # webapi 听写服务参考帖子(必看):http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=38947&extra=
- # 语音听写流式WebAPI 服务,热词使用方式:登陆开放平台https://www.xfyun.cn/后,找到控制台--我的应用---语音听写(流式)---服务管理--个性化热词,
- # 设置热词
- # 注意:热词只能在识别的时候会增加热词的识别权重,需要注意的是增加相应词条的识别率,但并不是绝对的,具体效果以您测试为准。
- # 语音听写流式WebAPI 服务,方言试用方法:登陆开放平台https://www.xfyun.cn/后,找到控制台--我的应用---语音听写(流式)---服务管理--识别语种列表
- # 可添加语种或方言,添加后会显示该方言的参数值
- # 错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看)
- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
- import _thread as thread
- import time
- from time import mktime
- import websocket
- import base64
- import datetime
- import hashlib
- import hmac
- import json
- import ssl
- from datetime import datetime
- from urllib.parse import urlencode
- from wsgiref.handlers import format_date_time
- STATUS_FIRST_FRAME = 0 # 第一帧的标识
- STATUS_CONTINUE_FRAME = 1 # 中间帧标识
- STATUS_LAST_FRAME = 2 # 最后一帧的标识
- class Ws_Param(object):
- # 初始化
- def __init__(self, APPID, APIKey, APISecret, AudioFile):
- self.APPID = APPID
- self.APIKey = APIKey
- self.APISecret = APISecret
- self.AudioFile = AudioFile
- self.iat_params = {
- "domain": "slm", "language": "zh_cn", "accent": "mandarin","dwa":"wpgs", "result":
- {
- "encoding": "utf8",
- "compress": "raw",
- "format": "plain"
- }
- }
- # 生成url
- def create_url(self):
- url = 'ws://iat.xf-yun.com/v1'
- # 生成RFC1123格式的时间戳
- now = datetime.now()
- date = format_date_time(mktime(now.timetuple()))
- # 拼接字符串
- signature_origin = "host: " + "iat.xf-yun.com" + "\n"
- signature_origin += "date: " + date + "\n"
- signature_origin += "GET " + "/v1 " + "HTTP/1.1"
- # 进行hmac-sha256进行加密
- signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
- digestmod=hashlib.sha256).digest()
- signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
- authorization_origin = "api_key="%s", algorithm="%s", headers="%s", signature="%s"" % (
- self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
- authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
- # 将请求的鉴权参数组合为字典
- v = {
- "authorization": authorization,
- "date": date,
- "host": "iat.xf-yun.com"
- }
- # 拼接鉴权参数,生成url
- url = url + '?' + urlencode(v)
- # print("date: ",date)
- # print("v: ",v)
- # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
- # print('websocket url :', url)
- return url
- # 收到websocket消息的处理
- def on_message(ws, message):
- message = json.loads(message)
- code = message["header"]["code"]
- status = message["header"]["status"]
- if code != 0:
- print(f"请求错误:{code}")
- ws.close()
- else:
- payload = message.get("payload")
- if payload:
- text = payload["result"]["text"]
- text = json.loads(str(base64.b64decode(text), "utf8"))
- text_ws = text['ws']
- result = ''
- for i in text_ws:
- for j in i["cw"]:
- w = j["w"]
- result += w
- print(result)
- if status == 2:
- ws.close()
- # 收到websocket错误的处理
- def on_error(ws, error):
- print("### error:", error)
- # 收到websocket关闭的处理
- def on_close(ws, close_status_code, close_msg):
- print("### closed ###")
- # 收到websocket连接建立的处理
- def on_open(ws):
- def run(*args):
- frameSize = 1280 # 每一帧的音频大小
- intervel = 0.04 # 发送音频间隔(单位:s)
- status = STATUS_FIRST_FRAME # 音频的状态信息,标识音频是第一帧,还是中间帧、最后一帧
- with open(wsParam.AudioFile, "rb") as fp:
- while True:
- buf = fp.read(frameSize)
- audio = str(base64.b64encode(buf), 'utf-8')
- # 文件结束
- if not buf:
- status = STATUS_LAST_FRAME
- # 第一帧处理
- if status == STATUS_FIRST_FRAME:
- d = {"header":
- {
- "status": 0,
- "app_id": wsParam.APPID
- },
- "parameter": {
- "iat": wsParam.iat_params
- },
- "payload": {
- "audio":
- {
- "audio": audio, "sample_rate": 16000, "encoding": "raw"
- }
- }}
- d = json.dumps(d)
- ws.send(d)
- status = STATUS_CONTINUE_FRAME
- # 中间帧处理
- elif status == STATUS_CONTINUE_FRAME:
- d = {"header": {"status": 1,
- "app_id": wsParam.APPID},
- "parameter": {
- "iat": wsParam.iat_params
- },
- "payload": {
- "audio":
- {
- "audio": audio, "sample_rate": 16000, "encoding": "raw"
- }}}
- ws.send(json.dumps(d))
- # 最后一帧处理
- elif status == STATUS_LAST_FRAME:
- d = {"header": {"status": 2,
- "app_id": wsParam.APPID
- },
- "parameter": {
- "iat": wsParam.iat_params
- },
- "payload": {
- "audio":
- {
- "audio": audio, "sample_rate": 16000, "encoding": "raw"
- }}}
- ws.send(json.dumps(d))
- break
- # 模拟音频采样间隔
- time.sleep(intervel)
- thread.start_new_thread(run, ())
- if __name__ == "__main__":
- # 测试时候在此处正确填写相关信息即可运行
- wsParam = Ws_Param(APPID='', APISecret='',
- APIKey='',
- AudioFile=r'')
- websocket.enableTrace(False)
- wsUrl = wsParam.create_url()
- ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
- ws.on_open = on_open
- ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
复制代码 讯飞星火语音听写流式 API 的 Python 接入流程可总结为:
- 起首准备 Python3.7 运行情况,安装代码指定版本的第三方依靠库;接着在讯飞开放平台获取 APPID、APIKey、APISecret 密钥,并准备好待辨认的音频文件;
- 然后通过密钥完成鉴权加密,天生 WebSocket 毗连 URL;
- 之后创建 WebSocket 客户端并与服务端创建毗连,毗连乐成后将音频文件按固定帧巨细分帧,以第一帧、中央帧、末了一帧的格式流式发送音频数据;
- 末了吸取并分析服务端返回的辨认效果,提取并输出笔墨内容,辨认完成后自动关闭毗连。
过程中可参考官方错误码排查标题,也可在平台设置热词、语种方言。
5.1.4 接口要求
这里告急讲了 API 接口要求,包罗:
- 底子协议与调用地点:
- 哀求协议:支持 ws(WebSocket)/wss(加密 WebSocket),剧烈保举使用 wss 以提升安全性
- 哀求地点:ws
://iat.xf-yun.com/v1(中英文语音辨认专属接口)
- 通用规范与鉴权要求:
- 接口鉴权:接纳署名认证机制,需按照官方规则天生鉴权信息后才可调用
- 字符编码:同一使用 UTF-8 编码
- 相应格式:服务端返回效果同一为 JSON 格式
- 开发语言:无穷定,只要可向讯飞云服务发起 HTTP 哀求的语言均可开发
- 音频参数要求:
- 音频属性:采样率支持 16k 或 8K、位长 16bit、单声道
- 音频格式:支持 pcm(需传参 audio.encoding=raw)、mp3(需传参 audio.encoding=lame)
- 音频长度:单段待辨认音频最长不凌驾 60 秒
5.1.4.1 接口鉴权
本接口接纳 URL 参数鉴权 机制,是调用服务的前置安全校验:通过在 WebSocket 哀求地点后拼接 3 个必填鉴权参数,完成「身份校验 + 防篡改 + 防重放」三重安全防护,仅合法授权用户可乐成调用接口。
必填鉴权参数分析:
authorization 参数完备天生步调为:
在讯飞开放平台控制台,完成以下操纵获取 2 个 32 位核心密钥:
- 创建 WebAPI 平台应用
- 开通「语音听写(流式版)」服务
- 检察并生存:APIKey(身份标识)、APISecret(署名密钥,需严格保密)
天生合规 date 参数:
- 格式要求:严格遵照 RFC1123 标准,时区必须为 UTC+0/GMT
- 校验规则:服务端会校验本地时间与服务器时间的弊端,超时哀求直接拦截,需确保本地时间同步
构造署名原始字段(signature_origin):按固定规则拼接 3 个参数(\n 为换行符,: 后必须生存 1 个空格):- host: $host\n
- date: $date\n
- $request-line
复制代码 字段分析:
- $host:固定为 iat.xf-yun.com
- $date:步调 2 天生的 RFC1123 格式时间
- $request-line:固定为 GET /v1 HTTP/1.1(对应接口哀求路径)
示例:- host: iat.xf-yun.com
- date: Tue, 14 May 2024 08:46:48 GMT
- GET /v1 HTTP/1.1
复制代码 接着,使用 hmac-sha256 加密算法,以 APISecret 为密钥,对 signature_origin 举行加密署名:- signature_sha = hmac-sha256(signature_origin, $apiSecret)
复制代码 对 signature_sha 举行Base64 编码,得到可用于拼接的 signature 字符串。
按固定格式拼接(留意引号、空格不可错漏,headers 为固定参数名,不可修改):- api_key="$api_key", algorithm="hmac-sha256", headers="host date request-line", signature="$signature"
复制代码
- 关键提示:headers的值为固定字符串 "host date request-line",仅代表到场署名的参数名,不是参数实际值
对 authorization_origin 举行Base64 编码,得到终极可拼接到 URL 的 authorization 参数
终极哀求格式为(保举使用wss加密协议提升安全性):- ws[s]://iat.xf-yun.com/v1?authorization={authorization}&date={date}&host={host}
复制代码 5.1.4.2 数据传输示例
讯飞中英辨认大模子接纳WebSocket 全双工通讯,握手乐成后客户端与服务端创建长毗连,支持双向数据传输:
- 上传:客户端以流式分包方式发送音频数据,服务端实时分析并辨认
- 吸取:服务端完成辨认片断后,通过 WebSocket 自动推送辨认效果到客户端
- 核心原则:符合实时语音场景,克制发包隔断过短 / 包长过大导致辨认耗时增长
音频发送规范发起:
哀求 JSON 示例(分帧逻辑)如下:
第一帧数据(status=0):- {
- "header": {
- "app_id": "your_appid",
- "res_id": "hot_words",
- "status": 0
- },
- "parameter": {
- "iat": {
- "domain": "slm",
- "language": "zh_cn",
- "accent": "mandarin",
- "dwa": "wpgs",
- "result": {
- "encoding": "utf8",
- "compress": "raw",
- "format": "json"
- }
- }
- },
- "payload": {
- "audio": {
- "encoding": "raw",
- "sample_rate": 16000,
- "channels": 1,
- "bit_depth": 16,
- "seq": 1,
- "status": 0,
- "audio": "AAAAAP..." // Base64编码的第一帧音频数据
- }
- }
- }
复制代码 中央帧数据(status=1):- {
- "header": {
- "app_id": "your_appid",
- "res_id": "hot_words",
- "status": 1
- },
- "parameter": {
- "iat": {...} // 与第一帧参数一致
- },
- "payload": {
- "audio": {
- "encoding": "raw",
- "sample_rate": 16000,
- "channels": 1,
- "bit_depth": 16,
- "seq": 2, // 帧序号递增
- "status": 1,
- "audio": "AAAAAA..." // Base64编码的中间帧音频数据
- }
- }
- }
复制代码 末了一帧数据:- {
- "header": {
- "app_id": "your_appid",
- "res_id": "hot_words",
- "status": 2
- },
- "parameter": {
- "iat": {...} // 与第一帧参数一致
- },
- "payload": {
- "audio": {
- "encoding": "raw",
- "sample_rate": 16000,
- "channels": 1,
- "bit_depth": 16,
- "seq": 531, // 最后一帧序号
- "status": 2,
- "audio": "" // 最后一帧可无音频数据
- }
- }
- }
复制代码 哀求核心参数分析:
返回 JSON 示例(流式辨认效果):
第一帧返回(status=0):- {
- "header": {
- "code": 0,
- "message": "success",
- "sid": "iat00e0044@hu18f5b16b033032...",
- "status": 0
- }
- }
复制代码 中央帧返回(status=1):- {
- "header": {
- "code": 0,
- "message": "success",
- "sid": "iat00e0044@hu18f5b16b033032...",
- "status": 1
- },
- "payload": {
- "result": {
- "compress": "raw",
- "encoding": "utf8",
- "format": "json",
- "seq": 2, // 对应请求帧序号
- "status": 1,
- "text": "cy12b1j6l9x1b..." // Base64编码的识别片段文本
- }
- }
- }
复制代码 末了一帧返回(status=2):- {
- "header": {
- "code": 0,
- "message": "success",
- "sid": "iat00e0044@hu18f5b16b033032...",
- "status": 2
- },
- "payload": {
- "result": {
- "compress": "raw",
- "encoding": "utf8",
- "format": "json",
- "seq": 76, // 最后一帧序号
- "status": 2,
- "text": "cy12b1j6l9x1bN2y..." // Base64编码的最终识别文本
- }
- }
- }
复制代码 简单来说,就是:
- 效果分析:返回效果中 payload.result.text 为 Base64 编码的文本,需先解码再分析 JSON,提取终极笔墨
- 状态关联:返回的 header.status 与哀求帧 status 对应,标识当前辨认阶段
- 错误处置惩罚:header.code=0 体现乐成,非 0 为错误(需参考官方错误码排查)
- 流式拼接:中央帧返回的 text 为辨认片断,需按 seq 次序拼接,末了一帧为完备效果
5.1.4.3 哀求入参与返回出参分析
哀求参数顶层布局如下:
顶层布局如下:
文本解码后参数分析(text 字段):payload.result.text 经 Base64 解码后为 JSON 对象,包罗布局化辨认效果,如下:- {
- "sn": 1,
- "ls": true,
- "bg": 0,
- "ed": 6,
- "ws": [{"cw": [{"w": "你好"}], "bg": 0}],
- "wb": 0,
- "wc": 0,
- "we": 0,
- "wp": 0,
- "ng": 0,
- "ph": 0
- }
复制代码
仅当开启动态修正(parameter.iat.dwa="wpgs")时返回,用于优化实时辨认效果:
5.2 实验前的准备
这是讯飞开放平台「星火语音辨认大模子」的产物首页,页面展示了该模子支持 37 种外语、202 种方言的实时语音转写本领,以及客户服务、游戏娱乐等实用场景和付费套餐,核心操纵是点击「免费试用」按钮,正式进入 ASR 服务的开通流程,是整个 API 设置的出发点。
上半部门为语音辨认服务套餐列表,点击「免费领取」选中中文语音辨认免费试用包;下半部门为服务购买页,点击「+」号按钮,触发新建应用流程,为 ASR 服务绑定专属的开发应用,是开通服务、天生 API 根据的关键前置步调。
上半部门是订单确认页,免费套餐应付金额为 0 元,勾选服务协议后点击「确认下单」,完成 ASR 服务的免费开通;下半部门展示了控制台入口,点击「控制台」即可进入应用管理配景,获取后续开发所需的 API 认证信息,是服务开通的收尾操纵。
上半部门是「我的应用」列表,表现了刚创建的「ASR 语音辨认」应用及其专属 APPID;下半部门是该应用的「中文辨认大模子」服务详情页,展示了剩余服务量、到期时间,以及 WebSocket 接口认证所需的 APPID、APIKey、APISecret 等核心开发根据,这些信息正是 Pico 端 xfyun_asr.py 代码中须要设置的授权参数,用于调用讯飞 ASR 语音辨认服务。
5.3 实验案例
在 upypi(https://upypi.net/)中搜刮 xfyun_asr:
这是一个实用于 MicroPython 的讯飞中英辨认大模子(ASR)驱动,通过 WebSocket 毗连讯飞开放平台,将 PCM 音频文件实时辨以为笔墨,已在树莓派 Pico 2W 上通过验证。
复制安装下令:- mpremote mip install https://upypi.net/pkgs/xfyun_asr/1.0.0
复制代码 输入到终端中实验:

然后将下面代码中 WIFI 和 API 干系设置项补全,烧录到单片机中:- # Python env : MicroPython v1.23.0
- # -*- coding: utf-8 -*-
- # @Time : 2026/04/14
- # @Author : leeqingsui
- # @File : main.py
- # @Description : iFlytek TTS + ASR demo for MicroPython on Raspberry Pi Pico 2W
- # ======================================== 导入相关模块 =========================================
- import network
- import asyncio
- import time
- import ntptime
- from xfyun_tts import XfyunTTS
- from xfyun_asr import XfyunASR
- # ======================================== 全局变量 ============================================
- WIFI_SSID = "your_wifi_ssid"
- WIFI_PASSWORD = "your_wifi_password"
- # TTS 凭据(需在讯飞控制台开通语音合成服务)
- TTS_APPID = "your_tts_appid"
- TTS_API_KEY = "your_tts_api_key"
- TTS_API_SECRET = "your_tts_api_secret"
- # ASR 凭据(需在讯飞控制台开通中英识别大模型服务)
- ASR_APPID = "your_asr_appid"
- ASR_API_KEY = "your_asr_api_key"
- ASR_API_SECRET = "your_asr_api_secret"
- OUTPUT_PCM = "output.pcm"
- OUTPUT_WAV = "output.wav"
- # ======================================== 功能函数 ============================================
- def connect_wifi():
- """
- 连接 WiFi 并返回网络对象。
- Returns:
- network.WLAN: 已连接的 WLAN 对象;连接失败时返回 None。
- ==========================================
- Connect to WiFi and return the network object.
- Returns:
- network.WLAN: Connected WLAN object; None if connection fails.
- """
- wlan = network.WLAN(network.STA_IF)
- wlan.active(True)
- if not wlan.isconnected():
- print("Connecting to WiFi:", WIFI_SSID)
- wlan.connect(WIFI_SSID, WIFI_PASSWORD)
- timeout = 15
- while not wlan.isconnected() and timeout > 0:
- time.sleep(1)
- timeout -= 1
- print("Connecting...", timeout, "s remaining")
- if wlan.isconnected():
- ip_info = wlan.ifconfig()
- print("WiFi connected")
- print("IP:", ip_info[0])
- print("Gateway:", ip_info[2])
- else:
- print("WiFi connection failed")
- return None
- else:
- print("WiFi already connected")
- return wlan
- def sync_ntp():
- """
- 通过 NTP 同步系统时间,为讯飞 API 鉴权签名提供准确时间戳。
- 依次尝试多个 NTP 服务器,全部失败时打印警告但不中断流程。
- ==========================================
- Sync system time via NTP for iFlytek API authentication signature.
- Tries multiple NTP servers in order; prints a warning if all fail.
- """
- servers = ("ntp.aliyun.com", "ntp.tencent.com", "pool.ntp.org")
- for host in servers:
- try:
- ntptime.host = host
- ntptime.settime()
- t = time.gmtime()
- print("NTP synced via {}: {}-{:02d}-{:02d} {:02d}:{:02d}:{:02d} UTC".format(
- host, t[0], t[1], t[2], t[3], t[4], t[5]))
- return
- except Exception as e:
- print("NTP failed ({}):".format(host), e)
- print("NTP sync unavailable; signature timestamp may be rejected.")
- async def run_tts(text):
- """
- 调用 XfyunTTS 流式合成指定文本,将 PCM 数据写入 output.pcm。
- Args:
- text (str): 待合成的文本内容。
- ==========================================
- Synthesize text via XfyunTTS and write raw PCM to output.pcm.
- Args:
- text (str): Text to synthesize.
- """
- print("Synthesizing:", text)
- total = await tts.synthesize(text, filepath=OUTPUT_PCM)
- if total:
- print("Saved", total, "bytes ->", OUTPUT_PCM)
- else:
- print("Synthesis failed: no audio data received.")
- async def run_tts_wav(text):
- """
- 调用 XfyunTTS 流式合成指定文本,将带 WAV 头的音频写入 output.wav。
- Args:
- text (str): 待合成的文本内容。
- ==========================================
- Synthesize text via XfyunTTS and write WAV file to output.wav.
- Args:
- text (str): Text to synthesize.
- """
- print("Synthesizing (WAV):", text)
- total = await tts.synthesize(text, filepath=OUTPUT_WAV)
- if total:
- print("Saved", total, "bytes PCM +44 bytes header ->", OUTPUT_WAV)
- else:
- print("Synthesis failed: no audio data received.")
- async def run_asr(filepath):
- """
- 调用 XfyunASR 识别指定 PCM 文件,打印识别结果。
- Args:
- filepath (str): 待识别的 PCM 文件路径。
- ==========================================
- Recognize a PCM file via XfyunASR and print the result.
- Args:
- filepath (str): Path to the PCM file to recognize.
- """
- print("Recognizing:", filepath)
- text = await asr.recognize(filepath)
- if text:
- print("ASR result:", text)
- else:
- print("Recognition failed: no text returned.")
- # ======================================== 自定义类 ============================================
- # ======================================== 初始化配置 ===========================================
- time.sleep(3)
- print("FreakStudio: iFlytek TTS + ASR Demo")
- tts = XfyunTTS(
- app_id = TTS_APPID,
- api_key = TTS_API_KEY,
- api_secret = TTS_API_SECRET,
- )
- # ASR 采样率须与 TTS 输出一致(TTS 默认 auf=audio/L16;rate=8000 → 8000 Hz)
- asr = XfyunASR(
- app_id = ASR_APPID,
- api_key = ASR_API_KEY,
- api_secret = ASR_API_SECRET,
- sample_rate = 8000,
- )
- # ======================================== 主程序 ===========================================
- if __name__ == "__main__":
- if not connect_wifi():
- print("Aborting: WiFi unavailable.")
- else:
- sync_ntp()
- # Demo 1: TTS 合成中英混合文本 → output.pcm
- asyncio.run(run_tts("大家好一块吃饭吧hello"))
- # Demo 2: ASR 识别 output.pcm → 打印文字
- asyncio.run(run_asr(OUTPUT_PCM))
- # Demo 3: TTS 合成 → output.wav(可在 PC 上直接播放验证)
- asyncio.run(run_tts_wav("Hi there, this is a WAV format test from Pico 2W."))
复制代码 这是一段基于树莓派 Pico 2W 硬件、运行在 MicroPython v1.23.0 情况的讯飞语音交互演示代码,它集成了讯飞语音合成(TTS)与语音辨认(ASR) 双功能,通过 WiFi 毗连网络并同步 NTP 时间完成 API 鉴权,可将文本转换为 PCM/WAV 格式音频文件,也能对音频文件举行笔墨辨认,完备实现了「笔墨转语音、语音转笔墨」的闭环语音交互测试,仅需设置讯飞平台授权信息与 WiFi 信息即可运行,是嵌入式装备实现离线 / 在线语音交互的核心示例步伐。
打开终端表现如下:
可以看到,驱动库正常安装:
这是主步伐 main.py 运行后的 Shell 日志:
- TTS 语音合成环节(第一个红框):
- 输入:中英混淆文本 各人好一块用饭吧hello
- 实验:通过 XfyunTTS 调用讯飞 TTS API,WebSocket 毗连乐成,流式吸取音频分片,终极天生 output.pcm 原始 PCM 音频文件(总巨细 39252 字节)
- 验证:TTS 合成正常,支持中英混淆文本,流式传输适配 MicroPython 的内存限定(单片机内存小,无法一次性加载大音频)。
- ASR 语音辨认环节(第二个红框):
- 输入:刚才 TTS 天生的 output.pcm 音频文件
- 实验:通过 XfyunASR 调用讯飞 ASR API,分帧发送音频数据,吸取辨认效果
- 输出:ASR result: 各人好,一块用饭吧,hello。
- 验证:
- ✅ 100% 还原输入文本,无错字、漏字
- ✅ 中英混淆辨认精确,自动添加规范标点
- ✅ 8000Hz 采样率的 PCM 音频辨认正常(和 TTS 输出采样率完全匹配,无格式标题)
- 附加验证:
- 后续日志:TTS 合成 WAV 格式文件(output.wav),可直接在电脑上用播放器打开,验证音频格式精确。
- 网络与时间:WiFi 毗连正常、NTP 时间同步乐成(讯飞 API 鉴权须要精确时间戳,确保署名有用),整个流程无鉴权错误。
输出的 PCM 文件可以在网站 https://pcm.qer.im/中播放:
验证乐成。
原文链接:https://f1829ryac0m.feishu.cn/wiki/J0lDwNHtCizJwekOXRecPA7inwb?fromScene=spaceOverview
|