语音翻译服务
分类: Azure认知服务 ◆ 标签: #Azure #人工智能 #语音服务 ◆ 发布于: 2023-06-05 16:58:20

大家知道有一个职业叫翻译
, 特别是同时翻译
非常吃香也非常厉害,但是如果人工智能能够更快速的发展的话,那么同时翻译
这个职业就会很快的消失了,我们今天来介绍一下我们Azure语音服务的另外一个功能就是语音翻译,字面意思就是可以实时的,多设备的将一种语言的语音及时转移成另外一种语音的语音,例如输入时英文语音但是输出时中文语音,而且时实时的,这就是机器的同声翻译。
本节Demo代码可以从这里下载: Demo Code
创建语音翻译项目
我们先创建一个基于控制台的项目,同时向项目添加引用包:
dotnet new console -n SpeechTranslation
cd SpeechTranslation
dotnet add package Microsoft.CognitiveServices.Speech
添加了包引用之后,我们可以使用编辑器或者IDE打开该项目,同时编辑Program.cs
, 添加如下的包引用:
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using Microsoft.CognitiveServices.Speech; using Microsoft.CognitiveServices.Speech.Audio; using Microsoft.CognitiveServices.Speech.Translation;
SpeechTranslationConfig 对象
我们前面的语音识别服务和语音合成服务,在开始使用SDK之前,我们都需要创建一个SpeechConfig
对象,但是对于语音翻译服务来讲我们需要的配置对象是``SpeechTranslationConfig, 我们通过这个配置对象来配置SDK并进行响应的服务调用,同时需要注意的是我们任然需要创建服务的
key和
region`, 因此我们先定义两个常量:
//服务的Key private static readonly string SPEECH__SUBSCRIPTION__KEY = ""; //服务的区域 private static readonly string SPEECH__SERVICE__REGION = "";
然后我们在方法Main
中定义一个配置对象,然后可以从Main
方法中对定义的其他方法进行调用,并传入该方法参数。
var config = SpeechTranslationConfig.FromSubscription(SPEECH__SUBSCRIPTION__KEY, SPEECH__SERVICE__REGION);
语音翻译成文本
我们之前学习过如何通过语音转文本,但是我们这个功能是从语音,翻译成你指定的语言文本。
设置语音源的语言
我们先需要设定来源语音的语言,例如中文
, 英语
等等,设定源语音还是通过配置对象SpeechTranslationConfig
对象来完成。
config.SpeechRecognitionLanguage = 'zh-CN';
设置需要翻译的结果语言
同样我们还是通过配置对象来设置目标语音,同时需要注意的是我们可以设置多个目标语言,例如可以将中文同时翻译成英语,德语,法语等等。
config.AddTargetLanguage("en-US"); config.AddTargetLanguage("de");
如果需要添加多个语言多次调用方法AddTargetLanguage
就可以了。您可以定义一个列表类型List<String>
, 然后使用ForEach
就可以一次全部加好,例如:
var langList = new List<String> { "en-US", "de", "fr" }; langList.ForEach(config.AddTargetLanguage);
这样就可以一次性添加好所有需要的语言了。
从麦克风输入并翻译
从麦克风进行输入的话,有两种形式,一种是不用指定AudioConfig
, 默认就会从麦克风进行输入,并翻译, 另外一种情况是指明AudioConfig
,然后使用该类的方法FromDefaultMicrophoneInput
从默认的麦克风进行输入,另外可以可以使用前一章的知识,找到多个麦克风,选择麦克风的ID,然后从对应的麦克风进行读入。
我们先来看默认的方式:
public async static Task TranslationFromMic(SpeechTranslationConfig config, string sourceLang, List<string> targetLanguage) { //设置源语言 config.SpeechRecognitionLanguage = sourceLang; //设置目的语言 targetLanguage.ForEach(config.AddTargetLanguage); using var recognizer = new TranslationRecognizer(config); Console.Write($"Say something in '{sourceLang}' and "); Console.WriteLine($"We will translate into '{string.Join("', '", targetLanguage)}'.\n "); var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { Console.WriteLine($"Recognized:\"{result.Text}\"; "); foreach (var (language, translation) in result.Translations) { Console.WriteLine($"Translated into '{language}': {translation} "); } } }
从代码可以看出无需指定AudioConfig
默认就会从默认的麦克风进行输入了。如果我们需要明确的指定从麦克风输入该如何处理呢?我们可以按照下面的代码进行处理:
public async static Task TranslationFromMic2(SpeechTranslationConfig config, string sourceLang, List<string> targetLanguage) { //设置源语言 config.SpeechRecognitionLanguage = sourceLang; //设置目的语言 targetLanguage.ForEach(config.AddTargetLanguage); using var audioConfig = AudioConfig.FromDefaultMicrophoneInput(); using var recognizer = new TranslationRecognizer(config, audioConfig); Console.Write($"Say something in '{sourceLang}' and "); Console.WriteLine($"We will translate into '{string.Join("', '", targetLanguage)}'.\n "); var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { Console.WriteLine($"Recognized:\"{result.Text}\"; "); foreach (var (language, translation) in result.Translations) { Console.WriteLine($"Translated into '{language}': {translation} "); } } }
从代码中可以看出我们首先需要创建一个AudioConfig
的对象,然后使用该对象的方法FromDefaultMicrophoneInput
返回一个Audio的配置,最后我们在创建翻译对象的时候,同时传入两个配置:
using var recognizer = new TranslationRecognizer(config, audioConfig);
这样就可以从麦克风中输入音频流了,然后回翻译成相应的文字。
从文件中读入音频流进行翻译
上述我们简要的介绍了如何从麦克风中输入,我们想从文件中进行输入,该如何处理呢?原理上很简单,我们还是需要创建一个AudioConfig
的对象,然后使用该对象的方法FromWaveFileInput
指定输入的文件就可以了。
public async static Task TranslationFromFile(SpeechTranslationConfig config, string sourceLang, List<string> targetLanguage) { //设置源语言 config.SpeechRecognitionLanguage = sourceLang; //设置目的语言 targetLanguage.ForEach(config.AddTargetLanguage); using var audioConfig = AudioConfig.FromWavFileInput("1.wav"); using var recognizer = new TranslationRecognizer(config, audioConfig); Console.Write($"Say something in '{sourceLang}' and "); Console.WriteLine($"We will translate into '{string.Join("', '", targetLanguage)}'.\n "); var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { Console.WriteLine($"Recognized:\"{result.Text}\"; "); foreach (var (language, translation) in result.Translations) { Console.WriteLine($"Translated into '{language}': {translation} "); } } }
支持将音频翻译成文字我们介绍完了,下面我们接着介绍如何将音频翻译成另外语言的音频。
语音翻译成其他语言的语音(Speech-to-Speech)
现在我们介绍真正的"同声翻译"了。例如将英语音频翻译成中文音频或者德文音频等等。
目前有两种方式实现这个功能:
- 监听
TranslationRecognizer
的Synthesizing
事件。 - 手动使用文本转语音的功能进行转换。
功能上说起来很简单,直接看代码就可以了。
监听TranslationRecognizer
的Synthesizing
事件
代码如下:
//通过事件来翻译到语音,注意如果是通过事件来翻译的话,目的语言只能单个,不能添加多个语言。 public async static Task TranslationToSpeechByEvent(SpeechTranslationConfig config, string sourceLang, string targetLanguage, string targetVoiceName) { //设置源语言 config.SpeechRecognitionLanguage = sourceLang; //设置目的语言 config.AddTargetLanguage(targetLanguage); //设置需要转换的语言 config.VoiceName = targetVoiceName; using var recognizer = new TranslationRecognizer(config); Console.Write($"Say something in '{sourceLang}' and "); Console.WriteLine($"We will translate into '{string.Join("', '", targetLanguage)}'.\n "); //定义事件来对语音进行翻译 recognizer.Synthesizing += (_, e) => { var audio = e.Result.GetAudio(); Console.WriteLine($"Audio synthesized: {audio.Length:#,0} byte(s) {(audio.Length == 0 ? "(Complete)" : "")}"); if (audio.Length > 0) { File.WriteAllBytes($"translation-{targetVoiceName}.wav", audio); } }; var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { Console.WriteLine($"Recognized:\"{result.Text}\"; "); foreach (var (language, translation) in result.Translations) { Console.WriteLine($"Translated into '{language}': {translation} "); } } }
这段代码非常好理解,主要的部分就在于如何监听事件。
注意
使用事件来进行语音翻译,不支持多语言转换,因此只能从一种语言翻译到另外一种语言,但是手动就可以实现一种语言翻译成多种语言。
手动使用文本转语音的SDK
这个部分理解是非常容易的,还是老规矩,看如下的代码:
public async static Task TranslationToSpeechByManual(SpeechTranslationConfig config, string sourceLang, List<string> targetLanguage) { //设置源语言 config.SpeechRecognitionLanguage = sourceLang; //设置目的语言 targetLanguage.ForEach(config.AddTargetLanguage); using var recognizer = new TranslationRecognizer(config); Console.Write($"Say something in '{sourceLang}' and "); Console.WriteLine($"We will translate into '{string.Join("', '", targetLanguage)}'.\n "); var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { // See: https://aka.ms/speech/sdkregion#standard-and-neural-voices var languageToVoiceMap = new Dictionary<string, string> { ["de"] = "de-DE-KatjaNeural", ["en"] = "en-US-AriaNeural", ["it"] = "it-IT-ElsaNeural", ["pt"] = "pt-BR-FranciscaNeural", ["zh-Hans"] = "zh-CN-XiaoxiaoNeural" }; Console.WriteLine($"Recognized: \"{result.Text}\""); foreach (var (language, translation) in result.Translations) { Console.WriteLine($"Translated into '{language}': {translation}"); var speechConfig = SpeechConfig.FromSubscription( SPEECH__SUBSCRIPTION__KEY, SPEECH__SERVICE__REGION); speechConfig.SpeechSynthesisVoiceName = languageToVoiceMap[language]; using var audioConfig = AudioConfig.FromWavFileOutput($"{language}-translation.wav"); using var synthesizer = new SpeechSynthesizer(speechConfig, audioConfig); await synthesizer.SpeakTextAsync(translation); } } }
好了语音翻译就简要的介绍到这里了。