news 2026/9/14 12:03:18

IoT-For-Beginners 多语言智能计时器:在 Raspberry Pi 上用 Azure Translator REST API 实现语音翻译

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
IoT-For-Beginners 多语言智能计时器:在 Raspberry Pi 上用 Azure Translator REST API 实现语音翻译

IoT-For-Beginners 多语言智能计时器:在 Raspberry Pi 上用 Azure Translator REST API 实现语音翻译

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

本篇指南基于 IoT-For-Beginners 开源课程项目的消费者项目第 4 课,讲解如何在 Raspberry Pi 上用 Python 调用 Azure Translator REST API 为语音交互应用添加双向文本翻译能力。读完后,你将掌握"用户语言 ↔ 服务器语言"的双语架构设计、Translator REST API 的完整调用方式(URL、请求头、参数、批量请求体与响应解析),以及一个可直接运行的智能计时器端到端实现。

为什么需要翻译:双语言架构

在多语言智能设备的典型架构中,应用的核心逻辑(语言理解 LUIS、应答文本的生成)通常只基于一种"服务器语言"训练和构建。为了让用户用自己的母语与设备对话,需要在语音识别之后、语言理解之前插入一次"用户语言 → 服务器语言"的翻译;在设备应答时,再插入一次"服务器语言 → 用户语言"的翻译。

下图展示了 smart timer 的完整多语言数据流:用户语音经麦克风采集后先做语音识别(STT)得到用户语言文本,Translator 将其翻译为服务器语言文本,经 Azure IoT Hub 与 Azure Functions 交给 LUIS 理解并生成应答文本,Functions 再经 IoT Hub 把应答发回设备,翻译回用户语言后合成语音(TTS)播放:

这一架构的关键前提是:Speech 服务的 REST API 并不支持在识别时直接附带翻译(内置翻译能力仅存在于 Speech SDK),因此课程选择用独立的 Translator 服务在设备端完成文本翻译,而智能计时器的其余部分保持不变。相关课程背景见 课程 README,设备端完整实现见 code/pi 目录。

第一步:定义用户语言与服务器语言两个变量

智能计时器需要同时持有两种语言:

  • language:用户实际说出的语言(用于语音识别与语音合成);
  • server_language:训练 LUIS 模型所用的语言(也是应答文本的原始生成语言)。

app.py顶部做如下更新:

language = '<user language>' server_language = '<server language>'

<user language>替换为你将说出的语言的区域名(locale),例如法语是fr-FR;将<server language>替换为训练 LUIS 所用的语言区域名。

提示(来自原文档):如果你不会说第二种语言,可以先用在线翻译工具把"set a 2 minute and 27 second timer"这类句子从服务器语言翻译成目标语言,并播放其发音,对着设备说出来即可。原文档中的示例即法语场景,区域名为fr-FR

第二步:配置 Translator API 密钥

Speech 服务需要先向 token issuer API 换取 access token,而Translator 服务不需要——它直接接受 API key。因此在speech_api_key下方新增:

translator_api_key = '<key>'

<key>替换为你的 Translator 资源的 API key。该资源通过 Azure CLI 创建(见 课程 README):

az cognitiveservices account create --name smart-timer-translator \ --resource-group smart-timer \ --kind TextTranslation \ --sku F0 \ --yes \ --location <location> az cognitiveservices account keys list --name smart-timer-translator \ --resource-group smart-timer \ --output table

第三步:实现translate_text函数

say函数上方定义translate_text函数。fromto语言作为参数传入,因为应用需要在两个方向上使用它——识别语音时从用户语言转到服务器语言,提供语音应答时从服务器语言转回用户语言:

def translate_text(text, from_language, to_language):

构造 URL 与请求头

url = f'https://api.cognitive.microsofttranslator.com/translate?api-version=3.0' headers = { 'Ocp-Apim-Subscription-Key': translator_api_key, 'Ocp-Apim-Subscription-Region': location, 'Content-type': 'application/json' }

