news 2026/9/14 9:54:33

基于 Azure Speech REST API 的 Raspberry Pi 语音转文本实现(IoT-For-Beginners smart-timer)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 Azure Speech REST API 的 Raspberry Pi 语音转文本实现(IoT-For-Beginners smart-timer)

基于 Azure Speech REST API 的 Raspberry Pi 语音转文本实现(IoT-For-Beginners smart-timer)

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

本指南来自 IoT-For-Beginners 项目第 6 部分「消费者设备」第 1 课(语音识别)的 Raspberry Pi 分支,讲解如何在树莓派上把录音按钮捕获到的语音通过 Azure 认知服务语音服务 REST API 实时转换为文本。读完本文,你将掌握访问令牌获取、REST 调用、RecognitionStatus/DisplayText响应解析,并得到一个可运行的「智能定时器」语音输入原型。

工作原理:先换令牌,再调 REST API

pi-speech-to-text.md采用的方案不是官方 Python SDK,而是纯 HTTP REST 调用:先用 API Key 从令牌签发端点换取短期访问令牌,再携带该令牌把 WAV 音频 POST 到识别端点。访问令牌有效期只有 10 分钟,因此代码每次识别前都应重新换取,保证令牌始终新鲜。

整个过程对应三个关键端点与两个阶段:

  1. 换令牌POST https://{location}.api.cognitive.microsoft.com/sts/v1.0/issuetoken,请求头携带Ocp-Apim-Subscription-Key
  2. 识别POST https://{location}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1,请求头携带Authorization: Bearer <token>与音频格式声明,请求体为 WAV 二进制数据。

前置条件:硬件与录音环境

本课建立在前两小节之上:pi-microphone.md(麦克风/扬声器配置)与pi-audio.md(按键控制录音)。需要确认:

  • 硬件:麦克风(USB 麦克风、USB 声卡+3.5mm 麦克风,或 [ReSpeaker 2-Mics Pi HAT],注意蓝牙麦克风在 Pi 上兼容性差);Grove 按键(若使用 ReSpeaker HAT 则免接,HAT 自带按键在 D17);扬声器。
  • 系统配置:用arecord -l查麦克风卡号,用aplay -l查扬声器卡号(card 0: Headphones为板载 3.5mm 接口),并在/usr/share/alsa/alsa.conf中把defaults.pcm.card改成目标扬声器卡号。
  • 依赖安装
    sudo apt update sudo apt install libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev libasound2-plugins --yes pip3 install pyaudio
  • 录音代码app.py用 PyAudio 打开pyaudio.paInt16、单声道、rate=48000(如报Invalid sample rate改 44100 或 16000)、frames_per_buffer=4096的输入流,while button.is_pressed()循环把 4096 字节块写入frames,松键后用wave模块封装为内存 WAV(io.BytesIO)并返回。可参照 code-record/pi/smart-timer/app.py。

实现步骤:把录音变成文本

以 code-speech-to-text/pi/smart-timer/app.py 为最终形态,逐步改造smart-timer项目中的app.py

1. 准备请求库与配置

删除上一节用于回放的play_audio函数(智能定时器不需要复读用户的话),并在文件顶部加入:

import requests

while True循环之前声明语音服务配置:

speech_api_key = '<key>' location = '<location>' language = '<language>'
  • <key>:语音服务资源的 API Key(创建资源后由az cognitiveservices account keys list获取);
  • <location>:创建资源时选择的区域,例如eastus,它决定令牌端点和识别端点的域名;
  • <language>:语音区域设置(locale),如en-GB对应英语,zn-HK对应粤语。完整列表见微软官方「Language and voice support」文档。

2. 获取访问令牌

def get_access_token(): headers = { 'Ocp-Apim-Subscription-Key': speech_api_key } token_endpoint = f'https://{location}.api.cognitive.microsoft.com/sts/v1.0/issuetoken' response = requests.post(token_endpoint, headers=headers) return str(response.text)

该函数把 API Key 放进Ocp-Apim-Subscription-Key请求头,POST 到令牌签发端点,返回的响应体即访问令牌字符串。令牌有效期 10 分钟,若识别返回 401(令牌过期),需重新调用本函数换新令牌再重试——这一点在 Wio Terminal 的 C++ 实现中体现得更明显(见 wio-terminal-speech-to-text.md 的 401 分支处理)。

3. 声明识别函数并组装请求

def convert_speech_to_text(buffer): url = f'https://{location}.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1' headers = { 'Authorization': 'Bearer ' + get_access_token(), 'Content-Type': f'audio/wav; codecs=audio/pcm; samplerate={rate}', 'Accept': 'application/json;text/xml' } params = { 'language': language }

