HoloLens(第一代)和 Azure 301:语言翻译


注意

混合现实学院教程在制作时考虑到了 HoloLens(第一代)和混合现实沉浸式头戴显示设备。 因此,对于仍在寻求这些设备的开发指导的开发人员而言,我们觉得很有必要保留这些教程。 我们不会在这些教程中更新 HoloLens 2 所用的最新工具集或集成相关的内容。 我们将维护这些教程,使之持续适用于支持的设备。 将来会发布一系列演示如何针对 HoloLens 2 进行开发的新教程。 此通知将在教程发布时通过指向这些教程的链接进行更新。


本课程介绍如何使用 Azure 认知服务和文本翻译 API 将翻译功能添加到混合现实应用程序。

Final product

文本翻译 API 是一种准实时翻译服务。 该服务基于云。应用可以使用 REST API 调用通过神经机器翻译技术将文本翻译为另一种语言。 有关详细信息,请访问 Azure 文本翻译 API 页

完成本课程后,你会有一个混合现实应用程序,该应用程序将能够执行以下操作:

  1. 用户将对连接到沉浸式 (VR) 头戴显示设备的麦克风(或 HoloLens 的内置麦克风)说话。
  2. 应用会捕获听写并将其发送到 Azure 文本翻译 API。
  3. 翻译结果会显示在 Unity 场景的简单 UI 组中。

本课程将介绍如何将 Translator 服务的结果引入基于 Unity 的示例应用程序。 你可以自行决定将这些概念应用到你可能会生成的自定义应用程序。

设备支持

课程 HoloLens 沉浸式头戴显示设备
MR 和 Azure 301:语言翻译

注意

尽管本课程主要重点介绍 Windows Mixed Reality 沉浸式 (VR) 头戴显示设备,但你也可以将本课程中学到的内容应用到 Microsoft HoloLens。 随着课程的进行,你将看到有关支持 HoloLens 可能需要进行的任何更改的说明。 使用 HoloLens 时,你可能会在语音捕获过程中注意到某些回声。

先决条件

注意

本教程专为具有 Unity 和 C# 基本经验的开发人员设计。 另请注意,本文档中的先决条件和书面说明在编写时(2018 年 5 月)已经过测试和验证。 可随意使用最新软件(如安装工具一文所列的软件),但不应假设本课程中的信息会与你在比下列版本更高的软件中找到的内容完全一致。

建议在本课程中使用以下硬件和软件:

开始之前

  • 为了避免在生成此项目时遇到问题,强烈建议在根文件夹或接近根的文件夹中创建本教程中提到的项目(长文件夹路径会在生成时导致问题)。

  • 使用本教程中的代码,可从连接到电脑的默认麦克风设备进行录制。 请确保将默认麦克风设备设置为计划用于捕获语音的设备。

  • 若要使电脑能够启用听写,请转到“设置”>“隐私”>“语音、墨迹书写和键入”,然后选择“打开语音服务和键盘输入建议”按钮

  • 如果使用连接到(或内置到)头戴显示设备的麦克风和耳机,请确保在“设置”>“混合现实”>“音频和语音”中启用“佩戴头戴显示设备时切换到头戴显示设备麦克风”选项。

    Mixed reality settings

    Microphone setting

警告

请注意,如果针对此实验室的沉浸式头戴显示设备进行开发,可能会遇到音频输出设备问题。 这是由于 Unity 存在问题,该问题在更高版本的 Unity (Unity 2018.2) 中进行了修复。 该问题阻止 Unity 在运行时更改默认音频输出设备。 解决方法是确保已完成上述步骤,并在此问题出现时关闭并重新打开编辑器。

第 1 章 - Azure 门户

