元峰AI笔记 · AI数字人

什么是文本转语音头像?

<title微软数字人来了</title

微软数字人来了

大家好,我是元峰。13 颗 AI 之心持有者。目前对数字人领域探索比较多,所以昨天看到微软推出了自己的数字人之后,立刻发布了一条风向标,今天就赶紧体验试下效果。体验还是相当 Nice,文末会有展示视频。

微软的叫法是:文本转语音头像!这项创新功能不仅允许用户通过文本输入来创建能够说话的头像视频,还能使用人类图像训练来制作实时互动的智能机器人。

今天这篇文章中,我会详细介绍这个功能的特性、优势和技术细节,并通过一系列实例展示它在不同场合的应用方法。

什么是文本转语音头像?

文本转语音头像是一项结合了视觉技术的文本转语音功能,它可以让用户制作出 2D 逼真头像的合成说话视频(让图片开口讲话)。这些头像模型是通过深度神经网络训练而成的,训练材料来自于真人视频录制样本(声音克隆)。

头像的声音则是由先进的文本转语音声音模型所提供(TTS),使其更加生动真实。

微软说构建头像的主要有两个原因:

  • 一是因为传统的视频内容制作不仅耗时而且成本高昂涉及到搭建拍摄环境、录制和剪辑等多个环节。文本转语音头像使用户可以更高效、更简便地创建视频内容,只需输入文本,就能制作出培训视频、产品介绍、客户评价等。
  • 二是随着 Azure OpenAI 服务及神经文本转语音技术的推出,数字互动变得更加自然和流畅。文本转语音头像让用户可以创造出更生动、更引人入胜的数字交互体验,例如可以利用头像开发对话型代理、虚拟助手、聊天机器人等。

在头像内容生成的流程中,有三个核心环节:**文本分析器、文本转语音音频合成器和文本转语音头像视频合成器。**首先,文本被输入到文本分析器中,并被转化为音素序列。接着,文本转语音音频合成器根据文本的声学特征来预测并合成声音,这两个步骤都由文本转语音的声音模型完成。最后,神经文本转语音头像模型根据这些声学特征预测唇形同步的图像,从而生成逼真的合成视频。

图片展示了文本转语音头像内容生成的流程。首先是文本/SSML输入,接着进入文本分析环节,随后是TTS音频合成,再到TTS头像视频合成,最终生成逼真的头像视频文件/流。其中,TTS音频合成由TTS/CNV模型支持,TTS头像视频合成由头像模型支持。该图与上文提到的头像内容生成的三个核心环节相呼应,直观呈现了从文本输入到生成逼真合成视频的过程。

这次发布包括哪些内容?

我们目前提供两种文本转语音头像功能:内制版和定制版

内制版文本转语音头像

微软在 Azure 平台上为订阅用户提供了预制的文本转语音头像产品,可以即插即用。这些头像能够根据文本输入用不同的语言和声音进行交流。客户可以从多种选项中选择一个头像,用来创造视频内容或开发具有实时头像反应的互动应用程序。

图片展示了微软Azure平台内制版文本转语音头像中的虚拟形象及背景。左侧是一位身着黑色上衣和蓝色牛仔裤的虚拟形象人物。右侧有五个小图,均标注为“lisa”,分别呈现了“casual - sitting”“graceful - sitting”“graceful - standing”“technical - sitting”“technical - standing”等不同姿态和风格的虚拟形象及背景。这些头像可供订阅用户即插即用,选择用于创造视频内容或开发互动应用程序等。

定制版文本转语音头像(需要申请)

定制版功能使客户能够为他们的产品或品牌创建个性化头像。客户可以上传自己的头像视频录制,系统将利用这些视频训练一个定制头像的合成视频。客户可以为他们的头像选择预制或定制的神经语音(声音克隆)。如果同时使用同一人的声音和形象创建定制的神经语音和文本转语音头像,该头像将非常接近于该人。(数字人克隆)

作为微软对负责任 AI 的承诺,文本转语音头像功能旨在保护个人和社会的权利,促进透明的人机交互,并防止有害的深度伪造和误导性内容的传播。因此,定制头像是一个限制访问功能,仅限注册用户使用,并且只适用于特定用例。要在你的商业应用中使用此功能,请在此处注册你的应用案例并申请访问权限

文本转语音头像可以做什么?

使用文本转语音头像,无论是利用预制头像还是定制头像,你都可以创造出各种引人入胜的视频,如培训视频、演示视频等。

它还可以帮助你为客户、员工和其他受众提供富有互动性的应用程序体验。

Azure AI 语音宣布了文本转语音头像的公开预览,其中涵盖了多种应用场景,例如:

批量视频内容创作

  • 企业培训视频
  • 产品介绍或广告材料
  • 让 CEO 的数字分身在会议中发表演讲