这里要点:

  • URL 中的{location}与配置一致,conversation表示会话式识别场景;
  • Authorization使用Bearer前缀 + 令牌,每次调用都现场换取,保证不过期;
  • Content-Type声明音频为 WAV/PCM,并携带samplerate={rate},该值与录音时 PyAudio 的采样率必须一致(源码里rate是全局变量,来自pi-audio.md的 48000/44100/16000);
  • Accept声明接受 JSON 或 XML;
  • paramslanguage告诉服务音频属于哪种语言。

4. 发送音频并解析结果

response = requests.post(url, headers=headers, params=params, data=buffer) response_json = response.json() if response_json['RecognitionStatus'] == 'Success': return response_json['DisplayText'] else: return ''

data=buffer直接上传上一节capture_audio()返回的 WAV 内存缓冲。响应 JSON 中:

  • RecognitionStatus:识别状态,Success表示成功提取出语音;
  • DisplayText:识别出的文本(DisplayText对文本进行显示优化,例如去掉标点、数字格式化等)。

5. 处理文本并改写主循环

def process_text(text): print(text) while True: while not button.is_pressed(): time.sleep(.1) buffer = capture_audio() text = convert_speech_to_text(buffer) process_text(text)

原循环中的play_audio(buffer)被替换为「识别 + 打印」。process_text目前只打印到控制台,在后续课程中会扩展为解析语音命令并设置定时器。

6. 运行验证

python3 app.py

按下按键对着麦克风说话,松键后语音被转为文本打印:

pi@raspberrypi:~/smart-timer $ python3 app.py Hello world. Welcome to IoT for beginners.

可尝试同音异义词句子,例如I want to buy two bananas and an apple too,观察服务如何依据上下文选择正确的 to/two/too,而非仅凭发音。

常见问题排查

  • OSError: [Errno -9997] Invalid sample rate:录音采样率不被硬件支持,将rate改为 44100 或 16000;
  • ALSA 提示Unknown PCM cards.pcm.front:来自 Pi 上未连接的音频设备配置,可忽略;
  • 识别返回 401:访问令牌过期,应重新调用get_access_token()后重试;
  • 识别结果为空:检查language是否与说话语言匹配、samplerate是否与录音一致、是否返回RecognitionStatusSuccess(此时函数返回空字符串)。

与另外两条实现路径的对照

同一课还提供了另外两份对照实现,便于理解 REST 与 SDK 的差异:

  • 虚拟设备(virtual-device-speech-to-text.md):在 PC 上使用官方 Python SDKazure-cognitiveservices-speech,通过SpeechConfig+SpeechRecognizer连续监听,recognized回调输出文本,无需手动换令牌;
  • Wio Terminal(wio-terminal-speech-to-text.md):与 Pi 同样走 REST 路径,但需在config.h内嵌两个 HTTPS 根证书(令牌端点证书与识别端点证书)、用WiFiClientSecure建立 TLS 连接,并通过自定义FlashStream(继承 ArduinoStream)把存放在 Flash 中的录音分块流式上传,避免内存溢出。FlashStream通过available()HTTPClient报告可发送字节数、read()逐字节取数,超过HTTP_TCP_BUFFER_SIZE即重新填充缓冲。

Pi 与 Wio 都使用同一套 REST API 语义(Bearer 令牌、Content-Type采样率声明、DisplayText字段),区别仅在传输层的实现细节,这为理解语音服务的云端协议提供了很好的跨平台参照。

小结

至此,树莓派上的「按下说话、松键识别、控制台出文本」的语音转文本程序已可运行。你已掌握 Azure 语音服务的令牌机制、REST 调用格式、WAV/PCM 音频格式声明与响应解析,这些知识将直接支撑后续课程中「把识别文本转换为智能定时器命令」的实现。

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 9:53:56

企业级AI智能体效能管理:可度量、可治理的落地实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:53:49

Q-Learning与SARSA算法实战对比及函数近似实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:51:40

700行手写RTOS内核:Cortex-M任务调度与临界区原理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:50:48

N皇后II优化全解析:从回溯到位运算与对称剪枝

刷过LeetCode的读者对第51题N皇后肯定不陌生&#xff0c;输出棋盘布局的回溯解法几乎是每个算法学习者的入门必修课。但紧接着的第52题N皇后II&#xff0c;很多人只是把它当成同一道题的简化版——只要把保存结果的代码删掉、改成计数器加一就行&#xff0c;于是草草收场。真正…

作者头像 李华