若要使用 Azure 翻译 API,需要将服务实例配置为可供应用程序使用。

  1. 登录到 Azure 门户

    注意

    如果你没有 Azure 帐户,需要创建一个。 如果你在课堂或实验室场景中跟着本教程学习,请让讲师或监督人员帮助设置你的新帐户。

  2. 登录后,单击左上角的“新建”,搜索“文本翻译 API”,并选择“Enter”

    New Resource

    注意

    在更新的门户中,“新建”一词可能已替换为“创建资源”

  3. 新页面会提供文本翻译 API 服务的说明。 在此页面的左下角,选择“创建”按钮,以创建与此服务的关联

    Create Translator Text API Service

  4. 单击“创建”后

    1. 插入此服务实例的所需名称

    2. 选择相应的订阅

    3. 选择合适的“定价层”。如果这是你首次创建文本翻译服务,系统会向你提供免费层(名为 F0)。

    4. 选择一个资源组或创建一个新资源组。 通过资源组,可监视和预配 Azure 资产集合、控制其访问权限并管理其计费。 建议保留与单个项目(例如通用资源组下的这些实验室)相关联的所有 Azure 服务。

      若要详细了解 Azure 资源组,请访问资源组一文。

    5. 为资源组确定位置(如果正在创建新的资源组)。 理想情况下,此位置在运行应用程序的区域中。 某些 Azure 资产仅在特定区域可用。

    6. 还需要确认了解应用于此服务的条款和条件。

    7. 选择创建

      Select Create button.

  5. 单击“创建”后,必须等待服务创建,这可能需要一分钟时间

  6. 创建服务实例后,门户中将显示一条通知。

    Azure Service creation notification

  7. 单击通知可浏览新的服务实例。

    Go to resource popup.

  8. 单击通知中的“转到资源”按钮,浏览新的服务实例。 你将访问新的文本翻译 API 服务实例。

    Translator Text API Service page

  9. 在本教程中,应用程序需要调用你的服务,这是使用服务的订阅密钥来完成的。

  10. 在文本翻译服务的“快速入门”页上,导航到第一步(“获取密钥”),然后单击“密钥”(也可单击服务导航菜单中由钥匙图标表示的蓝色“密钥”超链接来实现此操作)。 这将显示你的服务密钥

  11. 从显示的密钥中复制一个,稍后需要在项目中用到它。

第 2 章 - 设置 Unity 项目

设置并测试混合现实沉浸式头戴显示设备。

注意

本课程不需要运动控制器。 如果在设置沉浸式头戴显示设备方面需要支持,请执行这些步骤

下面是使用混合现实进行开发的典型设置,因此,这对其他项目来说是一个不错的模板:

  1. 打开 Unity,单击“新建”

    Start new Unity project.

  2. 现在需要提供 Unity 项目名称。 插入 MR_Translation。 确保将项目类型设置为“3D”。 将“位置”设置为适合你的位置(请记住,越接近根目录越好)。 然后,单击“创建项目”

    Provide details for new Unity project.

  3. 当 Unity 处于打开状态时,有必要检查默认“脚本编辑器”是否设置为“Visual Studio”。 转到“编辑”>“首选项”,然后在新窗口中导航到“外部工具”。 将外部脚本编辑器更改为 Visual Studio 2017。 关闭“首选项”窗口。

    Update script editor preference.

  4. 接下来,转到“文件”>“生成设置”,然后单击“切换平台”按钮将平台切换到“通用 Windows 平台”

    Build Settings window, switch platform to UWP.

  5. 转到“文件”>“生成设置”,并确保

    1. 将“目标设备”设置为“任何设备”

      对于 Microsoft HoloLens,请将“目标设备”设置为“HoloLens”

    2. 将“生成类型”设置为“D3D”

    3. 将“SDK”设置为“最新安装的版本”

    4. 将“Visual Studio 版本”设置为“最新安装的版本”

    5. 将“生成并运行”设置为“本地计算机”

    6. 保存场景并将其添加到生成。

      1. 通过选择“添加开放场景”来执行此操作。 将出现一个保存窗口。

        Click add open scenes button

      2. 为此创建新文件夹,并为将来的任何场景创建一个新文件夹,然后选择“新建文件夹”按钮以创建新文件夹,将其命名为“场景”

        Create new scripts folder

      3. 打开新创建的 Scenes 文件夹,然后在“文件名:”文本字段中键入 MR_TranslationScene,再按“保存”

        Give new scene a name.

        请注意,必须将 Unity 场景保存在 Assets 文件夹中,因为它们必须与 Unity 项目关联。 创建场景文件夹(和其他类似文件夹)是构建 Unity 项目的典型方式。

    7. 在“生成设置”中,其余设置目前应保留为默认值

  6. 在“生成设置”窗口中,单击“播放器设置”按钮,这会在检查器所在的空间中打开相关面板

    Open player settings.

  7. 在此面板中,需要验证一些设置:

    1. 在“其他设置”选项卡中

      1. “脚本运行时版本”应为“稳定”(.NET 3.5 等效版本)

      2. “脚本后端”应为 “.NET”

      3. “API 兼容性级别”应为“.NET 4.6”

        Update other settings.

    2. 在“发布设置”选项卡的“功能”下,检查以下内容

      1. InternetClient

      2. Microphone

        Updating publishing settings.

    3. 在面板再靠下部分,在“发布设置”下的“XR 设置”中,勾选“支持虚拟现实”,确保已添加“Windows Mixed Reality SDK”

      Update the X R Settings.

  8. 返回“生成设置”,此时 “Unity C#” 项目不再灰显;勾选此内容旁边的复选框

  9. 关闭“生成设置”窗口 。

  10. 保存场景和项目(“文件”>“保存场景/文件”>“保存项目”)

