跳至主要内容

翻譯語音 - Wio Terminal

在這部分課程中,你將編寫代碼以使用翻譯服務來翻譯文本。

使用翻譯服務將文本轉換為語音

語音服務 REST API 不支持直接翻譯,你可以使用翻譯服務來翻譯由語音轉文本服務生成的文本,以及語音回應的文本。此服務有一個 REST API 你可以用來翻譯文本,但為了使其更易於使用,這將被包裝在你的函數應用程序中的另一個 HTTP 觸發器中。

任務 - 創建一個無伺服器函數來翻譯文本

  1. 在 VS Code 中打開你的 smart-timer-trigger 項目,並打開終端,確保虛擬環境已激活。如果沒有,請終止並重新創建終端。

  2. 打開 local.settings.json 文件,並為翻譯 API 鍵和位置添加設置:

    "TRANSLATOR_KEY": "<key>",
    "TRANSLATOR_LOCATION": "<location>"

    <key> 替換為你的翻譯服務資源的 API 鍵。將 <location> 替換為你創建翻譯服務資源時使用的位置。

  3. 使用以下命令在函數應用程序項目的根文件夾中的 VS Code 終端內添加一個名為 translate-text 的新 HTTP 觸發器:

    func new --name translate-text --template "HTTP trigger"

    這將創建一個名為 translate-text 的 HTTP 觸發器。

  4. 用以下內容替換 translate-text 文件夾中的 __init__.py 文件的內容:

    import 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 的參數,將要翻譯的文本作為主體。最後,返回翻譯結果。

  5. 在本地運行你的函數應用程序。然後,你可以使用 curl 之類的工具來調用它,就像你測試 text-to-timer HTTP 觸發器一樣。確保將要翻譯的文本和語言作為 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 文件夾中找到此代碼。

任務 - 使用翻譯函數來翻譯文本

  1. 如果尚未打開,請在 VS Code 中打開 smart-timer 項目。

  2. 你的智能計時器將設置兩種語言 - 用於訓練 LUIS 的服務器語言(同樣的語言也用於構建與用戶對話的消息),以及用戶說的語言。更新 config.h 頭文件中的 LANGUAGE 常量為用戶將說的語言,並添加一個名為 SERVER_LANGUAGE 的新常量,用於訓練 LUIS 的語言:

    const char *LANGUAGE = "<user language>";
    const char *SERVER_LANGUAGE = "<server language>";

    <user language> 替換為你將用來說話的語言的區域名稱,例如法語的 fr-FR,或粵語的 zn-HK

    <server language> 替換為用於訓練 LUIS 的語言的區域名稱。

    你可以在 Microsoft docs 上的語言和語音支持文檔 中找到支持的語言及其區域名稱列表。

    💁 如果你不會多種語言,你可以使用 Bing 翻譯Google 翻譯 之類的服務,將你的首選語言翻譯成你選擇的語言。這些服務然後可以播放翻譯文本的音頻。

    例如,如果你用英語訓練 LUIS,但想使用法語作為用戶語言,你可以使用 Bing 翻譯將 "set a 2 minute and 27 second timer" 從英語翻譯成法語,然後使用 聽翻譯 按鈕將翻譯說到你的麥克風中。

    Bing 翻譯上的聽翻譯按鈕

  3. SPEECH_LOCATION 下添加翻譯 API 鍵和位置:

    const char *TRANSLATOR_API_KEY = "<KEY>";
    const char *TRANSLATOR_LOCATION = "<LOCATION>";

    <KEY> 替換為你的翻譯服務資源的 API 鍵。將 <LOCATION> 替換為你創建翻譯服務資源時使用的位置。

  4. VOICE_URL 下添加翻譯觸發器 URL:

    const char *TRANSLATE_FUNCTION_URL = "<URL>";

    <URL> 替換為你的函數應用程序上的 translate-text HTTP 觸發器的 URL。這將與 TEXT_TO_TIMER_FUNCTION_URL 的值相同,只是函數名稱為 translate-text 而不是 text-to-timer

  5. src 文件夾中添加一個名為 text_translator.h 的新文件。

  6. 此新的 text_translator.h 頭文件將包含一個用於翻譯文本的類。將以下內容添加到此文件中以聲明此類:

    #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 客戶端。

  7. 在此類的 public 部分中添加一個方法來翻譯文本:

    String translateText(String text, String from_language, String to_language)
    {
    }

    此方法接受要翻譯的語言和要翻譯到的語言。在處理語音時,語音將從用戶語言翻譯為 LUIS 服務器語言,並在給出回應時將從 LUIS 服務器語言翻譯為用戶語言。

  8. 在此方法中,添加代碼以構建包含要翻譯的文本和語言的 JSON 主體:

    DynamicJsonDocument 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);
  9. 在此之下,添加以下代碼以將主體發送到無伺服器函數應用程序:

    HTTPClient httpClient;
    httpClient.begin(_client, TRANSLATE_FUNCTION_URL);

    int httpResponseCode = httpClient.POST(body);
  10. 接下來,添加代碼以獲取響應:

    String 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);
    }
  11. 最後,添加代碼以關閉連接並返回翻譯文本:

    httpClient.end();

    return translated_text;

任務 - 翻譯識別的語音和回應

  1. 打開 main.cpp 文件。

  2. 在文件頂部添加一個包含 TextTranslator 類頭文件的指令:

    #include "text_translator.h"
  3. 設置計時器時說的文本需要翻譯。為此,在 say 函數的第一行添加以下內容:

    text = textTranslator.translateText(text, LANGUAGE, SERVER_LANGUAGE);

    這將文本翻譯為用戶語言。

  4. processAudio 函數中,通過 String text = speechToText.convertSpeechToText(); 調用從捕獲的音頻中檢索文本。在此調用之後,翻譯文本:

    String text = speechToText.convertSpeechToText();
    text = textTranslator.translateText(text, LANGUAGE, SERVER_LANGUAGE);

    這將文本從用戶語言翻譯為服務器上使用的語言。

  5. 構建此代碼,將其上傳到你的 Wio Terminal,並通過串行監視器進行測試。一旦你在串行監視器中看到 Ready,按下 C 按鈕(左側最靠近電源開關的按鈕),然後說話。確保你的函數應用程序正在運行,並用用戶語言請求計時器,無論是自己說該語言,還是使用翻譯應用程序。

    Connecting 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 文件夾中找到此代碼。

😀 你的多語言計時器程序成功了!