https://www.w3.org/TR/2010/REC-speech-synthesis11-20100907/
您可以在 Text-to-Speech 请求中发送语音合成标记语言 (SSML),提供有关暂停以及首字母缩写词、日期、时间、缩写或应予以屏蔽的文本的音频格式等详细信息,以在音频响应中实现更多自定义功能。
以下示例展示了一个 SSML 标记和 Text-to-Speech 合成文本:
<speak>
Here are <say-as interpret-as="characters">SSML</say-as> samples.
I can pause <break time="3s"/>.
I can play a sound
<audio src="https://www.example.com/MY_MP3_FILE.mp3">didn't get your MP3 audio file</audio>.
I can speak in cardinals. Your number is <say-as interpret-as="cardinal">10</say-as>.
Or I can speak in ordinals. You are <say-as interpret-as="ordinal">10</say-as> in line.
Or I can even speak in digits. The digits for ten are <say-as interpret-as="characters">10</say-as>.
I can also substitute phrases, like the <sub alias="World Wide Web Consortium">W3C</sub>.
Finally, I can speak a paragraph with two sentences.
<p><s>This is sentence one.</s><s>This is sentence two.</s></p>
</speak>
以下为示例 SSML 文档的合成文本:
Here are S S M L samples. I can pause [3 second pause]. I can play a sound [audio file plays].
I can speak in cardinals. Your number is ten.
Or I can speak in ordinals. You are tenth in line.
Or I can even speak in digits. The digits for ten are one oh.
I can also substitute phrases, like the World Wide Web Consortium.
Finally, I can speak a paragraph with two sentences. This is sentence one. This is sentence two.
有关使用 SSML 的提示
根据您的实现,您可能需要在发送到 Text-to-Speech 的 SSML 载荷中转义引号。以下示例展示了如何设置 JSON 对象中包含的 SSML 输入的格式。
"{
'input':{
'ssml':'<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>'
},
'voice':{
'languageCode':'en-us',
'name':'en-US-Standard-B',
'ssmlGender':'MALE'
},
'audioConfig':{
'audioEncoding':'MP3'
}
}"
预留字符
避免在要转换为音频的文本中使用 SSML 保留字符。如果需要使用 SSML 预留字符,请使用字符的转义代码防止将字符作为代码读取。下表显示了预留的 SSML 字符及其关联的转义代码。
字符 | 转义码 |
---|---|
” | " |
& | & |
' | ' |
< | < |
> | > |
对 SSML 元素的支持
<speak>
SSML 响应的根元素。
如需详细了解 speak 元素,请参阅 W3 规范。
示例
<speak>
my SSML content
</speak>
<break>
一个空元素,控制字词之间的停顿或其他韵律边界。可以选择在任何一对标记之间使用 <break>。如果字词之间没有此元素,系统会根据语境自动确定中断。
如需详细了解 break 元素,请参阅 W3 规范。
特性 | 说明 |
---|---|
time | 以秒或毫秒为单位设置中断的时长(如“3 秒”或“250 毫秒”)。 |
strength | 用相对概念设置输出韵律中断的强度。有效值包括“极弱”、“弱”、“中等”、“强”和“极强”。值“无”表示不应输出韵律中断边界,这可用于防止处理器以其他方式产生韵律中断。其他值表示标记之间存在单调非递减(概念上增加)的中断强度。较强的边界通常伴随着停顿。 |
示例 以下示例展示了如何使用 <break> 元素在步骤之间停顿:
<speak>
Step 1, take a deep breath. <break time="200ms"/>
Step 2, exhale.
Step 3, take a deep breath again. <break strength="weak"/>
Step 4, exhale.
</speak>
<say‑as>
借助此元素,您可以指明元素中包含的文本构造类型的相关信息。它也有助于指定呈现所含文本的详细程度。
<say‑as> 元素具有必要属性 interpret-as,它决定值的读出方式。可以根据特定的 interpret-as 值选用属性 format 和 detail。
interpret-as 属性支持以下值:
-
currency
以下示例读作“forty two dollars and one cents”。如果省略语言属性,则会使用当前语言区域。
<speak>
<say-as interpret-as='currency' language='en-US'>$42.01</say-as>
</speak>
-
telephone
以下示例读作“one eight zero zero two zero two one two one two”。如果省略“google:style”属性,则会将数字零读作字母 O。
“google:style='zero-as-zero'”属性目前仅适用于 EN 语言区域。
<speak>
<say-as interpret-as='telephone' google:style='zero-as-zero'>1800-202-1212</say-as>
</speak>
-
verbatim 或 spell-out
以下示例会逐个读出字母:
<speak>
<say-as interpret-as="verbatim">abcdefg</say-as>
</speak>
-
date
format 属性是一系列日期字段字符代码。format 支持的字段字符代码包括 {y、m、d},分别代表年、月、日(日期)。如果该字段代码针对年、月或日显示一次,则预期的年月日位数分别为 4、2 和 2。如果该字段代码重复出现,则预期位数是代码重复的次数。日期文本中的字段可用标点符号和/或空格分隔。
detail 属性控制日期的口语形式。对于 detail='1',只需说出日期字段和月或年字段之一,尽管两者都可能提供。这是没有给出所有三个字段时的默认值。口语形式为“The {ordinal day} of {month}, {year}”。
以下示例读作“The tenth of September, nineteen sixty”:
<speak>
<say-as interpret-as="date" format="yyyymmdd" detail="1">
1960-09-10
</say-as>
</speak>
以下示例读作“The tenth of September”:
<speak>
<say-as interpret-as="date" format="dm">10-9</say-as>
</speak>
对于 detail='2',日、月和年字段均为必需,这是所有三个字段都提供时的默认值。口语形式为“{month} {ordinal day}, {year}”。
以下示例读作“September tenth, nineteen sixty”:
<speak>
<say-as interpret-as="date" format="dmy" detail="2">
10-9-1960
</say-as>
</speak>
-
characters
以下示例读作“C A N”:
<speak>
<say-as interpret-as="characters">can</say-as>
</speak>
-
cardinal
以下示例读作“Twelve thousand three hundred forty five”(美式英语)或“Twelve thousand three hundred and forty five”(英式英语):
<speak>
<say-as interpret-as="cardinal">12345</say-as>
</speak>
-
ordinal
以下示例读作“First”:
<speak>
<say-as interpret-as="ordinal">1</say-as>
</speak>
-
fraction
以下示例读作“five and a half”:
<speak>
<say-as interpret-as="fraction">5+1/2</say-as>
</speak>
-
expletive 或 bleep
以下示例发出哔哔声,就像已经被屏蔽了:
<speak>
<say-as interpret-as="expletive">censor this</say-as>
</speak>
-
unit
根据数字将单位转换为单数或复数。以下示例读作“10 feet”:
<speak>
<say-as interpret-as="unit">10 foot</say-as>
</speak>
-
time
以下示例读作“Two thirty P.M.”:
<speak>
<say-as interpret-as="time" format="hms12">2:30pm</say-as>
</speak>
format 属性是一系列时间字段字符代码。format 中支持的字段字符代码为 {h、m、s、Z、12、24},分别表示时、(这个小时的)分、(这个分钟的)秒、时区、12 小时制和 24 小时制。如果该字段代码针对时、分或秒显示一次,则预期的位数分别为 1、2 和 2。如果该字段代码重复出现,则预期位数是代码重复的次数。时间文本中的字段可以用标点符号和/或空格分隔。如果未在格式中指定时、分或秒,或者没有匹配的位数,则该字段将被视为零值。默认 format 为“hms12”。
detail 属性控制时间的口语形式是 12 小时制还是 24 小时制。如果 detail='1' 或者 detail 省略,则口语形式为 24 小时制,时间格式为 24 小时制。如果 detail='2' 或者 detail 省略,则口语形式为 12 小时制,时间格式为 12 小时制。
https://www.w3.org/TR/speech-synthesis/#S3.1.9
<p>,<s>
句子和段落元素。
如需详细了解 p 和 s 元素。
https://www.w3.org/TR/speech-synthesis/#edef_paragraph
<p><s>This is sentence one.</s><s>This is sentence two.</s></p>
最佳做法 使用 <s>...</s> 标记来封装完整的句子,尤其是当它们包含用于改变 prosody 的 SSML 元素(即 <audio>、<break>、<emphasis>、<par>、<prosody>、<say-as>、<seq> 和 <sub>)。如果您希望语音中断的时间足够长,这样您就可以听到它,请使用 <s>...</s> 标记并在句子之间插入该中断。
<sub>
指示在发音时用别名属性值中的文本替换所包含的文本。
您还可以使用 sub 元素来提供难读单词的简化发音。下面的最后一个示例演示了这个用例在日语中的应用。
如需详细了解 sub 元素,请参阅 W3 规范.
https://www.w3.org/TR/speech-synthesis/#edef_sub
<sub alias="World Wide Web Consortium">W3C</sub>
<sub alias="にっぽんばし">日本橋</sub>
<mark>
将标记置于文本或标记序列中的空元素。它可用于引用序列中的特定位置,或将标记插入输出流以进行异步通知。
如需详细了解 mark 元素,请参阅 W3 规范。
https://www.w3.org/TR/speech-synthesis/#S3.3.2
<speak>
Go from <mark name="here"/> here, to <mark name="there"/> there!
</speak>
<prosody>
用于自定义元素中所包含文本的音高、语速和音量。目前支持 rate、pitch 和 volume 属性。
您可以根据 W3 规范设置 rate 和 volume 属性。以下三个选项可用于设置 pitch 属性的值:
https://www.w3.org/TR/speech-synthesis11/#S3.2.4
以下示例使用 <prosody> 元素以低于正常值 2 个半音的音高缓慢说话:
<prosody rate="slow" pitch="-2st">Can you hear me now?</prosody>
<emphasis>
用于添加或移除元素所含文本中的重音。<emphasis> 元素修改语音的方式与 <prosody> 类似,但不需要设置单独的语音属性。
此元素支持可选的“等级”属性,其中包含以下有效值:
-
strong
-
moderate
-
none
-
reduced
如需详细了解 emphasis 元素,请参阅 W3 规范。
https://www.w3.org/TR/speech-synthesis11/#S3.2.2
以下示例使用 <emphasis> 元素发布公告:
<emphasis level="moderate">This is an important announcement</emphasis>
<par>
允许您一次播放多个媒体元素的并行媒体容器。唯一允许的内容是一个或多个 <par>、<seq> 和 <media> 元素构成的序列。<media> 元素的顺序并不重要。
除非子元素指定不同的开始时间,否则元素的隐式开始时间与 <par> 容器的隐式开始时间相同。如果子元素具有为其开始或结束属性设置的偏移值,则元素的偏移量将是相对于 <par> 容器开始时间的值。对于根 <par> 元素,开始属性会被忽略,开始时间是 SSML 语音合成过程开始为根 <par> 元素生成输出的时间(即生效时间为“零”)。
<speak>
<par>
<media xml:id="question" begin="0.5s">
<speak>Who invented the Internet?</speak>
</media>
<media xml:id="answer" begin="question.end+2.0s">
<speak>The Internet was invented by cats.</speak>
</media>
<media begin="answer.end-0.2s" soundLevel="-6dB">
<audio
src="https://actions.google.com/.../cartoon_boing.ogg"/>
</media>
<media repeatCount="3" soundLevel="+2.28dB"
fadeInDur="2s" fadeOutDur="0.2s">
<audio
src="https://actions.google.com/.../cat_purr_close.ogg"/>
</media>
</par>
</speak>
<phoneme>
您可使用 <phoneme> 标记以内嵌方式生成单词的自定义发音。Text-to-Speech 接受 IPA 和 X-SAMPA 语音字母。请参阅 Phones 页面,查看受支持的语言和音素的列表。
每个 <phoneme> 标记的每个应用都指向单个字词的发音:
<phoneme alphabet="ipa" ph="ˌmænɪˈtoʊbə">manitoba</phoneme>
<phoneme alphabet="x-sampa" ph='m@"hA:g@%ni:'>mahogany</phoneme>
重音标记
一个转录最多可存在 3 个级别的重音:
-
主重音:在 IPA 中用 /ˈ/ 表示,在 X-SAMPA 中用 /"/ 表示。
-
次重音:在 IPA 中用 /ˌ/ 表示,在 X-SAMPA 中用 /%/ 表示。
-
无重音:(在任一注释中)未标记有符号。
某些语言可能不到 3 个级别,或者跟踪不标识重音位置。请参阅音素页面,查看适用于您所用语言的重音级别。重音标记放置在每个重音音节的开头。例如,以美式英语为例:
示例字词 | IPA | X-SAMPA |
---|---|---|
water | ˈwɑːtɚ | "wA:t@` |
underwater | ˌʌndɚˈwɑːtɚ | %Vnd@"wA:t@ |
宽式音标与严式音标
一般来说,您的转录必然是更加宽式、音素更强。例如,在美式英语中,转录两个元音间的 /t/(而不是使用点):
示例字词 | IPA | X-SAMPA |
---|---|---|
butter | ˈbʌtɚ instead of ˈbʌɾɚ | "bVt@ instead of "bV4@ |
某些情况下,使用音素表示法会使 TTS 结果听起来不太自然(例如,如果音素序列在结构上很难发音)。
例如在英语中,/s/ 有发音同化的现象。此时,转录中应反映出这种同化:
示例字词 | IPA | X-SAMPA |
---|---|---|
cats | ˈkæts | "k{ts |
dogs | ˈdɑːgz 而非 ˈdɑːgs | "dA:gz 而非 "dA:gs |
弱读
每个音节必须包含一个(且只包含一个)元音。这意味着应避免使用音节辅音,而是使用弱化元音进行转录。例如:
示例字词 | IPA | X-SAMPA |
---|---|---|
kitten | ˈkɪtən 而非 ˈkɪtn | "kIt@n 而非 "kitn |
kettle | ˈkɛtəl 而非 ˈkɛtl | "kEt@l 而非 "kEtl |
音节划分
可选择性地使用 /./ 指定音节标界。每个音节必须包含一个(且只包含一个)元音。例如:
示例字词 | IPA | X-SAMPA |
---|---|---|
可读性 | ˌɹiː.də.ˈbɪ.lə.tiː | %r\i:.d@."bI.l@.ti: |
时长
Text-to-Speech 支持 <say-as interpret-as="duration">
以适当地读取时长。例如,以下示例会被读作“5 小时 30 分钟”:
<say-as interpret-as="duration" format="h:m">5:30</say-as>
格式字符串支持以下值:
缩写词 | 值 |
---|---|
h | 小时 |
m | 分钟 |
s | 秒 |
ms | 毫秒 |
<lang>
您可以使用 <lang>
在同一 SSML 请求中包括多种语言的文本。所有语言都将合成到同一语音中,除非您使用 <voice>
标记明确更改语音。xml:lang
字符串必须包含 BCP-47 格式的目标语言(此值在支持的语音表中列为“语言代码”)。在下面的例子中,“chat”用法语读出来,而不是用默认语言(英语):
<speak>The french word for cat is <lang xml:lang="fr-FR">chat</lang></speak>
Text-to-Speech 会尽量支持 <lang>
标记。如果在同一 SSML 请求中指定了所有语言组合,则并非所有语言组合都会产生相同的质量结果。在某些情况下,某个语言组合可能会产生可检测到但具有微妙或负面感知性的影响。已知问题:
-
<lang>
标记不支持带有汉字字符的日语。输入会被直译且读作中文字符。 -
<lang>
标记不支持闪米特语(如阿拉伯语、希伯来语和波斯语),这些语音导致不读出任何内容。如果要使用上述任一语言,我们建议您使用<voice>
标记切换到使用能读出您想使用的语言的语音(如果有)。
SSML 时间点
Text-to-Speech API 支持在您创建的音频数据中使用时间点。时间点是与脚本中指定点对应的时间戳(以秒为单位,从生成音频时开始计算)。您可以使用 <mark>
标记在脚本中设置时间点。生成音频后,API 会返回音频开始时和时间点之间的时间偏移。
设置时间点需要执行两个步骤:
-
将
<mark>
SSML 标记添加到脚本中您希望其获取时间戳的位置。 -
将 TimepointType 设置为
SSML_MARK
。如果未设置此字段,则默认情况下不返回时间点。
以下示例返回两个时间点:
-
timepoint_1:表示生成的音频中“Mark”一词出现的时间(以秒为单位)。
-
timepoint_2:表示生成的音频中“word”一词出现的时间(以秒为单位)。
<speak>Hello <mark name="timepoint_1"/> Mark. Good to <mark
name="timepoint_2"/> see you.</speak>
参考文献
https://www.w3.org/TR/2010/REC-speech-synthesis11-20100907/
https://cloud.google.com/text-to-speech/docs/ssml?hl=zh-cn
https://github.com/Reverseblade/ssml-builder
https://github.com/sumsted/pyssml/
https://github.com/guest271314/SSMLParser
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/9bb1019326d8c846886627cfd5fffd3e39b3f2bb/texttospeech/snippets/ssml_addresses.py#L74