第3章 - 主摄像头设置

重要

如果想要跳过本课程的“Unity 设置”部分,直接学习代码,可下载此 .unitypackage,将其作为自定义包导入到项目中,然后从第 5 章继续学习。 仍然需要创建一个 Unity 项目。

  1. 在“层次结构面板”中,你会找到一个称为“主摄像头”的对象,一旦“进入”应用程序,此对象就代表你的“头部”视角

  2. 在你面前的 Unity 仪表板上,选择“主摄像头 GameObject”。 你会注意到,“检查器面板”(通常位于仪表板内的右侧)将显示该 GameObject 的各种组件(“转换”位于顶部,其次是“摄像头”和一些其他组件)。 需要重置主摄像头的转换,以便正确定位。

  3. 若要实现这一点,请选择摄像头“转换”组件旁边的齿轮图标,并选择“重置”

    Reset the Main Camera transform.

  4. “转换”组件应如下所示

    1. “位置”设置为“0, 0, 0”

    2. “旋转”设置为“0, 0, 0”

    3. “缩放”设置为“1, 1, 1”

      Transform information for Camera

  5. 接下来,在选择“主摄像头”对象的情况下,会看到检查器面板最底部的“添加组件”按钮

  6. 选择该按钮,然后搜索(可以在搜索栏中键入“音频源”,也可以在相应部分导航)名为“音频源”的组件(如下所示),并将其选中(也可以在它上面按 Enter)。

  7. “音频源”组件将添加到“主摄像头”,如下所示。

    Add an Audio Source component.

    注意

    对于 Microsoft HoloLens,你还需要进行以下更改,这些内容是“主摄像头”上的“摄像头”组件的一部分

    • 清除标志:纯色
    • 背景“黑色,Alpha 0”- 十六进制颜色:#00000000

第 4 章 - 设置调试画布

