翻译语音 - Wio Terminal
在本课的这一部分中,您将编写代码,通过翻译服务来翻译文本。
使用翻译服务将文本转换为语音
语音服务的 REST API 不支持直接翻译,但您可以使用翻译服务来翻译由语音转文本服务生成的文本,以及语音响应的文本。该服务提供了一个 REST API,您可以用来翻译文本,但为了简化使用,您可以将其封装在函数应用中的另一个 HTTP 触发器中。
任务 - 创建一个无服务器函数来翻译文本
在 VS Code 中打开您的
smart-timer-trigger项目,并确保虚拟环境已激活。如果未激活,请终止并重新创建终端。打开
local.settings.json文件,并添加翻译器 API 密钥和位置的设置:json"TRANSLATOR_KEY": "<key>", "TRANSLATOR_LOCATION": "<location>"将
<key>替换为您的翻译服务资源的 API 密钥。将<location>替换为您创建翻译服务资源时使用的位置。使用以下命令在 VS Code 终端中函数应用项目的根文件夹内,为此应用添加一个名为
translate-text的新 HTTP 触发器:shfunc new --name translate-text --template "HTTP trigger"这将创建一个名为
translate-text的 HTTP 触发器。将
translate-text文件夹中的__init__.py文件内容替换为以下内容:pythonimport logging import os import requests import azure.functions as func location = os.environ['TRANSLATOR_LOCATION'] translator_key = os.environ['TRANSLATOR_KEY'] def main(req: func.HttpRequest) -> func.HttpResponse: req_body = req.get_json() from_language = req_body['from_language'] to_language = req_body['to_language'] text = req_body['text'] logging.info(f'Translating {text} from {from_language} to {to_language}') url = f'https://api.cognitive.microsofttranslator.com/translate?api-version=3.0' headers = { 'Ocp-Apim-Subscription-Key': translator_key, 'Ocp-Apim-Subscription-Region': location, 'Content-type': 'application/json' } params = { 'from': from_language, 'to': to_language } body = [{ 'text' : text }] response = requests.post(url, headers=headers, params=params, json=body) return func.HttpResponse(response.json()[0]['translations'][0]['text'])此代码从 HTTP 请求中提取文本和语言,然后向翻译器 REST API 发出请求,将语言作为 URL 的参数,文本作为请求体传递。最后返回翻译结果。
在本地运行您的函数应用。您可以使用类似 curl 的工具来调用它,就像测试
text-to-timerHTTP 触发器一样。确保以 JSON 格式的请求体传递要翻译的文本和语言:json{ "text": "Définir une minuterie de 30 secondes", "from_language": "fr-FR", "to_language": "en-US" }此示例将 Définir une minuterie de 30 secondes 从法语翻译为美式英语。它将返回 Set a 30-second timer。
💁 您可以在 code/functions 文件夹中找到此代码。
任务 - 使用翻译器函数翻译文本
如果尚未打开,请在 VS Code 中打开
smart-timer项目。您的智能计时器将设置两种语言——用于训练 LUIS 的服务器语言(同样用于构建与用户交流的消息),以及用户使用的语言。更新
config.h头文件中的LANGUAGE常量为用户将使用的语言,并添加一个名为SERVER_LANGUAGE的新常量,用于训练 LUIS 的语言:cppconst char *LANGUAGE = "<user language>"; const char *SERVER_LANGUAGE = "<server language>";将
<user language>替换为您将使用的语言的区域名称,例如法语的fr-FR或粤语的zn-HK。将
<server language>替换为用于训练 LUIS 的语言的区域名称。您可以在 Microsoft 文档上的语言和语音支持文档 中找到支持的语言及其区域名称的列表。
💁 如果您不说多种语言,可以使用像 Bing Translate 或 Google Translate 这样的服务,将您的首选语言翻译成您选择的语言。这些服务还可以播放翻译文本的音频。
例如,如果您用英语训练 LUIS,但希望使用法语作为用户语言,您可以使用 Bing Translate 将诸如 "set a 2 minute and 27 second timer" 的句子从英语翻译成法语,然后使用 Listen translation 按钮将翻译语音播放到您的麦克风中。

