你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
如何将文本转语音头像与实时合成配合使用
本操作指南介绍如何将文本转语音虚拟形象与实时合成配合使用。 系统收到文本输入后,将几乎实时地生成合成虚拟形象视频。
先决条件
若要开始,请确保满足以下先决条件:
- Azure 订阅:免费创建一个订阅。
- 语音资源:在 Microsoft Azure 门户中创建语音资源。 如果要创建语音资源来访问虚拟形象,请选择“标准 S0”定价层。
- 你的语音资源密钥和区域:部署语音资源后,选择“转到资源”以查看和管理密钥。
设置环境
若要进行实时虚拟形象合成,需要安装适用于 JavaScript 的语音SDK 才能与网页一起使用。 有关安装说明,请参阅安装语音 SDK。
下面是不同平台和浏览器上实时虚拟形象的兼容性:
平台 | Chrome | Microsoft Edge | Safari | Firefox | Opera |
---|---|---|---|---|---|
Windows | Y | Y | 不可用 | 是1 | Y |
Android | Y | Y | 不可用 | Y12 | N |
iOS | Y | Y | Y | Y | Y |
macOS | Y | Y | Y | 是1 | Y |
1 它不适用于通信服务的 ICE 服务器,但适用于 Coturn。
2 背景透明度不起作用。
选择文本转语音语言和语音
语音服务中的文本转语音功能支持广泛的语言和语音组合。 你可以获取完整列表,或在语音库中试用它们。
指定 SpeechConfig
的语言或语音,使其与输入文本匹配,并使用指定的语音。 以下代码片段显示了此技术的工作原理:
const speechConfig = SpeechSDK.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.speechSynthesisLanguage = "en-US";
speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
所有神经网络声音都是多语言的,并且能够流利地使用自己的语言和英语。 例如,如果英语的输入文本为“I'm excited to try text to speech”并且你选择了 es-ES-ElviraNeural,则该文本将用带西班牙口音的英语讲出。
如果语音没有使用输入文本的语言讲出,则语音服务不会创建合成音频。 有关支持的神经语音的完整列表,请参阅语音服务的语言和语音支持。
默认语音是从语音列表 API 根据区域设置返回的第一个语音。 语音的先后次序如下:
- 如果未设置
SpeechSynthesisVoiceName
或SpeechSynthesisLanguage
,则会讲en-US
的默认语音。 - 如果仅设置了
SpeechSynthesisLanguage
,则会讲指定区域设置的默认语音。 - 如果同时设置了
SpeechSynthesisVoiceName
和SpeechSynthesisLanguage
,则会忽略SpeechSynthesisLanguage
设置。 系统会讲你使用SpeechSynthesisVoiceName
指定的语音。 - 如果使用语音合成标记语言 (SSML) 设置了 voice 元素,则会忽略
SpeechSynthesisVoiceName
和SpeechSynthesisLanguage
设置。
选择虚拟形象角色和风格
可在此处找到支持的虚拟形象角色和风格。
以下代码片段演示了如何设置虚拟形象角色和风格:
const avatarConfig = new SpeechSDK.AvatarConfig(
"lisa", // Set avatar character here.
"casual-sitting", // Set avatar style here.
);
设置与实时虚拟形象的连接
实时虚拟形象使用 WebRTC 协议输出虚拟形象视频流。 需要通过 WebRTC 对等连接设置与虚拟形象服务的连接。
首先,需要创建 WebRTC 对等连接对象。 WebRTC 是一种 P2P 协议,它依赖于 ICE 服务器进行网络中继。 语音服务提供网络中继功能,并公开 REST API 以发出 ICE 服务器信息。 因此,建议从语音服务中提取 ICE 服务器。 还可以选择使用自己的 ICE 服务器。
下面是从语音服务终结点提取 ICE 信息的示例请求:
GET /cognitiveservices/avatar/relay/token/v1 HTTP/1.1
Host: westus2.tts.speech.microsoft.com
Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY
以下代码片段演示如何创建 WebRTC 对等连接。 ICE 服务器 URL、ICE 服务器用户名和 ICE 服务器凭据都可以从上述 HTTP 请求的有效负载中提取。
// Create WebRTC peer connection
peerConnection = new RTCPeerConnection({
iceServers: [{
urls: [ "Your ICE server URL" ],
username: "Your ICE server username",
credential: "Your ICE server credential"
}]
})
注意
ICE 服务器 URL 有两种类型:一种具有前缀 turn
(如 turn:relay.communication.microsoft.com:3478
),一种具有前缀 stun
(如 stun:relay.communication.microsoft.com:3478
)。 在前面的示例方案中,对于 urls
,只需包含带有 turn
前缀的 URL。
其次,需要在对等连接的 ontrack
回调函数中设置视频和音频播放器元素。 此回调在连接期间调用两次,一次用于视频音轨,一次用于音频音轨。需要在回调函数中创建视频和音频播放器元素。
以下代码片段演示了如何执行此操作:
// Fetch WebRTC video/audio streams and mount them to HTML video/audio player elements
peerConnection.ontrack = function (event) {
if (event.track.kind === 'video') {
const videoElement = document.createElement(event.track.kind)
videoElement.id = 'videoPlayer'
videoElement.srcObject = event.streams[0]
videoElement.autoplay = true
}
if (event.track.kind === 'audio') {
const audioElement = document.createElement(event.track.kind)
audioElement.id = 'audioPlayer'
audioElement.srcObject = event.streams[0]
audioElement.autoplay = true
}
}
// Offer to receive one video track, and one audio track
peerConnection.addTransceiver('video', { direction: 'sendrecv' })
peerConnection.addTransceiver('audio', { direction: 'sendrecv' })
第三,需要调用语音 SDK 来创建虚拟形象合成器并连接到虚拟形象服务,并将对等连接用作参数。
// Create avatar synthesizer
var avatarSynthesizer = new SpeechSDK.AvatarSynthesizer(speechConfig, avatarConfig)
// Start avatar and establish WebRTC connection
avatarSynthesizer.startAvatarAsync(peerConnection).then(
(r) => { console.log("Avatar started.") }
).catch(
(error) => { console.log("Avatar failed to start. Error: " + error) }
);
在虚拟形象处于空闲状态 5 分钟后,实时 API 将断开连接。 即使头像未空闲且正常运行,实时 API 也会在 10 分钟连接后断开连接。 若要确保实时虚拟形象的连续操作超过 10 分钟,则可以启用自动重新连接。 有关如何设置自动重新连接的信息,请参阅此示例代码(搜索“自动重新连接”)。
从文本输入合成会说话的虚拟形象视频
执行上述步骤后,应会看到在 Web 浏览器中播放的虚拟形象视频。 虚拟形象处于活动状态,眨眼且身体轻微移动,但还没有说话。 虚拟形象正在等待文本输入即可开始说话。
以下代码片段演示如何将文本发送到虚拟形象合成器,并让虚拟形象说话:
var spokenText = "I'm excited to try text to speech avatar."
avatarSynthesizer.speakTextAsync(spokenText).then(
(result) => {
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
console.log("Speech and avatar synthesized to video stream.")
} else {
console.log("Unable to speak. Result ID: " + result.resultId)
if (result.reason === SpeechSDK.ResultReason.Canceled) {
let cancellationDetails = SpeechSDK.CancellationDetails.fromResult(result)
console.log(cancellationDetails.reason)
if (cancellationDetails.reason === SpeechSDK.CancellationReason.Error) {
console.log(cancellationDetails.errorDetails)
}
}
}
}).catch((error) => {
console.log(error)
avatarSynthesizer.close()
});
可以在 GitHub 上找到端到端工作示例。
关闭实时虚拟形象连接
若要在实时虚拟形象使用完毕后避免不必要的成本,请务必关闭连接。 有若干方法可实现此操作:
关闭浏览器网页时,将释放 WebRTC 客户端对等连接对象,并在几秒钟后自动关闭虚拟形象连接。
如果头像保持空闲状态 5 分钟,则虚拟形象服务会自动关闭连接。
可以通过运行以下代码来主动关闭虚拟形象连接:
avatarSynthesizer.close()
可以在 GitHub 上找到端到端工作示例。
编辑背景
虚拟形象实时合成 API 目前不支持设置背景图像/视频,仅支持设置纯色背景,不支持透明背景。 但是,有一种在客户端实现背景自定义的替代方法,遵循以下准则:
- 将背景色设置为绿色(方便着色),虚拟形象实时合成 API 支持该颜色。
- 创建大小与虚拟形象视频相同的画布元素。
- 捕获虚拟形象视频的每个帧,并应用像素逐像素计算,将绿色像素设置为透明,并将重新计算的帧绘制到画布上。
- 隐藏原始视频。
使用此方法,可以获取一个动画画布,其像视频一样播放,具有透明背景。 下面是演示此类方法的示例代码。
获得透明背景虚拟形象后,可以通过将图像或视频放置在画布后面,将背景设置为任何图像或视频。