实时互动应用

  • 旅游网站的聊天机器人
  • 直播商业活动中的虚拟销售
  • AI 老师在线授课,可答疑解惑
  • 回答员工疑问的虚拟 HR

如何使用?

微软本次发布的版本,同时支持 Azure AI Speech Studio 的 UI 工具API 访问

Azure AI Speech Studio

图片展示了Azure AI Speech Studio的起始页面。页面顶部有“开始使用Azure认知服务语音”的标题,下方介绍了语音功能,包括使用语音转文本和文本转语音等功能,还展示了三个应用场景的图片,分别为移动设备的文本转语音字幕、通过运动分析提供反馈、实现聊天机器人语音交互。此外,页面底部有“语音转文本”的相关说明。该图片与上文提到的微软数字人可通过Azure AI Speech Studio的UI工具访问的内容相关,直观呈现了该工具界面。

图片展示了Azure AI Speech Studio界面中的“文本转语音”部分。界面中有多个功能选项图标,其中下方“文本转语音虚拟形象”选项被红框突出显示,其下方英文说明为“Create photorealistic avatar - talking videos with just text”。该图片位于介绍微软数字人使用方式的文档中,与提及的Azure AI Speech Studio UI工具相关,展示了其中可创建语音头像的功能入口。

https://speech.microsoft.com/portal

会说话的虚拟形象

图片展示了Azure AI Speech Studio界面中“会说话的虚拟形象”相关内容,画面左侧有一位女性虚拟形象,右侧呈现内置形象Lisa的几种姿势图示,包括休闲坐姿、优雅坐姿等。下方有示例文本、语音选择等操作选项,还有步骤引导,如创建语音资源、输入文本生成视频等。该图片与上文提到的使用Azure AI Speech Studio体验语音头像的内容相关,直观呈现了操作界面和部分功能。

注册 Azure 账户

但是不管界面还是 API 版本,都需要注册 Azure 账户。如果新用户可以享受 12 个月的免费服务。

https://azure.microsoft.com/zh-cn/free/ai-services/

图片展示了Azure免费账户相关信息。画面中一台笔记本电脑屏幕显示内容,旁边有红色框突出显示“通过Azure免费帐户创建定制的AI支持的搜索,12个月的免费服务(包括Azure AI服务)助你开始使用AI支持的搜索”,下方有“免费开始使用”和“查看限时优惠”两个按钮。图片下方还有三行文字,分别介绍热门服务可免费使用12个月、超55项其他服务始终免费、从200美元Azure额度开始等内容。此图与上文注册Azure账户及新用户可享12个月免费服务的内容相关。

  1. 创建新的语音资源

图片展示了Azure AI Speech Studio中创建语音资源的相关界面。界面显示“后续步骤”,第一步为选择语音资源,当前语音资源为“Feng (SpeechServices, 美国西部2, S0)”,区域是“westus2”,还显示了语音终结点等信息。画面中“创建语音资源”按钮被红色圆圈突出显示。该图片与上文“创建新的语音资源”步骤相关,是在注册Azure账户后,创建语音资源操作中的一个界面展示,帮助用户了解在该平台创建语音资源的具体操作画面。

  1. 在填写新的资源名称之前,需要先点击 转到 Azure 门户以使用高级设置进行创建 一个语音服务。