若要显示转换的输入和输出,需要创建一个基本 UI。 在本课程中,我们将创建一个“画布 UI”对象,其中包含多个“文本”对象来显示数据。

  1. 右键单击“层次结构面板”的空白区域,在“UI”下,添加一个画布

    Add new Canvas UI object.

  2. 选择“画布”对象后,在“检查器面板”(在“画布”组件内)中将“渲染模式”更改为“世界空间”。

  3. 接下来,在检查器面板的“矩形转换”中更改以下参数

    1. POS - X 0 Y 0 Z 40

    2. - 500

    3. - 300

    4. 缩放 - X 0.13 Y 0.13 Z 0.13

      Update the rect transform for the canvas.

  4. 右键单击“层次结构面板”中的“画布”,在“UI”下,添加一个面板。 此面板会提供将在场景中显示的文本的背景。

  5. 右键单击“层次结构面板”中的“面板”,在“UI”下,添加一个“文本”对象。 重复同一过程,直到总共创建了四个 UI 文本对象(提示:如果已选择第一个“文本”对象,则可以直接按 Ctrl + D 来复制它,直到总共有四个对象)。

  6. 对于每个文本对象,请选择它,然后使用下表在检查器面板中设置参数。

    1. “矩形转换”组件:

      名称 变换 - 位置 宽度 高度
      MicrophoneStatusLabel X -80 Y 90 Z 0 300 30
      AzureResponseLabel X -80 Y 30 Z 0 300 30
      DictationLabel X -80 Y -30 Z 0 300 30
      TranslationResultLabel X -80 Y -90 Z 0 300 30
    2. “文本(脚本)”组件:

      名称 文本 字体大小
      MicrophoneStatusLabel 麦克风状态: 20
      AzureResponseLabel Azure Web 响应 20
      DictationLabel 你刚才说: 20
      TranslationResultLabel 转换: 20

      Input the corresponding values for the UI labels.

    3. 另外,请将“字体样式”设置为“粗体”。 这会使文本更易于阅读。

      Bold Font.

  7. 对于第 5 章中创建的每个 UI 文本对象,请创建一个新的子 UI 文本对象。 这些子对象会显示应用程序的输出。 通过右键单击预期的父对象(例如 MicrophoneStatusLabel)来创建子对象,接着选择“UI”,然后选择“文本”。

  8. 对于每个这样的子对象,请选择它,然后使用下面的表在检查器面板中设置参数。

    1. “矩形转换”组件:

      名称 变换 - 位置 宽度 高度
      MicrophoneStatusText X 0 Y -30 Z 0 300 30
      AzureResponseText X 0 Y -30 Z 0 300 30
      DictationText X 0 Y -30 Z 0 300 30
      TranslationResultText X 0 Y -30 Z 0 300 30
    2. “文本(脚本)”组件:

      名称 文本 字体大小
      MicrophoneStatusText ?? 20
      AzureResponseText ?? 20
      DictationText ?? 20
      TranslationResultText ?? 20
  9. 接下来,选择每个文本组件的“中心”对齐选项:

    align text.

  10. 若要确保子 UI 文本对象易于阅读,请更改其颜色。 为此,请单击“颜色”旁边的条(目前为“黑色”)。

    Input corresponding values for the UI text outputs.

  11. 然后,在新的小“颜色”窗口中,将“十六进制颜色”更改为“0032EAFF”

    Update color to blue.

  12. UI 的外观应如下所示。

    1. 在“层次结构面板”中:

      Have hierarchy in the provided structure.

    2. 在“场景”和“游戏视图”中:

      Have the scene and game views in the same structure.

第 5 章 - 创建 Results 类

需要创建的第一个脚本是 Results 类,该类负责提供查看翻译结果的方法。 该类存储和显示以下内容:

  • 来自 Azure 的响应结果。
  • 麦克风状态。
  • 听写(语音到文本)结果。
  • 翻译结果。

