Unity C# 之 Azure 微軟SSML語音合成TTS流式獲取音頻數(shù)據(jù)以及表情嘴型 Animation 的簡單整理
目錄
Unity C# 之 Azure 微軟SSML語音合成TTS流式獲取音頻數(shù)據(jù)以及表情嘴型 Animation 的簡單整理
一、簡單介紹
二、實現(xiàn)原理
三、注意事項
四、實現(xiàn)步驟
五、關鍵代碼
一、簡單介紹
Unity 工具類,自己整理的一些游戲開發(fā)可能用到的模塊,單獨獨立使用,方便游戲開發(fā)。
本節(jié)介紹,這里在使用微軟的Azure 使用SSML進行SS語音合成的音頻,并且獲取表情嘴型Animation 數(shù)據(jù),并且保存到本地,在特定的情況下,用于本地讀取音頻和表情嘴型Animation 數(shù)據(jù),直接使用,避免可能網(wǎng)絡訪問造成的延遲問題,這里簡單說明,如果你有更好的方法,歡迎留言交流。
語音合成標記語言 (SSML) 是一種基于 XML 的標記語言,可用于微調文本轉語音輸出屬性,例如音調、發(fā)音、語速、音量等。 與純文本輸入相比,你擁有更大的控制權和靈活性。
可以使用 SSML 來執(zhí)行以下操作:
- ??? 定義輸入文本結構,用于確定文本轉語音輸出的結構、內(nèi)容和其他特征。 例如,可以使用 SSML 來定義段落、句子、中斷/暫?;蜢o音。 可以使用事件標記(例如書簽或視素)來包裝文本,這些標記可以稍后由應用程序處理。
- ??? 選擇語音、語言、名稱、樣式和角色。 可以在單個 SSML 文檔中使用多個語音。 調整重音、語速、音調和音量。 還可以使用 SSML 插入預先錄制的音頻,例如音效或音符。
- ??? 控制輸出音頻的發(fā)音。 例如,可以將 SSML 與音素和自定義詞典配合使用來改進發(fā)音。 還可以使用 SSML 定義單詞或數(shù)學表達式的具體發(fā)音。
?下面是 SSML 文檔的基本結構和語法的子集:
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="string"> <mstts:backgroundaudio src="string" volume="string" fadein="string" fadeout="string"/> <voice name="string" effect="string"> <audio src="string"></audio> <bookmark mark="string"/> <break strength="string" time="string" /> <emphasis level="value"></emphasis> <lang xml:lang="string"></lang> <lexicon uri="string"/> <math xmlns="http://www.w3.org/1998/Math/MathML"></math> <mstts:audioduration value="string"/> <mstts:express-as style="string" styledegree="value" role="string"></mstts:express-as> <mstts:silence type="string" value="string"/> <mstts:viseme type="string"/> <p></p> <phoneme alphabet="string" ph="string"></phoneme> <prosody pitch="value" contour="value" range="value" rate="value" volume="value"></prosody> <s></s> <say-as interpret-as="string" format="string" detail="string"></say-as> <sub alias="string"></sub> </voice> </speak>
?SSML 語音和聲音
語音合成標記語言 (SSML) 的語音和聲音 - 語音服務 - Azure AI services | Microsoft Learn
官網(wǎng)注冊:
面向學生的 Azure - 免費帳戶額度 | Microsoft Azure
官網(wǎng)技術文檔網(wǎng)址:
技術文檔 | Microsoft Learn
官網(wǎng)的TTS:
文本轉語音快速入門 - 語音服務 - Azure Cognitive Services | Microsoft Learn
Azure Unity SDK? 包官網(wǎng):
安裝語音 SDK - Azure Cognitive Services | Microsoft Learn
SDK具體鏈接:
https://aka.ms/csspeech/unitypackage
?文章來源地址http://www.zghlxwxcb.cn/news/detail-652289.html
二、實現(xiàn)原理
1、官網(wǎng)申請得到語音合成對應的 SPEECH_KEY 和 SPEECH_REGION
2、然后對應設置 語言 和需要的聲音 配置
3、使用 SSML 帶有流式獲取得到音頻數(shù)據(jù),在聲源中播放或者保存即可,樣例如下
public static async Task SynthesizeAudioAsync()
{
var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
var ssml = File.ReadAllText("./ssml.xml");
var result = await speechSynthesizer.SpeakSsmlAsync(ssml);
using var stream = AudioDataStream.FromResult(result);
await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}
4、本地保存音頻,以及表情嘴型 Animation 數(shù)據(jù)
// 獲取到視頻的數(shù)據(jù),保存為 .wav
using var stream = AudioDataStream.FromResult(speechSynthesisResult);
await stream.SaveToWaveFileAsync($"./{fileName}.wav");
/// <summary>
/// 嘴型 animation 數(shù)據(jù),本地保存為 json 數(shù)據(jù)
/// </summary>
/// <param name="fileName">保存文件名</param>
/// <param name="content">保存內(nèi)容</param>
/// <returns></returns>
static async Task CommitAsync(string fileName,string content)
{
var bits = Encoding.UTF8.GetBytes(content);
using (var fs = new FileStream(
path: @$"d:\temp\{fileName}.json",
mode: FileMode.Create,
access: FileAccess.Write,
share: FileShare.None,
bufferSize: 4096,
useAsync: true))
{
await fs.WriteAsync(bits, 0, bits.Length);
}
}
三、注意事項
1、不是所有的 speechSynthesisVoiceName 都能生成對應的 表情嘴型 Animation 數(shù)據(jù)
四、實現(xiàn)步驟
這里是直接使用 .Net VS 中進行代碼測試
1、在 NuGet 中安裝 微軟的 Speech 包
?2、代碼編寫實現(xiàn) SSML 合成語音,并且本地保存對應的 音頻文件和表情嘴型 Animation json 數(shù)據(jù)
3、運行代碼,運行完后,就會本地保存對應的 音頻文件和表情嘴型 Animation json 數(shù)據(jù)
?
?4、本地查看保存的數(shù)據(jù)
文章來源:http://www.zghlxwxcb.cn/news/detail-652289.html
?
五、關鍵代碼
using Microsoft.CognitiveServices.Speech;
using System.Text;
class Program
{
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
static string speechKey = "YOUR_SPEECH_KEY";
static string speechRegion = "YOUR_SPEECH_REGION";
static string speechSynthesisVoiceName = "zh-CN-XiaoxiaoNeural";
static string fileName = "Test" + "Hello";
static string InputAudioContent = "黃河之水天上來,奔流到海不復回"; // 生成的
static int index = 0; // 記錄合成的表情口型動畫的數(shù)據(jù)數(shù)組個數(shù)
static string content="["; // [ 是為了組成 json 數(shù)組
async static Task Main(string[] args)
{
var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
// 根據(jù)需要可以使用更多 xml 配置,讓合成的聲音更加生動立體
var ssml = @$"<speak version='1.0' xml:lang='zh-CN' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name='{speechSynthesisVoiceName}'>
<mstts:viseme type='FacialExpression'/>
<mstts:express-as style='friendly'>{InputAudioContent}</mstts:express-as>
</voice>
</speak>";
// Required for sentence-level WordBoundary events
speechConfig.SetProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");
using (var speechSynthesizer = new SpeechSynthesizer(speechConfig))
{
// Subscribe to events
// 注冊表情嘴型數(shù)據(jù)
speechSynthesizer.VisemeReceived += async (s, e) =>
{
Console.WriteLine($"VisemeReceived event:" +
$"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms"
+ $"\r\n\tVisemeId: {e.VisemeId}"
// + $"\r\n\tAnimation: {e.Animation}"
);
if (string.IsNullOrEmpty( e.Animation)==false)
{
// \r\n, 是為了組合 json 格式
content += e.Animation + "\r\n,";
index++;
}
};
// 注冊合成完畢的事件
speechSynthesizer.SynthesisCompleted += async (s, e) =>
{
Console.WriteLine($"SynthesisCompleted event:" +
$"\r\n\tAudioData: {e.Result.AudioData.Length} bytes" +
$"\r\n\tindex: {index} " +
$"\r\n\tAudioDuration: {e.Result.AudioDuration}");
content = content.Substring(0, content.Length-1);
content += "]";
await CommitAsync(fileName, content);
};
// Synthesize the SSML
Console.WriteLine($"SSML to synthesize: \r\n{ssml}");
var speechSynthesisResult = await speechSynthesizer.SpeakSsmlAsync(ssml);
// 獲取到視頻的數(shù)據(jù),保存為 .wav
using var stream = AudioDataStream.FromResult(speechSynthesisResult);
await stream.SaveToWaveFileAsync(@$"d:\temp\{fileName}.wav");
// Output the results
switch (speechSynthesisResult.Reason)
{
case ResultReason.SynthesizingAudioCompleted:
Console.WriteLine("SynthesizingAudioCompleted result");
break;
case ResultReason.Canceled:
var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult);
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
}
break;
default:
break;
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
/// <summary>
/// 嘴型 animation 數(shù)據(jù),本地保存為 json 數(shù)據(jù)
/// </summary>
/// <param name="fileName">保存文件名</param>
/// <param name="content">保存內(nèi)容</param>
/// <returns></returns>
static async Task CommitAsync(string fileName,string content)
{
var bits = Encoding.UTF8.GetBytes(content);
using (var fs = new FileStream(
path: @$"d:\temp\{fileName}.json",
mode: FileMode.Create,
access: FileAccess.Write,
share: FileShare.None,
bufferSize: 4096,
useAsync: true))
{
await fs.WriteAsync(bits, 0, bits.Length);
}
}
}
到了這里,關于Unity C# 之 Azure 微軟SSML語音合成TTS流式獲取音頻數(shù)據(jù)以及表情嘴型 Animation 的簡單整理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!