图片展示了“创建语音资源”的弹窗界面。其中有“新资源的名称”“订阅”“区域”“定价层”“资源组”等输入和选择项。界面底部有一个红色椭圆框突出显示的链接“转到Azure门户以使用高级设置进行创建”,这与文档中“在填写新的资源名称之前,需要先点击[转到Azure门户以使用高级设置进行创建](https://go.microsoft.com/fwlink/?linkid=2086754)一个语音服务”的步骤描述相呼应,是创建语音资源流程中的关键操作指引部分。

图片展示了Azure门户中创建语音服务的界面,为“创建语音服务”步骤中的操作指引图示。画面中有多项配置内容,包括订阅、资源组、区域、名称、定价层等。其中用红色数字序号标识了关键步骤:①先建一个资源组;②推荐美国西部;③配置一个名字;④选择定价层,有免费有付费;⑤开始创建。图片与上下文关系紧密,是对上文“在填写新的资源名称之前,需要先点击[转到Azure门户以使用高级设置进行创建]一个语音服务”操作的具体展示。

图片展示的是Azure门户中语音服务的部署完成页面。页面顶部显示服务名称为“Microsoft.CognitiveServicesSpeechServices”,下方“部署完成”区域有部署名称、订阅、资源等信息。在“部署详细信息”部分,资源名称“Msttshng”被红色圆圈突出显示,服务类型为Azure AI service,状态为Created。该图片对应文档中“创建新的语音资源”步骤里,在点击链接创建语音服务后,语音服务创建完成时的页面展示,用于说明语音服务创建成功后的界面情况。

  1. 语音服务创建完成,重新创建语音资源。

图片展示了Azure中“创建语音资源”的界面。画面中有一个名为“新资源的名称”的输入框,框内填写了“metafeng”,且该输入框被红色圆圈突出显示。此外,界面还包括订阅、区域、定价层、资源组等设置项,并有“创建新订阅”“创建新资源组”等操作选项。此图与上文提到的“重新创建语音资源”相关,展示了创建语音资源时填写新资源名称等配置信息的步骤。

图片展示了在注册Azure账户并完成语音服务创建后,创建语音资源的后续步骤界面。核心内容是“1.选择语音资源”部分,其被红色圆圈突出标注。这里可选择语音资源,如“Feng (SpeechServices, 美国西部 2.50)”,并显示区域为“westus2 - 韦斯顿 2”,还有语音终结点网址。该图片与上文“创建新的语音资源”内容相关,说明在完成前期操作后,在此处进一步选择和配置语音资源,之后可进行“2.创建您自己的视频”操作。

基础的信息全部配置完成,就可以体验语音头像了。

内置形象

内置形象 Lisa,提供几种不同的姿势:休闲坐姿,优雅的坐姿,优雅的站姿,技术坐姿,技术站姿

图片展示了微软数字人内置形象Lisa的几种不同姿势。左侧是Lisa休闲坐姿的形象,身着黑色上衣和蓝色牛仔裤。右侧列出了Lisa的其余姿势,包括优雅坐姿、优雅站姿、技术坐姿和技术站姿。上下文提到可使用Azure AI Speech Studio的UI工具和API访问微软数字人,还介绍了注册Azure账户、创建语音资源等前期操作,此图片是对内置形象Lisa姿势选择的展示,之后还提及了选择语言和语音、自定义手势等后续操作。

选择语言和语音

图片展示了Azure AI Speech Studio中选择语言和语音的界面。界面中有两个下拉菜单被红色圆圈突出显示,左侧下拉菜单可选择语言,如“中文(普通话,简体)”等多种中文变体;右侧下拉菜单可选择语音,如“Xiaochen”等。这些语音模型由深度神经网络训练而成,训练材料来自真人视频。此图片对应文档中“选择语言和语音”部分,直观呈现了该操作步骤的界面情况。

插入分隔

图片展示了Azure AI Speech Studio中选择语言和语音、插入分隔的操作界面。语言选择为中文(普通话),在“插入分隔”选项框中,有标准、默认、高级、自定义几种模式可选。画面中有红色箭头指向“插入分隔”选项框以及一段文本内容,文本旁标注有“400毫秒”,表明这些头像模型通过深度神经网络训练而成,用户可借此制作二维逼真头像的合成说话视频。此图对应文档中介绍使用微软数字人时选择语言和语音、插入分隔的操作步骤部分。

自定义插入手势

图片展示了Azure AI Speech Studio中自定义插入手势的界面。界面上方有“播放音频”“插入分隔”“插入手势”“语速”等功能按钮,其中“插入手势”按钮被突出显示。点击“插入手势”后,弹出的窗口中显示了内置形象Lisa的几种手势选项,如wave - left - 1、wave - left - 2等,每个手势选项配有Lisa做出相应手势的图片。该图片与文档中介绍使用微软数字人时“自定义插入手势”的内容相对应。

调整语速

图片展示了Azure AI Speech Studio中调整语速的界面。界面中语言选择为中文(普通话,简体),语音为“Xiao”。语速设置部分有一个蓝色进度条,当前语速为“x1.2”,被红色圆圈突出显示。下方有文本内容,介绍文本转语音头像的技术及训练材料来源等信息。此图片与文档中“调整语速”的上下文对应,展示了调整语速的具体操作界面和设置情况。

预览视频&下载视频

图片展示了Azure AI Speech Studio中会说话的虚拟形象界面。左侧是虚拟形象展示区域,呈现一位身着黑色服装的女性形象。左下角有“预览视频”和“下载视频”按钮。右侧列出内置形象Lisa的几种姿势,包括休闲坐姿、优雅坐姿、优雅站姿、技术坐姿和技术站姿。下方可选择语言(如中文普通话[简体])和语音(如Xiaochen),还有播放音频、插入分隔、插入手势、语速等设置选项。此图与上文介绍的使用微软数字人,体验语音头像相关内容相呼应。

但是,测试下来,这个预览中,最终的视频只能生成一句,文本太长就会失败。

所以,接下来我就测试 API 版本试试。

API 版本测试

GitHub 链接

可直接使用 官方提供的 Notebook 来制作头像视频:https://github.com/Azure/gen-cv/tree/main/avatar/video

图片展示的是一个GitHub页面界面,左侧是文件目录栏,右侧是文件内容显示区域。在右侧内容显示区域中,有一个文件名为“create - avatar - video.py”,其左侧有一个圆圈标识,右侧显示该文件最近一次提交是3天前。图片下方的文本介绍了使用文本转语音数字人创建引人入胜的视频,及其在教育内容、企业通信等领域的应用。此图片与上文提到的官方提供的用于制作头像视频的GitHub链接相关,展示了链接对应仓库中的文件情况。

图片展示的是微软数字人相关的GitHub页面,文件路径为gen-cv/avatar/video/create-avatar-video.ipynb 。页面中标题为“Use the TTS Avatar Service to Create Engaging Videos”,下方介绍了使用Azure TTS Avatar API和自定义脚本创建头像视频的步骤,还列出了额外资源如可用语音和语言链接、示例代码链接等,以及使用该服务的先决条件。此图与文档中介绍使用官方提供的Notebook制作头像视频的内容相关,展示了相关Notebook所在位置及部分内容。

https://github.com/Azure/gen-cv/tree/main/avatar/video

谷歌 Colab 链接

下面是我下载之后在谷歌 Colab 中修改后的版本:

https://colab.research.google.com/drive/1r-MmWYHqf53qHTbjVkfD73WwKn-QVlmD?usp=sharing

图片展示的是在谷歌Colab中打开的名为“create - avatar - video.ipynb”的文件界面。界面中显示了使用TTS Avatar服务创建引人入胜视频的相关说明,包括引导通过Azure TTS Avatar API和自定义脚本创建基于化身的视频,介绍了从创建脚本到生成视频的步骤,还提及了可用的资源、语言支持等信息,下方有设置步骤的代码示例。此图片与文档中介绍如何在谷歌Colab中使用相关版本制作头像视频的上下文相契合。

运行代码及解释

下面写一下我跑这个代码过程中的详细步骤,遇到很多问题以及我是如何解决的。

代码框1

import requests
import json
import time
import os
from dotenv import load_dotenv

这段代码是一个 Python 脚本的一部分,其中包含了一些模块导入语句。每个导入的模块都有其特定的用途:

  1. import requests

    • requests 是一个流行的 Python 库,用于发送 HTTP 请求。这意味着代码中可能会涉及到与网络资源的交互,如 API 调用、网页内容获取等。
  2. import json

  • json 模块用于处理 JSON 数据。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于网络通信。这表明脚本可能会处理 JSON 格式的数据,如解析来自网络请求的响应或将数据转换为 JSON 格式发送。
  1. import time
  • time 模块提供了与时间相关的函数。这可能用于处理时间相关的操作,如延迟(等待)、记录时间戳、测量代码执行时间等。
  1. import os
  • os 模块提供了一系列与操作系统交互的功能,包括但不限于文件和目录的管理、环境变量的读取、执行操作系统命令等。这可能表明脚本需要与文件系统交互,或者需要读取操作系统层面的配置。
  1. from dotenv import load_dotenv
  • dotenv 是一个用于管理环境变量的 Python 库。load_dotenv 函数用于加载 .env 文件中的环境变量。.env 文件通常用于存储配置信息,如数据库连接字符串、API 密钥等,以避免将这些敏感信息硬编码在代码中。 综合来看,这段代码可能是一个涉及网络请求、数据处理、时间操作和环境配置管理的应用程序或脚本的一部分。它表明开发者可能在处理网络数据,同时关注代码的安全性和配置的灵活性。

图片展示的是运行包含模块导入语句的Python代码时出现的报错信息。代码框内显示了5条模块导入语句,包括requests、json、time、os以及from dotenv import load_dotenv。报错信息以红色字体突出显示,提示出现“ModuleNotFoundError: No module named 'dotenv'”,即找不到名为“dotenv”的模块。这与上下文提到的代码运行过程中遇到的问题相呼应,表明在运行代码时因缺少“dotenv”模块而报错。

好家伙,第一段就开始报错,但是不慌,这是跑 Python 代码时最常见的问题。

解决办法:缺啥补啥,此环境缺少 dotenv 库,于是执行 pip 进行安装。

!pip install python-dotenv

图片展示了运行代码“!pip install dotenv”时出现错误的界面。代码执行后显示正在收集dotenv,使用缓存文件,但随后提示子进程退出时出错,python setup.py egg_info未成功运行,退出代码为1。还指出这是与包相关的问题,非pip问题,在生成包元数据时遇到错误。此图片与上文提到的运行Python代码时因缺少dotenv库,执行pip安装却报错的内容相呼应,直观呈现了报错情况。

出师继续不利,这个错误没遇到过,直接把错误丢给 GPT,这不一下就知道什么原因了。原来是 Python 包名的问题。

图片是ChatGPT给出的报错原因及解决办法。显示出现错误通常是因为错误的包名、Python环境问题、依赖性问题或网络问题等。其中特别指出,错误的包名情况下,可能试图安装一个不存在的包,正确包名是“python-dotenv”,并建议尝试使用“pip install python-dotenv”来安装。这与上下文提到的将报错内容丢给GPT,得知是Python包名问题相呼应,为解决运行Python代码时遇到的报错提供了指导。

!pip install python-dotenv

图片展示的是运行Python代码安装python - dotenv库的过程及结果。代码框中显示两条命令,分别为注释掉的#!pip install dotenv和!pip install python - dotenv。下方反馈信息表明正在收集、下载并成功安装了python - dotenv库,版本为1.0.0。这与上文提到运行Python代码时因缺少dotenv库报错,需执行pip安装的内容相呼应,展示了安装操作后的成功反馈。

成功解决,继续下一段代码。

代码框2

# if not load_dotenv('./.env-avatar-video'): raise Exception("env file not found")
os.environ["SPEECH_SERVICE_REGION"] = "your_service_region" #替换为你的资源区域
os.environ["SPEECH_SERVICE_API_KEY"] = "your_api_key" #替换为你的资源秘钥

service_region = os.getenv("SPEECH_SERVICE_REGION")
subscription_key = os.getenv("SPEECH_SERVICE_API_KEY")

# print(service_region,subscription_key)

url_base = f"https://{service_region}.customvoice.api.speech.microsoft.com/api"

project_folder = '/content/my-project'
if not os.path.exists(project_folder):
    os.makedirs(project_folder)
# project_folder = './my-project' # your project folder
# # os.makedirs(project_folder, exist_ok=True)

texttype = 'ssml' # ssml or PlainText
# texttype = 'Plaintext'

ssml_path = os.path.join(project_folder, '/content/ssml.txt') # if your avatar text input is in SSML format
plaintext_path = os.path.join(project_folder, '/content/plaintext.txt') # if your avatar text input is plaintext format

原代码中是需要通过内置环境变量来获取变量,但因为 Colab 环境问题,直接获取环境变量有很多限制。

图片是ChatGPT给出的在Google Colab中运行代码时问题的解决方案。指出问题可能是‘env-avatar-video’文件不存在或路径不正确。解决步骤为:上传该文件到Colab环境;确认文件路径与‘load_dotenv’函数指定路径匹配;检查环境变量格式;确保文件格式正确;上传并确认路径无误后重新运行代码。若仍未解决,可在代码中设置环境变量,但可能暴露敏感信息,并给出了在代码中设置环境变量的示例代码。

所以这边我直接在代码中设置环境变量,但请注意,这样做可能会暴露敏感信息

例如:

os.environ["SPEECH_SERVICE_REGION"] = "your_service_region" #资源区域 os.environ["SPEECH_SERVICE_API_KEY"] = "your_api_key" #资源秘钥

这里有两个 API 需要从前面的语音资源中获取。

图片展示了使用微软数字人的后续步骤。第一步是选择语音资源,可从下拉菜单中选择如Feng(SpeechServices,美国西部2,S0)等语音资源,下方有“区域”显示为westus2,“资源密钥”处有红框标注,旁边箭头指向代码中获取变量的对应内容your_service_region和your_api_key,语音终结点也有显示。第二步是创建自己的视频,输入文本脚本并选择头像生成视频,满意后下载到本地。此图与上文提到从语音资源获取两个API的内容相关。

代码框3

# Helper functions

def download_file(url, local_path):
    """
    Download a file from a given URL to a local path. This function streams the file from the URL and writes it in chunks to the local
    file system. This allows it to handle large files that might not fit in memory.

    Parameters:
    url (str): The URL of the file to download.
    local_path (str): The local path where the file should be saved.

    Returns:
    str: The local path to the downloaded file.
    """
    with requests.get(url, stream=True) as r:
        r.raise_for_status()

        # Extract filename from URL
        filename = url.split("/")[-1].split("?")[0]

        local_filename = os.path.join(local_path, filename)

        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)

    return local_filename