若要创建此类,请执行以下操作:

  1. 右键单击“项目”面板,然后单击“创建”>“文件夹”。 将文件夹命名为“脚本”

    Create scripts folder.

    Open the scripts folder.

  2. 创建“Scripts”文件夹后,双击它以将其打开。 然后在该文件夹中,右键单击并选择“创建”>“C# 脚本”。 将脚本命名为“Results”

    Create the first script.

  3. 双击新的“Results”脚本以在 Visual Studio 中将其打开

  4. 插入以下命名空间:

        using UnityEngine;
        using UnityEngine.UI;
    
  5. 在类中插入以下变量:

        public static Results instance;
    
        [HideInInspector] 
        public string azureResponseCode;
    
        [HideInInspector] 
        public string translationResult;
    
        [HideInInspector] 
        public string dictationResult;
    
        [HideInInspector] 
        public string micStatus;
    
        public Text microphoneStatusText;
    
        public Text azureResponseText;
    
        public Text dictationText;
    
        public Text translationResultText;
    
  6. 然后添加 Awake() 方法,当类初始化时将调用该方法。

        private void Awake() 
        { 
            // Set this class to behave similar to singleton 
            instance = this;           
        } 
    
  7. 最后,添加负责将各种结果信息输出到 UI 的方法。

        /// <summary>
        /// Stores the Azure response value in the static instance of Result class.
        /// </summary>
        public void SetAzureResponse(string result)
        {
            azureResponseCode = result;
            azureResponseText.text = azureResponseCode;
        }
    
        /// <summary>
        /// Stores the translated result from dictation in the static instance of Result class. 
        /// </summary>
        public void SetDictationResult(string result)
        {
            dictationResult = result;
            dictationText.text = dictationResult;
        }
    
        /// <summary>
        /// Stores the translated result from Azure Service in the static instance of Result class. 
        /// </summary>
        public void SetTranslatedResult(string result)
        {
            translationResult = result;
            translationResultText.text = translationResult;
        }
    
        /// <summary>
        /// Stores the status of the Microphone in the static instance of Result class. 
        /// </summary>
        public void SetMicrophoneStatus(string result)
        {
            micStatus = result;
            microphoneStatusText.text = micStatus;
        }
    
  8. 返回到 Unity 之前,请务必在 Visual Studio 中保存所做的更改

第 6 章 - 创建 MicrophoneManager 类

要创建的第二个类是 MicrophoneManager

此类负责执行以下操作:

  • 检测连接到头戴显示设备或计算机的录音设备(以默认的为准)。
  • 捕获音频(语音),并使用听写将其存储为字符串。
  • 暂停语音后,将听写提交给 Translator 类。
  • 承载一个方法,该方法可以在需要时停止语音捕获。

若要创建此类,请执行以下操作:

  1. 双击“Scripts”文件夹将其打开

  2. 右键单击“脚本”文件夹,然后单击“创建”>“C# 脚本”。 将脚本命名为“MicrophoneManager”

  3. 双击此新脚本,在 Visual Studio 中将其打开。

  4. 在 MicrophoneManager 类的顶部,将命名空间更新为与以下内容相同

        using UnityEngine; 
        using UnityEngine.Windows.Speech;
    
  5. 然后,将以下变量添加到 MicrophoneManager 类中

        // Help to access instance of this object 
        public static MicrophoneManager instance; 
    
        // AudioSource component, provides access to mic 
        private AudioSource audioSource; 
    
        // Flag indicating mic detection 
        private bool microphoneDetected; 
    
        // Component converting speech to text 
        private DictationRecognizer dictationRecognizer; 
    
  6. 现在需要添加 Awake() 和 Start() 方法的代码。 类初始化时,将调用这些方法:

        private void Awake() 
        { 
            // Set this class to behave similar to singleton 
            instance = this; 
        } 
    
        void Start() 
        { 
            //Use Unity Microphone class to detect devices and setup AudioSource 
            if(Microphone.devices.Length > 0) 
            { 
                Results.instance.SetMicrophoneStatus("Initialising..."); 
                audioSource = GetComponent<AudioSource>(); 
                microphoneDetected = true; 
            } 
            else 
            { 
                Results.instance.SetMicrophoneStatus("No Microphone detected"); 
            } 
        } 
    
  7. 可以删除 Update() 方法,因为此类不会使用它

  8. 现在,你需要应用用于启动和停止语音捕获的方法,并将其传递给你即将构建的 Translator 类。 复制以下代码,并将其粘贴到 Start() 方法下。

        /// <summary> 
        /// Start microphone capture. Debugging message is delivered to the Results class. 
        /// </summary> 
        public void StartCapturingAudio() 
        { 
            if(microphoneDetected) 
            {               
                // Start dictation 
                dictationRecognizer = new DictationRecognizer(); 
                dictationRecognizer.DictationResult += DictationRecognizer_DictationResult; 
                dictationRecognizer.Start(); 
    
                // Update UI with mic status 
                Results.instance.SetMicrophoneStatus("Capturing..."); 
            }      
        } 
    
        /// <summary> 
        /// Stop microphone capture. Debugging message is delivered to the Results class. 
        /// </summary> 
        public void StopCapturingAudio() 
        { 
            Results.instance.SetMicrophoneStatus("Mic sleeping"); 
            Microphone.End(null); 
            dictationRecognizer.DictationResult -= DictationRecognizer_DictationResult; 
            dictationRecognizer.Dispose(); 
        }
    

    提示

    这里还提供了 StopCapturingAudio() 方法(尽管此应用程序不会使用它),这是考虑到你可能需要在应用程序中实现停止捕获音频的功能。

  9. 现在需要添加语音停止时要调用的听写处理程序。 此方法随后会将听写的文本传递到 Translator 类。

        /// <summary>
        /// This handler is called every time the Dictation detects a pause in the speech. 
        /// Debugging message is delivered to the Results class.
        /// </summary>
        private void DictationRecognizer_DictationResult(string text, ConfidenceLevel confidence)
        {
            // Update UI with dictation captured
            Results.instance.SetDictationResult(text);
    
            // Start the coroutine that process the dictation through Azure 
            StartCoroutine(Translator.instance.TranslateWithUnityNetworking(text));   
        }
    
  10. 返回到 Unity 之前,请务必在 Visual Studio 中保存所做的更改。