在
SPEECH_LOCATION下添加翻译器 API 密钥和位置:cppconst char *TRANSLATOR_API_KEY = "<KEY>"; const char *TRANSLATOR_LOCATION = "<LOCATION>";将
<KEY>替换为您的翻译服务资源的 API 密钥。将<LOCATION>替换为您创建翻译服务资源时使用的位置。在
VOICE_URL下添加翻译器触发器 URL:cppconst char *TRANSLATE_FUNCTION_URL = "<URL>";将
<URL>替换为函数应用中translate-textHTTP 触发器的 URL。此值与TEXT_TO_TIMER_FUNCTION_URL的值相同,只是函数名称从text-to-timer改为translate-text。在
src文件夹中添加一个新文件,命名为text_translator.h。此新的
text_translator.h头文件将包含一个用于翻译文本的类。在此文件中添加以下内容以声明此类:cpp#pragma once #include <Arduino.h> #include <ArduinoJson.h> #include <HTTPClient.h> #include <WiFiClient.h> #include "config.h" class TextTranslator { public: private: WiFiClient _client; }; TextTranslator textTranslator;这声明了
TextTranslator类以及该类的一个实例。该类有一个用于 WiFi 客户端的字段。在此类的
public部分中,添加一个用于翻译文本的方法:cppString translateText(String text, String from_language, String to_language) { }此方法接收要翻译的源语言和目标语言。在处理语音时,语音将从用户语言翻译为 LUIS 服务器语言;在给出响应时,将从 LUIS 服务器语言翻译为用户语言。
在此方法中,添加代码以构造包含要翻译文本和语言的 JSON 请求体:
cppDynamicJsonDocument doc(1024); doc["text"] = text; doc["from_language"] = from_language; doc["to_language"] = to_language; String body; serializeJson(doc, body); Serial.print("Translating "); Serial.print(text); Serial.print(" from "); Serial.print(from_language); Serial.print(" to "); Serial.print(to_language);在此代码下方,添加以下代码以将请求体发送到无服务器函数应用:
cppHTTPClient httpClient; httpClient.begin(_client, TRANSLATE_FUNCTION_URL); int httpResponseCode = httpClient.POST(body);接下来,添加代码以获取响应:
cppString translated_text = ""; if (httpResponseCode == 200) { translated_text = httpClient.getString(); Serial.print("Translated: "); Serial.println(translated_text); } else { Serial.print("Failed to translate text - error "); Serial.println(httpResponseCode); }最后,添加代码以关闭连接并返回翻译后的文本:
cpphttpClient.end(); return translated_text;
任务 - 翻译识别的语音和响应
打开
main.cpp文件。在文件顶部添加一个包含
TextTranslator类头文件的指令:cpp#include "text_translator.h"设置计时器或计时器到期时说出的文本需要被翻译。为此,在
say函数的第一行添加以下内容:cpptext = textTranslator.translateText(text, LANGUAGE, SERVER_LANGUAGE);这将文本翻译为用户语言。
在
processAudio函数中,通过String text = speechToText.convertSpeechToText();调用从捕获的音频中检索文本。在此调用之后,翻译文本:cppString text = speechToText.convertSpeechToText(); text = textTranslator.translateText(text, LANGUAGE, SERVER_LANGUAGE);这将文本从用户语言翻译为服务器使用的语言。
构建此代码,将其上传到您的 Wio Terminal,并通过串行监视器进行测试。当您在串行监视器中看到
Ready时,按下 C 按钮(左侧靠近电源开关的按钮),然后开始说话。确保您的函数应用正在运行,并以用户语言请求计时器,无论是自己说该语言,还是使用翻译应用。textConnecting to WiFi.. Connected! Got access token. Ready. Starting recording... Finished recording Sending speech... Speech sent! {"RecognitionStatus":"Success","DisplayText":"Définir une minuterie de 2 minutes 27 secondes.","Offset":9600000,"Duration":40400000} Translating Définir une minuterie de 2 minutes 27 secondes. from fr-FR to en-US Translated: Set a timer of 2 minutes 27 seconds. Set a timer of 2 minutes 27 seconds. {"seconds": 147} Translating 2 minute 27 second timer started. from en-US to fr-FR Translated: 2 minute 27 seconde minute a commencé. 2 minute 27 seconde minute a commencé. Translating Times up on your 2 minute 27 second timer. from en-US to fr-FR Translated: Chronométrant votre minuterie de 2 minutes 27 secondes. Chronométrant votre minuterie de 2 minutes 27 secondes.
💁 您可以在 code/wio-terminal 文件夹中找到此代码。
😀 您的多语言计时器程序大获成功!