上面这段代码是写了一个函数,待会我们生成视频之后,下载视频用的,暂时不用管。

代码框4

# load speaking script
if texttype == 'ssml':
    with open(ssml_path, 'r') as file:
        content = file.read()
elif texttype == 'Plaintext':
    with open(plaintext_path, 'r') as file:
        content = file.read()
else:
    print(f'Error: Texttype needs to be either "ssml" or "Plaintext". Got {texttype} instead.')

print(content)

这段代码是选择给头像的文案的文本方式:简单的纯文本文件 plaintext 或者 更高级的语音合成标记语言 SSML格式。

简单的纯文本格式

图片展示的是选择给头像文案的语音合成标记语言SSML格式相关设置界面。界面中有“播放音频”“插入分隔”“插入手势”“语速”等操作按钮,还有“SSML mode SSML模式”开关。语言选择为“中文(普通话,简体)” ,语音为“Xiaochen”。下方有一段示例文本,介绍了可用SSML让头像用不同语言讲话、添加效果等相关内容,与上文提及的选择头像文案的文本方式(SSML格式)相对应。

这个例子展示了你可以用 SSML 让你的头像用不同的语言讲话,并且如何添加效果。我们使用的是小辰的声音,它能用几种语言讲话。这里是多语言才华横溢的小辰用法语说话。我的声音很容易被识别。
我可以用 15 种不同的风格讲话。如果你想要一个喊叫的头像,对我来说没问题!或者怎么样,来点耳语对话?你可以在我的语言中插入一个暂停,使用一个断句标签。使用音素来正确发音特定的单词,如 OpenAI 的 DALLE 模型。没有音素,神经语音会错误地说 DALLE。调整说话速度,所以如果你想,我可以说得非常快,或者说得相当慢。随意调整音调以提高声音,或者相反,如果你更喜欢那样。最后,这是你如何降低音量,或者让我说话更大声。我们希望这些示例能帮助你定制你的头像的沟通,以获得更引人入胜的体验。玩得开心!