警告

此时,你会注意到在 Unity 编辑器控制台面板中出现了错误(“名称 ‘Translator’ 不存在...”)。 这是因为代码引用了将在下一章中创建的 Translator 类

第 7 章 - 调用 Azure 和翻译服务

需要创建的最后一个脚本是 Translator 类

此类负责执行以下操作:

  • 使用 Azure 对应用进行身份验证,以获取身份验证令牌
  • 使用身份验证令牌提交要翻译的文本(从 MicrophoneManager 类接收)。
  • 接收翻译后的结果,并将其传递到要在 UI 中可视化的 Results 类。

若要创建此类,请执行以下操作:

  1. 转到之前创建的“脚本”文件夹

  2. 右键单击“项目”面板,然后单击“创建”>“C# 脚本”。 将脚本命名为“Translator”

  3. 双击新的 Translator 脚本以通过 Visual Studio 打开它

  4. 将以下命名空间添加到 文件顶部:

        using System;
        using System.Collections;
        using System.Xml.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. 然后将以下变量添加到 Translator 类中

        public static Translator instance; 
        private string translationTokenEndpoint = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken"; 
        private string translationTextEndpoint = "https://api.microsofttranslator.com/v2/http.svc/Translate?"; 
        private const string ocpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key"; 
    
        //Substitute the value of authorizationKey with your own Key 
        private const string authorizationKey = "-InsertYourAuthKeyHere-"; 
        private string authorizationToken; 
    
        // languages set below are: 
        // English 
        // French 
        // Italian 
        // Japanese 
        // Korean 
        public enum Languages { en, fr, it, ja, ko }; 
        public Languages from = Languages.en; 
        public Languages to = Languages.it; 
    

    注意

    • 插入语言 enum 中的语言只是示例。 可以根据需要随意添加更多内容;此 API 支持 60 多种语言(包括 Klingon)!
    • 还有一个涵盖可用语言的交互程度更高的页面,但请注意的是,只有在站点语言设置为“en-us”(Microsoft 网站可能会重定向到你的母语)时,此页才正常显示。 可以在页面底部更改站点语言,也可以通过更改 URL 来这样做。
    • 在上述代码片段中,authorizationKey 值必须是在订阅 Azure 文本翻译 API 时收到的密钥。 第 1 章对此进行了介绍。
  6. 现在需要添加 Awake() 和 Start() 方法的代码

  7. 在这种情况下,代码将使用授权密钥调用 Azure 以获取令牌。

        private void Awake() 
        { 
            // Set this class to behave similar to singleton  
            instance = this; 
        } 
    
        // Use this for initialization  
        void Start() 
        { 
            // When the application starts, request an auth token 
            StartCoroutine("GetTokenCoroutine", authorizationKey); 
        }
    

    注意

    该令牌会在 10 分钟后过期。 根据应用的方案,可能需要多次进行相同的协同例程调用。

  8. 用于获取令牌的协同例程如下所示:

        /// <summary> 
        /// Request a Token from Azure Translation Service by providing the access key. 
        /// Debugging result is delivered to the Results class. 
        /// </summary> 
        private IEnumerator GetTokenCoroutine(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new InvalidOperationException("Authorization key not set.");
            }
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Post(translationTokenEndpoint, string.Empty))
            {
                unityWebRequest.SetRequestHeader("Ocp-Apim-Subscription-Key", key);
                yield return unityWebRequest.SendWebRequest();
    
                long responseCode = unityWebRequest.responseCode;
    
                // Update the UI with the response code 
                Results.instance.SetAzureResponse(responseCode.ToString());
    
                if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
                {
                    Results.instance.azureResponseText.text = unityWebRequest.error;
                    yield return null;
                }
                else
                {
                    authorizationToken = unityWebRequest.downloadHandler.text;
                }
            }
    
            // After receiving the token, begin capturing Audio with the MicrophoneManager Class 
            MicrophoneManager.instance.StartCapturingAudio();
        }
    

    警告

    如果编辑 IEnumerator 方法 GetTokenCoroutine () 的名称,则需要更新以上代码中的 StartCoroutine 和 StopCoroutine 调用字符串值。 按照 Unity 文档,若要停止特定的协同例程,需要使用字符串值方法。

  9. 接下来,添加协同例程(其正下方有一个“support”流方法),以获取 MicrophoneManager 类收到的文本的翻译。 此代码将创建一个要发送到 Azure 文本翻译 API 的查询字符串,然后使用内部 Unity UnityWebRequest 类通过查询字符串对终结点进行“Get”调用。 然后,使用该结果在“结果”对象中设置翻译。 下面的代码显示了实现:

        /// <summary> 
        /// Request a translation from Azure Translation Service by providing a string.  
        /// Debugging result is delivered to the Results class. 
        /// </summary> 
        public IEnumerator TranslateWithUnityNetworking(string text)
        {
            // This query string will contain the parameters for the translation 
            string queryString = string.Concat("text=", Uri.EscapeDataString(text), "&from=", from, "&to=", to);
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(translationTextEndpoint + queryString))
            {
                unityWebRequest.SetRequestHeader("Authorization", "Bearer " + authorizationToken);
                unityWebRequest.SetRequestHeader("Accept", "application/xml");
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
                {
                    Debug.Log(unityWebRequest.error);
                    yield return null;
                }
    
                // Parse out the response text from the returned Xml
                string result = XElement.Parse(unityWebRequest.downloadHandler.text).Value;
                Results.instance.SetTranslatedResult(result);
            }
        }
    
  10. 返回到 Unity 之前,请务必在 Visual Studio 中保存所做的更改