注意两点实现细节:

  1. URL 与 location 的关系:Speech 服务的 REST 端点是按区域划分的(如https://{location}.stt.speech.microsoft.com/...),而 Translator 的端点api.cognitive.microsofttranslator.com是全球统一的,区域信息通过Ocp-Apim-Subscription-Region请求头传递;
  2. 鉴权方式:API key 通过Ocp-Apim-Subscription-Key请求头直接传递,无需像 Speech 服务那样调用issuetoken接口获取 Bearer token。

构造参数与请求体

params = { 'from': from_language, 'to': to_language } body = [{ 'text' : text }]
  • params指定翻译方向:把from语言的文本翻译成to语言;
  • body是要翻译的文本。请求体是一个数组——因为同一次调用中可以批量翻译多个文本块。

发起请求并解析响应

response = requests.post(url, headers=headers, params=params, json=body)

响应是一个 JSON 数组,其中第一项包含translations数组,对应请求体中每个文本项的翻译结果:

[ { "translations": [ { "text": "Set a 2 minute 27 second timer.", "to": "en" } ] } ]

从数组第一项的第一条翻译中取出text属性并返回:

return response.json()[0]['translations'][0]['text']

第四步:在主循环中翻译用户语音

更新while True主循环,将convert_speech_to_text识别出的文本从用户语言翻译到服务器语言后再发给 IoT Hub:

if len(text) > 0: print('Original:', text) text = translate_text(text, language, server_language) print('Translated:', text) message = Message(json.dumps({ 'speech': text })) device_client.send_message(message)

这段代码同时把原文与译文打印到控制台,便于调试识别与翻译环节。

第五步:在say函数中翻译应答文本

更新say函数,把要朗读的文本从服务器语言翻译回用户语言,再交给 TTS:

def say(text): print('Original:', text) text = translate_text(text, server_language, language) print('Translated:', text) speech = get_speech(text) play_speech(speech)

get_speech会用language(用户语言)对应的 voice 构造 SSML 并调用 TTS 端点,因此翻译后的文本正好与合成语音的语言匹配。

运行与预期输出

确保 Functions 应用正在运行,然后用用户语言(自己说或用翻译工具播放音频)请求一个计时器:

pi@raspberrypi:~/smart-timer $ python3 app.py Connecting Connected Using voice fr-FR-DeniseNeural Original: Définir une minuterie de 2 minutes et 27 secondes. Translated: Set a timer of 2 minutes and 27 seconds. Original: 2 minute 27 second timer started. Translated: 2 minute 27 seconde minute a commencé. Original: Times up on your 2 minute 27 second timer. Translated: Chronométrant votre minuterie de 2 minutes 27 secondes.

提示(来自原文档):由于不同语言表达同一意思的方式不同,你得到的识别/翻译文本可能与你给 LUIS 的示例略有差异。遇到这种情况,应给 LUIS 增加更多示例,然后重新训练并重新发布模型。

源码级解析:完整设备端实现

课程给出的完整代码位于 code/pi/smart-timer/app.py,其中与翻译直接相关的调用链如下:

  • translate_text:即上文逐步构建的函数,一次requests.post完成翻译,返回response.json()[0]['translations'][0]['text']
  • convert_speech_to_text:STT 端点按区域划分({location}.stt.speech.microsoft.com),通过get_access_token()获取 Bearer token,并把language作为查询参数传入——这就是"识别的是用户语言"的落点;
  • say:翻译后调用get_speech/play_speech,SSML 中的xml:lang与 voice 均基于用户语言;
  • 主循环:按住按钮采集音频 → STT → 翻译 → 以{"speech": text}的 JSON 消息发送到 IoT Hub。

从源码结构看,翻译被放置在设备端有两个原因:一来识别出的文本必须先进入服务器语言才能被 LUIS 理解,这一步在消息离开设备前完成;二来应答文本在进入 TTS 前完成回译,保证合成语音的语言与用户一致。

同一翻译能力的三种落点:设备端、云端与 SDK

课程在同一个 code 目录下给出了三套实现,可以对照理解翻译能力的不同放置位置:

  1. 树莓派(本篇):设备端直接用 REST API 调用 Translator,密钥写在设备代码中,适合资源充足、能自由出网的单板机;
  2. WIO Terminal:资源受限的嵌入式设备改为调用 Azure Functions 中的 translate-text 函数 作为代理。C++ 侧的 TextTranslator 类 将textfrom_languageto_language序列化为 JSON POST 到TRANSLATE_FUNCTION_URL,由 Functions 侧读取环境变量TRANSLATOR_KEYTRANSLATOR_LOCATION完成真正的 API 调用,再返回翻译文本——密钥因此不落在设备上;
  3. 虚拟设备:识别环节改用 Speech SDK 的TranslationRecognizerSpeechTranslationConfig中设置speech_recognition_languagetarget_languages),SDK 在识别的同时直接返回目标语言文本,识别方向不再需要 REST 翻译;但 TTS 方向仍保留与树莓派版一致的 RESTtranslate_text实现,见 virtual-iot-device/smart-timer/app.py。Functions 侧的环境变量配置可在 local.settings.json 中对照查看(TRANSLATOR_KEYTRANSLATOR_LOCATION)。

三种方案对应同一条架构主线:识别与合成用 Speech 服务,翻译用 Translator 服务;差异只在于翻译调用放在设备端 REST、云端代理还是 SDK 内置能力。

后续方向与清理

完成本课后的进阶任务是用两台设备(其中一台可以是虚拟设备)搭建"通用翻译机":一台配置为一种语言,另一台配置为另一种语言,各自把语音转为文本经 IoT Hub 与 Functions 发给对方,翻译后播放——完整要求见 assignment.md。

本课是消费者项目的最后一课。课程 README 提醒:完成课程与作业后,应按 clean-up 指南 清理你创建的 cloud 资源(Speech、Translator、IoT Hub、Functions 等),以免产生不必要的费用。

【免费下载链接】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 12:03:11

有线通信标准全解析:从铜缆到光纤,从以太网到工业总线

我入行那会儿&#xff0c;师傅跟我说过一句话&#xff1a;无线是趋势&#xff0c;但有线才是底线。干了十几年通信和嵌入式相关的活儿&#xff0c;这话我越想越觉得对。数据中心里几百G的流量在跑&#xff0c;工厂产线上机械臂在分秒级联动&#xff0c;手术室里超高清内窥镜画面…

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

从零手写MCP Server:协议核心、开发部署与客户端接入全指南

/* 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 12:00:51

光储系统双层优化模型与改进粒子群算法实践

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

作者头像 李华