更高级的语音合成标记语言(SSML)格式(推荐使用)

那么问题来了,什么是 SSML 格式?(文章最后会有视频解释)

SSML(Speech Synthesis Markup Language)格式是一种基于 XML 的标记语言,专门用于控制和定制文本转语音(TTS)系统的输出。它允许用户精确地指定语音合成的各种方面,包括发音、音调、音量、语速、停顿等。通过 SSML,用户可以让合成语音更加自然、表情丰富,并能够适应特定的语境和应用需求。SSML 格式常用于开发高度个性化的语音应用,如虚拟助手、自动语音响应系统、有声读物等。

图片展示了一段基于SSML格式的代码示例,代码上方有“播放音频”按钮和“SSML mode SSML模式”开关,开关处于开启状态并以红色圆圈突出显示。代码中包含xmlns等属性声明,使用了“zh - CN - XiaochenNeural”声音,展示了让头像用不同语言讲话及添加效果的示例,如小辰用法语说话等内容,与上文介绍如何用SSML让头像以不同语言讲话等上下文紧密相关。

This example shows what you can do with SSML to let your avatar speak in various languages and how to add effects. We are using the voice Jenny Multilangual which is able to speak in several languages. Voici le talent linguistique Jenny parlant français. Ma voix est bien reconnaissable. I can speak in 15 different styles. If you want a shouting Avatar, no problem for me!Or what about some whispered dialog?DALLEso I can talk really fast if that's what you want or talk quite slowly.Feel free to adjust the pitch for more highness of the sound. Or the opposite if you like that better.Finally, here is how you reduce the volume.Or make me speak louder.Have fun!