第 8 章 - 配置 Unity 场景

  1. 返回 Unity 编辑器,单击“Scripts”文件夹中的“Results”类,并将其拖放到“层次结构”面板中的“主摄像头”对象中

  2. 单击“主相机”并查看“检查器”面板。 你会发现,在新添加的 Script 组件中,有四个包含空值的字段。 这些是对代码中的属性的输出引用。

  3. 将相应的“Text”对象从“层次结构”面板拖放到这四个槽中,如下图所示

    Update target references with specified values.

  4. 接下来,单击“Scripts”文件夹中的 Translator 类 ,并将其拖到“层次结构”面板中的“主相机”对象

  5. 然后,单击“Scripts”文件夹中的 MicrophoneManager 类 ,并将其拖到“层次结构”面板中的“主摄像头”对象

  6. 最后,单击“主摄像头”并查看“检查器”面板。 你会注意到,在进行拖动操作时所在的脚本中,有两个下拉框可用于设置语言。

    Ensure the intended translation languages are input.

第 9 章 - 在混合现实中测试

此时,需要测试场景是否已正确实现。

请确保:

  • 第 1 章所述的所有设置均已正确设置。
  • Results、Translator 和 MicrophoneManager 的脚本已附加到“主摄像头”对象。
  • 已将 Azure 文本翻译 API 服务密钥置于 Translator 脚本的 authorizationKey 变量中。
  • 已正确分配主摄像头检查器面板中的所有字段
  • 麦克风在运行场景时工作(如果不工作,请检查连接的麦克风是否为默认设备,以及你是否已在 Windows 中正确设置麦克风)。