上面英文版本是官方给的示例。使用 GPT 直接转换为中文版本的,切记要保持格式不变。

图片展示的是一段SSML示例的中文翻译代码。代码中包含<speak>、<voice>、<lang>等多种标签,如<voice name="zh - CN - XiaoxiaoNeural">指定了语音名称,<lang>标签用于设置语言等。还对不同的语音风格如“shouting”“whispering”等进行了示例,以及介绍了<prosody>标签用于调整音量、音高、语速等。这段翻译保持了原有的SSML标签和属性不变,仅将文本部分译为中文,与上文提到的将英文版本示例用GPT转换为中文版本且保持格式不变的内容相呼应。

这个例子展示了你可以用 SSML 让你的头像用不同的语言讲话,并且如何添加效果。 我们使用的是小辰的声音,它能用几种语言讲话。 这里是多语言才华横溢的小辰用法语说话。我的声音很容易被识别。 我可以用 15 种不同的风格讲话。 如果你想要一个喊叫的头像,对我来说没问题! 或者怎么样,来点耳语对话? 你可以在我的语言中插入一个暂停 使用一个断句标签。 使用音素来正确发音特定的单词,如 OpenAI 的 DALLE 模型。没有音素,神经语音会错误地说 DALLE。 调整说话速度 所以如果你想,我可以说得非常快 或者说得相当慢。 随意调整音调以提高声音。 或者相反,如果你更喜欢那样。 最后,这是你如何降低音量。 或者让我说话更大声。 我们希望这些示例能帮助你定制你的头像的沟通,以获得更引人入胜的体验。 玩得开心!

然后我们需要创建 2 个文件,分别把两种格式的内容写进去。

图片展示了在使用微软数字人API版本测试时创建文件的相关代码界面。左侧文件栏中,有“plaintext.txt”和“ssml.txt”两个文件被红色箭头指向,对应上文提到的需创建的两个文件,用于写入不同格式内容。右侧代码部分包含一些路径和变量设置等代码,与上下文介绍的配置参数、生成头像视频的步骤相关,是具体代码实现的展示,辅助理解创建文件及后续操作的过程。

代码框5

# generate avatar video
payload = json.dumps({
    "displayName": "my avatar",
    "description": "Vision AI Solution Accelerator Demo",
    "textType": texttype, # PlainText, ssml
    "inputs": [
        {
            "text": content
        }
    ],
    "synthesisConfig": {
        "voice": "zh-CN-XiaochenNeural",  # set voice name for plain text; ignored for ssml
    },
    "properties": {
        "talkingAvatarCharacter": "lisa",  # custom avatar. pre-built avatar: lisa
        "talkingAvatarStyle": "technical-standing",  # supported lisa styles: casual-sitting, graceful-sitting, graceful-standing, technical-sitting, technical-standing
        "videoFormat": "webm",  # mp4 or webm, webm is required for transparent background
        "videoCodec": "vp9",  # hevc, h264 or vp9, vp9 is required for transparent background; default is hevc
        "subtitleType": "soft_embedded",
        "backgroundColor": "transparent",
    },
})

session = requests.Session()
session.headers.update({
    'Accept': 'application/json',
    'Ocp-Apim-Subscription-Key': subscription_key,
    'Content-Type': 'application/json'
})

url_com = f'{url_base}/texttospeech/3.1-preview1/batchsynthesis/talkingavatar'

response = session.post(url_com, data=payload)

print(f'Status code: {response.status_code}')
if response.status_code >= 400:
    print('Job submission failed. Please verify your subscription key and try again.')
    print(response.text)
else:
    print('Job submitted successfully. Processing', end=' ')
    r = response.json()

    while True:
        result = session.get(f'{url_base}/texttospeech/3.1-preview1/batchsynthesis/talkingavatar/{r["id"]}')
        if result.json()['status'] == 'Succeeded':
            print('\n\nReady. Synthesized video:\n' + result.json()['outputs']['result'])
            break
        if result.json()['status'] == 'Failed':
            print('synthesis failed')
            print(result.json()['properties']['error'])
            break
        print('.', end = '')
        time.sleep(10)

这里主要配置几个参数:

语言和音色:"voice": "zh-CN-XiaochenNeural", 从语音库中选择合适的,中文,晓辰。

图片展示了微软语音库的界面,用于选择语言和音色。界面中可看到多种语音选项,其中被红圈高亮的是“中文普通话 - 晓辰”,箭头将其与右侧代码中“name":"zh-CN-XiaochenNeural" 相连,表明在代码配置中选择该语音对应的参数写法。此图与上下文的关系是,为上下文提到的 “语言和音色:'voice':'zh-CN-XiaochenNeural'” 提供了直观的选择参考示例,辅助理解从语音库中选择中文晓辰音色这一配置操作。

选择头像形象:"talkingAvatarCharacter": "lisa", 内置的目前只有 Lisa。

图片展示了微软数字人API版本测试中选择头像形象及姿势的相关内容。左侧是选中的“Lisa”数字人形象,身着黑色服装。右侧为虚拟形象和背景选择区域,虚拟形象有“Lisa”的多种姿势选项,包括休闲坐姿(casual - sitting)、优雅坐姿(graceful - sitting)、优雅站姿(graceful - standing)、技术坐姿(technical - sitting)和技术站姿(technical - standing),当前“technical - standing”被框选突出显示。图片与上下文紧密相关,直观呈现了文中提到的选择头像形象及姿势的配置操作。

选择姿势:"talkingAvatarStyle": "technical-standing",休闲坐姿,优雅的坐姿,优雅的站姿,技术坐姿,技术站姿。

图片展示了微软数字人API版本测试中可选择的虚拟形象及姿势。共有五个“lisa”形象,分别对应不同姿势,即休闲坐姿(casual - sitting)、优雅坐姿(graceful - sitting)、优雅站姿(graceful - standing)、技术坐姿(technical - sitting)和技术站姿(technical - standing),其中技术站姿的“lisa”形象被蓝色框突出显示。这与上文提到的配置参数中“选择头像形象:'talkingAvatarCharacter':'lisa'”及“选择姿势:'talkingAvatarStyle':'technical - standing'”相呼应,直观呈现了可选项。

视频背景:backgroundColor": "transparent", 透明或者白色。

图片展示了微软数字人API版本测试中视频背景的选择界面。界面分为“虚拟形象”和“背景”两部分,在“背景”部分有两种背景选项,左侧是白色背景,标注为“White”,右侧是透明背景,标注为“Transparent”。这与上文提到的视频背景可选择“透明或者白色”相呼应,直观呈现了背景选择的具体样式,帮助理解在配置生成头像视频时的背景设置参数。

视频格式:"videoFormat": "webm", 可以选择 MP4 和 webm 格式。如果视频背景选择了透明,这里就选择 webm 格式。