可以通过在 Unity 编辑器中按“播放”按钮来测试沉浸式头戴显示设备。 该应用应该可以通过附加的沉浸式头戴显示设备来运行。

警告

如果在 Unity 控制台中看到一个指示默认音频设备有变化的错误,则场景可能无法按预期方式工作。 这是混合现实门户处理带内置麦克风的头戴显示设备的内置麦克风的方式造成的。 如果看到此错误,只需停止场景并再次启动它,然后一切就会按预期方式工作。

第 10 章 - 在本地计算机上生成 UWP 解决方案和进行旁加载

此项目的 Unity 部分所需的一切现已完成,接下来要从 Unity 生成它。

  1. 导航到“生成设置”:“文件”>“生成设置…”

  2. 在“生成设置”窗口中,单击“生成”

    Build the Unity scene.

  3. 如果尚未勾选“Unity C# 项目”,请勾选

  4. 单击“生成”。 Unity 将启动“文件资源管理器”窗口,你需要在其中创建并选择一个文件夹来生成应用。 现在创建该文件夹,并将其命名为“应用”。 选择“应用”文件夹,然后按“选择文件夹”

  5. Unity 将开始将项目生成到“应用”文件夹

  6. Unity 完成生成(可能需要一些时间)后,会在生成位置打开“文件资源管理器”窗口(检查任务栏,因为它可能不会始终显示在窗口上方,但会通知你增加了一个新窗口)

第 11 章 - 部署应用程序

若要部署应用程序,请执行以下操作:

  1. 导航到新的 Unity 生成(“应用”文件夹)并使用 Visual Studio 打开解决方案文件

  2. 在“解决方案配置”中,选择“调试”

  3. 在“解决方案平台”中,选择“x86,本地计算机”

    对于 Microsoft HoloLens,你可能会发现,将此选项设置为“远程计算机”会更容易,这样你就不会受限于你的计算机。 不过,还需要执行以下操作:

    • 了解 HoloLens 的 IP 地址,该地址可通过“设置”>“网络和 Internet”>“Wi-Fi”>“高级选项”找到;应使用 IPv4 地址
    • 确保将“开发人员模式”设置为“开”,可通过“设置”>“更新和安全”>“适用于开发人员”找到它

    Deploy the solution from Visual Studio.

  4. 转到“生成”菜单,单击“部署解决方案”,以将应用程序旁加载到电脑

  5. 应用现在应显示在已安装的应用列表中,随时可以启动。

  6. 启动后,应用会提示你授予其对麦克风的访问权限。 请确保单击“是”按钮。

  7. 你现在已准备好开始翻译!

你已完成文本翻译 API 应用程序

恭喜,你已构建混合现实应用!它利用 Azure 文本翻译 API 将语音转换为翻译的文本。

Final product.

额外练习

练习 1

是否可以向应用添加文本转语音功能,使返回的文本被朗读出来?

练习 2

使用户能够在应用中更改源语言和输出语言,这样,当你每次需要更改语言时,就无需重新生成应用。