图片展示的是用于生成头像视频的代码片段。代码中配置了多个参数,关键内容用红色圆圈标注并附带蓝色文字解释。其中,音色设置为中文晓辰,对应代码 "voice":"zh-CN-XiaochenNeural";头像形象选择内置的Lisa,对应 "talkingAvatarCharacter":"lisa";姿势选择技术站姿,对应 "talkingAvatarStyle":"technical - standing" ;视频背景为透明,视频格式相关配置也在代码中体现。此图片与上文介绍代码框中配置参数的内容相呼应,直观呈现了代码中具体的参数设置情况。

到这一步也就意味着配置全部结束了,然后执行这个代码框,就可以生成头像视频了。

图片展示的是代码编辑界面,其中代码框内容为创建头像视频的相关代码。画面中红圈突出、并有红色箭头指向的部分是代码中的“143”行。上下文提到配置好语言和音色、头像形象、姿势、视频背景、视频格式等参数后执行代码框可生成头像视频,此图应是在展示执行生成头像视频代码时的界面,可能意在说明代码执行到某一行的状态等相关信息,与上下文讲述的运行代码生成视频的内容相关。

代码框7

# download video to project folder. Note: An existing video file will be overwritten.
url = result.json()['outputs']['result']
local_filename = download_file(url, project_folder)
print(f'{local_filename} downloaded.')

经过 6 分钟的等待之后,视频就制作好,程序会返回给我们的是一个下载链接。

使用之前的视频下载函数,即可将视频下载到本地。

现在结合这个视频,在看这个 SSML 格式,就能懂这些标签是做什么的了。(这个例子中讲法语的部分是没有生效的。)

这个例子展示了你可以用 SSML 让你的头像用不同的语言讲话,并且如何添加效果。 我们使用的是小辰的声音,它能用几种语言讲话。 这里是多语言才华横溢的小辰用法语说话。我的声音很容易被识别。 我可以用 15 种不同的风格讲话。 如果你想要一个喊叫的头像,对我来说没问题! 或者怎么样,来点耳语对话? 你可以在我的语言中插入一个暂停 使用一个断句标签。 使用音素来正确发音特定的单词,如 OpenAI 的 DALLE 模型。没有音素,神经语音会错误地说 DALLE。 调整说话速度 所以如果你想,我可以说得非常快 或者说得相当慢。 随意调整音调以提高声音。 或者相反,如果你更喜欢那样。 最后,这是你如何降低音量。 或者让我说话更大声。 我们希望这些示例能帮助你定制你的头像的沟通,以获得更引人入胜的体验。 玩得开心!

再看英文原版的,效果会更明显。

This example shows what you can do with SSML to let your avatar speak in various languages and how to add effects. We are using the voice Jenny Multilangual which is able to speak in several languages. Voici le talent linguistique Jenny parlant français. Ma voix est bien reconnaissable. I can speak in 15 different styles. If you want a shouting Avatar, no problem for me!Or what about some whispered dialog?DALLEso I can talk really fast if that's what you want or talk quite slowly.Feel free to adjust the pitch for more highness of the sound. Or the opposite if you like that better.Finally, here is how you reduce the volume.Or make me speak louder.Have fun!

最后,意外的收获。玩了一天,就生成了 3 条视频,竟然倒欠微软爸爸 464 美刀,可是后面又显示无需付费。不得不感慨,数字人这玩意,成本是真的高!!!

图片展示了微软Azure的成本管理与计费界面,显示了以0829结尾的卡片计费信息。其中,余额一栏以红色字体突出显示为“-464.40”,表示欠费464.40美元,而信用额度为“464.40”。该图片与文档上下文相关,对应文档中提到的“玩了一天,就生成了3条视频,竟然倒欠微软爸爸464美刀,可是后面又显示无需付费”,直观呈现了文档中所述的欠费情况。

最后的话

体验完微软数字人技术后,这也是用了这么多数字人平台后,第一次从底层用代码去制作出一个数字人。诚然,这次的尝试对于像我这样的普通用户来说,确实有些技术性和挑战性,从注册账号到操作界面,都让人觉得步步为营。

今天在实现的过程中,大家也看到了,遇到了各种各样的问题,但是有 GPT 的加持,也就迎刃而解了。正如爬山一般,虽然路途崎岖,却也充满了探索的乐趣和成就感。

微软的这项服务,虽然现阶段似乎更适合那些编程高手和技术达人,但我相信,随着技术的发展和改进,未来一定会有更多适合我们这些普通用户的产品和服务出现。我期待有一天,我们都能轻松地打造和定制属于自己的数字头像,就像在科幻电影中那样激动人心。

以上就是微软数字人的初体验。如有收获,请给元峰点个赞。

参考文章:https://techcommunity.microsoft.com/t5/ai-azure-ai-services-blog/azure-ai-speech-announces-public-preview-of-text-to-speech/ba-p/3981448