本文介绍SSML(Speech Synthesis Markup Language)标记语言的功能、标签用法及示例。
概述
SSML是一种基于XML的语音合成标记语言,用于控制断句、分词、发音、语速、停顿、音高和音量,以及添加背景音乐。
智能语音交互的SSML实现基于W3C SSML 1.0,支持本文列出的标签,并非全部W3C标签。
使用方式
目前SSML仅支持中文和英文音色。两种语言支持的标签及内容有所不同,具体以各标签的说明为准。
-
短文本语音合成的文本须包含在一个
<speak>...</speak>根元素中。<speak>前可以省略XML声明。 -
长文本任务(包括实时长文本合成和异步长文本合成)可以包含多个成对的
<speak>...</speak>标签,也可以将SSML与纯文本混用。以下文本可作为一次长文本语音合成请求传入。使用Java SDK实时长文本语音合成时,通过setLongText设置文本。<speak><say-as interpret-as="telephone">114</say-as>查询号码 <say-as interpret-as="cardinal">123</say-as>开始干。加起来为<say-as interpret-as="digits">1234</say-as>。<say-as interpret-as="name">张三</say-as>的快递。<say-as interpret-as="address">富路国际1号楼3单元304</say-as><say-as interpret-as="nick">李四6689</say-as></speak>
标签内容和属性中的XML特殊字符需要转义:"写为",'写为',&写为&,<写为<,>写为>。
将SSML文本作为语音合成请求的text参数传入。以下展示Java SDK调用片段及对应的请求内容。完整的客户端初始化和调用流程,请参见Java SDK。
Java SDK调用片段:
SpeechSynthesizer synthesizer = new SpeechSynthesizer(client, getSynthesizerListener());
String text = "<speak>请闭上眼睛休息一下<break time=\"500ms\"/>好了,请睁开眼睛。</speak>";
synthesizer.setText(text);
对应的请求内容:
{
"payload": {
"volume": 50,
"sample_rate": 16000,
"format": "wav",
"text": "<speak>请闭上眼睛休息一下<break time=\"500ms\"/>好了,请睁开眼睛。</speak>"
},
"context": {
"sdk": {
"name": "nls-sdk-java",
"version": "2.0.4"
}
},
"header": {
"namespace": "SpeechSynthesizer",
"name": "StartSynthesis",
"message_id": "5fdf78c0dd574b6897f3cb204dd0****",
"appkey": "fd4er4aa****",
"task_id": "6e1be78ef5804c50a2c5a8b92de1****"
}
}
标签
<speak>
<speak>标签是所有待支持SSML标签的根节点。一切需要调用SSML标签的文本都要包含在<speak></speak>中。
<speak>需要调用SSML标签的文本</speak>
属性
<speak>标签支持如下属性。
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
线上可调用的发音人的名称代号,为全小写的 |
否 |
阿里巴巴语音合成特有标签。在合成时,指定发音人,优先级高于接口请求参数 “xiaoyue”暂不支持在voice中设置。 |
|
|
String |
PCM/WAV/MP3 |
否 |
阿里巴巴语音合成特有标签。在合成时,指定音频文件格式,优先级高于接口请求参数 实时长文本任务在SSML标签中设置 |
|
|
String |
8000/16000/24000/48000 |
否 |
阿里巴巴语音合成特有标签。在合成时,指定音频的采样率,优先级高于接口请求参数 实时长文本任务在SSML标签中设置 |
|
|
String |
[-500,500]之间的整数。默认值为0。
|
否 |
阿里巴巴语音合成特有标签。在合成时,指定音频的语速,优先级高于接口请求参数 |
|
|
String |
[-500,500]之间的整数。默认值为0。
|
否 |
阿里巴巴语音合成特有标签。在合成时,指定音频的音高,优先级高于接口请求参数 |
|
|
String |
[0,100]之间的整数。默认值为50。
|
否 |
阿里巴巴语音合成特有标签。在合成时,指定音频的音量,优先级高于接口请求参数 |
|
|
String |
robot/lolita/lowpass/echo/eq/lpfilter/hpfilter |
否 |
阿里巴巴语音合成特有标签。使用该标签可以使合成的语音产生不同的声音效果。
|
|
|
String |
当effect取值为eq/lpfilter/hpfilter时,使用该参数修改效果器的默认效果。 |
否 |
|
|
|
String |
线上可调用的背景音乐的名称。详情请参见bgm属性说明。 |
否 |
阿里巴巴语音合成特有标签。为合成的语音添加指定的背景音乐。 |
|
|
String |
[0,100]之间的整数。默认值为50。
|
否 |
阿里巴巴语音合成特有标签。控制背景音乐的音量。 |
bgm属性说明
内嵌背景音乐
目前阿里巴巴语音合成服务内嵌如下几款背景音乐供体验:
自定义背景音乐
将自定义背景音存放在OSS,并确保文件URL可通过HTTP/HTTPS访问。创建Bucket,请参见创建存储空间;上传文件和获取文件URL,请参见控制台快速入门。
音频要求:
-
采样率16 kHz、单声道WAV格式。
-
短文本语音合成的背景音不超过2.8 MB。长文本语音合成的背景音不超过7.3 MB。
-
合成时长超出背景音时长时,背景音将随合成音频循环播放(如果背景音不是WAV格式,可使用ffmpeg将其转为WAV格式:
ffmpeg -i 输入音频 -acodec pcm_s16le -ac 1 -ar 16000 目标.wav)。 -
标签内的URL如果包含XML的特殊字符,需要做字符转义。
-
位深度要求16位。
需要对上传的音频版权承担相应的法律责任。
示例
空属性
<speak>
需要调用SSML标签的文本
</speak>
音频效果:SSML-speak1.mp3
voice属性
<speak voice="xiaogang">
我是男声。
</speak>
音频效果:SSML-speak2.mp3
encodeType属性
<speak encodeType="mp3">
我可以生成压缩格式的音频。
</speak>
音频效果:SSML-encode.mp3
sampleRate属性
<speak sampleRate="8000">
看看我的文件大小吧,是16000采样率音频的一半。
</speak>
音频效果:SSML-speak4.mp3
rate属性
<speak rate="200">
我的语速比正常人快。
</speak>
音频效果:SSML-speak5.mp3
pitch属性
<speak pitch="-100">
我的音高却比别人低。
</speak>
音频效果:SSML-speak6.mp3
volume属性
<speak volume="80">
我的音量也很大。
</speak>
音频效果:SSML-speak7.mp3
属性组合(空格分隔)
<speak rate="200" pitch="-100" volume="80">
所以放在一起,我的声音是这样的。
</speak>
音频效果:SSML-speak8.mp3
effect属性
<speak effect="robot">
你喜欢机器人瓦力吗?
</speak>
音频效果:SSML-speak9.mp3
bgm属性
<speak bgm="http://nls.alicdn.com/bgm/2.wav" backgroundMusicVolume="30" rate="-500" volume="40">
<break time="2s"/>
阴崖老木苍苍烟
<break time="700ms"/>
雨声犹在竹林间
<break time="700ms"/>
绵蕝固知裨国计
<break time="700ms"/>
绵州风物总堪怜
<break time="2s"/>
</speak>
音频效果:SSML-speak10.mp3
标签关系
<speak>标签可以包含文本和以下标签:
-
<break>
-
<s>
-
<w>
-
<phoneme>
-
<say-as>
-
<vhml/>
<emotion>
<emotion>用于多情感声音合成,该标签是可选标签,不支持多情感声音合成的发音人使用情感标签会导致合成请求报错。
<emotion category="happy" intensity="1.0">今天天气真不错!</emotion>
属性
<emotion>标签支持如下属性。
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
枚举值:如neutral, happy。 |
是 |
指定说话情绪。每个发音人支持的情绪参见下表所示。 |
|
|
String |
浮点值:数值范围 [0.01,2.0]。 |
否 |
指定情绪强度。默认值为1.0,表示预定义的情绪强度。最小值为0.01,导致目标情绪略有倾向。最大值为2.0,导致目标情绪强度加倍。 |
其中,多情感声音支持说明如下。
|
音色名 |
|
情感分类(emotion category) |
|
知锋_多情感 |
zhifeng_emo |
angry,fear,happy,neutral,sad,surprise |
|
知冰_多情感 |
zhibing_emo |
angry,fear,happy,neutral,sad,surprise |
|
知妙_多情感 |
zhimiao_emo |
serious,sad,disgust,jealousy,embarrassed,happy,fear,surprise,neutral,frustrated,affectionate,gentle,angry,newscast,customer-service,story,living |
|
知米_多情感 |
zhimi_emo |
angry,fear,happy,hate,neutral,sad,surprise |
|
知燕_多情感 |
zhiyan_emo |
neutral,happy,angry,sad,fear,hate,surprise,arousal |
|
知贝_多情感 |
zhibei_emo |
neutral,happy,angry,sad,fear,hate,surprise |
|
知甜_多情感 |
zhitian_emo |
neutral,happy,angry,sad,fear,hate,surprise |
示例
<speak voice="zhitian_emo">
<emotion category="happy" intensity="1.0">今天天气真不错!</emotion>
</speak>
音频效果:SSML-emotion.wav
标签关系
<emotion>标签可以包含文本和以下标签:
-
<s>
-
<sub>
-
<say-as>
-
<w>
-
<phoneme>
-
<soundEvent/>
-
<break/>
-
<vhml/>
<break>
用于在文本中插入停顿,该标签是可选标签。
<!-- 不指定属性 -->
<break/>
<!-- 指定time属性 -->
<break time="string"/>
属性
使用无属性的<break>标签时,停顿时长为“1s”。
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
[number]s/[number]ms |
否 |
以秒/毫秒为单位设置停顿的时长 (如“2s”、“50ms”)。
|
连续出现多个<break>标签时,停顿时长为各标签停顿时长之和,若总时长超过10秒,则只生效10秒。
例如,在以下示例中,连续3个<break>标签的总停顿时长为15秒,但由于超过10秒,最终有效停顿时长为10秒。
<speak>
请闭上眼睛休息一下<break time="5s"/><break time="5s"/><break time="5s"/>好了,请睁开眼睛。
</speak>
示例
<speak>
请闭上眼睛休息一下<break time="500ms"/>好了,请睁开眼睛。
</speak>
音频效果:SSML-break.mp3
标签关系
<break>是空标签,不能包含任何标签。如果SSML结构中存在<s>标签,请把<break>写在<s>里面,表示对当前段落或句子设置停顿。
<s>
用于表示文本的句子结构,该标签是可选标签。
<s>文本</s>
属性
无。
示例
<speak><s>这是第一句话</s><s>这是第二句话</s></speak>
音频效果:SSML-s.mp3
标签关系
<s>标签可以包含文本和以下标签:
-
<break>
-
<w>
-
<phoneme>
-
<say-as>
-
<vhml/>
<sub>
使用别名替换标签内文本。
<sub alias="string"></sub>
属性
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
替换后的内容 |
是 |
用于替换标签内的文本。 |
示例
<speak><sub alias="网络协议标准">W3C</sub></speak>
音频效果:SSML-sub.mp3
标签关系
<sub>标签可以包括文本及<vhml/>。
<w>
用于表示文本的词语结构,该标签是可选标签。英文文本通常采用空格来进行分词,一般无需使用此标签。<w>标签内部必须是一个独立的词或短语,这个词或短语不允许混合使用中文和其他外语。
<w>文本</w>
属性
无。
示例
<speak>南京市长<w>江大桥</w>今天发表了演讲。</speak>
音频效果:SSML-w.mp3
标签关系
<w>标签可以包含文本和<vhml/>
<vhml>
获取动画标记的时间戳前,在语音合成请求中设置enable_subtitle=true和enable_phoneme_timestamp=true。
<vhml/>是虚拟人类标记语言标签,用于在文本中插入人体和面部表情的动画标记。src属性为自定义字符串,其值会在时间戳中返回,可用于驱动虚拟人的面部或肢体动画。标记内容出现在text中,phoneme为字符串"null",begin_index、end_index、begin_time、end_time均为0。
通常,<vhml>标记在时间戳中的顺序与原文本中的顺序一致。如果标记位于需要正则化的文本内部或旁边(例如,123会正则化为“一百二十三”),返回标记的位置可能与原文本不一致,但多个<vhml>标记之间的顺序不会错乱。
<vhml src="content"/>
属性
无。
示例
<speak><vhml src="start"/>我们今天来<vhml src="t0"/>介绍一下这个新商品<vhml src="end"/></speak>
时间戳结果如下:
{
"subtitles":[
{
"text":"start",
"phoneme":"null",
"begin_index":0,
"end_index":0,
"begin_time":0,
"end_time":0
},
{
"text":"我",
"phoneme":"null",
"begin_index":0,
"end_index":1,
"begin_time":0,
"end_time":88
},
{
"text":"们",
"phoneme":"null",
"begin_index":1,
"end_index":2,
"begin_time":88,
"end_time":238
},
{
"text":"今",
"phoneme":"null",
"begin_index":2,
"end_index":3,
"begin_time":238,
"end_time":450
},
{
"text":"天",
"phoneme":"null",
"begin_index":3,
"end_index":4,
"begin_time":450,
"end_time":650
},
{
"text":"来",
"phoneme":"null",
"begin_index":4,
"end_index":5,
"begin_time":650,
"end_time":825
},
{
"text":"t0",
"phoneme":"null",
"begin_index":0,
"end_index":0,
"begin_time":0,
"end_time":0
},
{
"text":"介",
"phoneme":"null",
"begin_index":5,
"end_index":6,
"begin_time":825,
"end_time":988
},
{
"text":"绍",
"phoneme":"null",
"begin_index":6,
"end_index":7,
"begin_time":988,
"end_time":1213
},
{
"text":"一",
"phoneme":"null",
"begin_index":7,
"end_index":8,
"begin_time":1213,
"end_time":1325
},
{
"text":"下",
"phoneme":"null",
"begin_index":8,
"end_index":9,
"begin_time":1325,
"end_time":1525
},
{
"text":"这",
"phoneme":"null",
"begin_index":9,
"end_index":10,
"begin_time":1525,
"end_time":1663
},
{
"text":"个",
"phoneme":"null",
"begin_index":10,
"end_index":11,
"begin_time":1663,
"end_time":1750
},
{
"text":"新",
"phoneme":"null",
"begin_index":11,
"end_index":12,
"begin_time":1750,
"end_time":1950
},
{
"text":"商",
"phoneme":"null",
"begin_index":12,
"end_index":13,
"begin_time":1950,
"end_time":2188
},
{
"text":"品",
"phoneme":"null",
"begin_index":13,
"end_index":14,
"begin_time":2188,
"end_time":2538
},
{
"text":"end",
"phoneme":"null",
"begin_index":0,
"end_index":0,
"begin_time":0,
"end_time":0
}
]
}
标签关系
<vhml/>是一个空标签。
<phoneme>
用于控制标签内文本的读音,该标签是可选标签。英文文本不支持该标签。
<phoneme alphabet="string" ph="string">文本</phoneme>
属性
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
py |
是 |
“py”表示拼音。 |
|
|
String |
标签内文本对应的拼音串 |
是 |
拼音用法的赋值规范:
|
示例
<speak>
去<phoneme alphabet="py" ph="dian3 dang4 hang2">典当行</phoneme>把这个玩意<phoneme alphabet="py" ph="dang4 diao4">当掉</phoneme>
</speak>
音频效果:SSML-phoneme.mp3
标签关系
<phoneme>标签可以包括文本和<vhml/>。
<soundEvent>
提示音标签,可以在SSML合成过程中,通过该标签在任意位置插入提示音。
<soundEvent src="URL"/>
属性
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
URL提示音资源路径 |
是 |
将自定义提示音存放在OSS,并确保文件URL可通过HTTP/HTTPS访问。创建Bucket,请参见创建存储空间;上传文件和获取文件URL,请参见控制台快速入门。 音频要求:
重要
需要对上传的音频版权承担相应的法律责任。 |
示例
<speak>
一匹马受了惊吓<soundEvent src="http://nls.alicdn.com/sound-event/horse-neigh.wav"/>人们四散躲避
</speak>
音频效果:SSML-sound-event.mp3
标签关系
<soundEvent>是空标签,不可以包含任何标签。
<say-as>
用于指示出标签内文本的信息类型,进而按照该类型的默认发音方式发音。
<say-as interpret-as="string">文本</say-as>
属性
|
属性名称 |
属性类型 |
属性值 |
是否必选 |
描述 |
|
|
String |
cardinal/digits/telephone/name/address/id/characters/punctuation/date/time/currency/measure |
是 |
指示出标签内文本的信息类型:
|
示例
cardinal
<speak>
<say-as interpret-as="cardinal">12345</say-as>
</speak>
中文音频效果:SSML-say-as_Cardinal.mp3
<speak>
<say-as interpret-as="cardinal">10234</say-as>
</speak>
英文音频效果:en-SSML-say-as_cardinal.mp3
digits
<speak>
<say-as interpret-as="digits">12345</say-as>
</speak>
中文音频效果:SSML-say-as_digit.mp3
<speak>
<say-as interpret-as="digits">10234</say-as>
</speak>
英文音频效果:en-SSML-say-as_digits.mp3
telephone
<speak>
<say-as interpret-as="telephone">12345</say-as>
</speak>
中文音频效果:SSML-say-as_Telephone.mp3
<speak>
<say-as interpret-as="telephone">10234</say-as>
</speak>
英文音频效果:en-SSML-say-as_telephone.mp3
name
<speak>
她的曾用名是<say-as interpret-as="name">曾小凡</say-as>
</speak>
音频效果:SSML-say-as_Name.mp3
address
<speak>
<say-as interpret-as="address">富路国际1号楼3单元304</say-as>
</speak>
id
<speak>
<say-as interpret-as="id">myid_1998</say-as>
</speak>
音频效果:SSML-say-as_id.mp3
characters
<speak>
<say-as interpret-as="characters">希腊字母αβ</say-as>
</speak>
中文音频效果:SSML-say-as_characters.mp3
<speak>
<say-as interpret-as="characters">*b+3.c$=α</say-as>
</speak>
punctuation
<speak>
<say-as interpret-as="punctuation"> -./:;</say-as>
</speak>
date
<speak>
<say-as interpret-as="date">1000-10-10</say-as>
</speak>
中文音频效果:SSML-say-as_date.mp3
<speak>
<say-as interpret-as="date">10-01-2020</say-as>
</speak>
英文音频效果:en-SSML-say-as_date.mp3
time
<speak>
<say-as interpret-as="time">5:00am</say-as>
</speak>
中文音频效果:SSML-say-as_time.mp3
<speak>
<say-as interpret-as="time">0500</say-as>
</speak>
英文音频效果:en-SSML-say-as_time.mp3
currency
<speak>
<say-as interpret-as="currency">13,000,000.00RMB</say-as>
</speak>
中文音频效果:SSML-say-as_currency.mp3
<speak>
<say-as interpret-as="currency">$1,000.01</say-as>
</speak>
英文音频效果:en-SSML-say-as_currency.mp3
measure
<speak>
<say-as interpret-as="measure">100m12cm6mm</say-as>
</speak>
中文音频效果:SSML-say-as_measure.mp3
<speak>
<say-as interpret-as="measure">1,000.01kg</say-as>
</speak>
英文音频效果:en-SSML-say-as_measure.mp3
标签关系
<say-as>标签可以包括文本及<vhml/>。
综合示例
以下示例演示多种标签的组合用法。音频效果:综合示例.mp3。
-
示例样音中旁白发音人使用的是定制声音,暂没有开放。体验定制声音,请参见语音合成声音定制。
-
短文本语音合成每次请求的文本不能超过300字符,且只能包含一个
<speak>根元素。以下示例包含多个<speak>片段,使用短文本语音合成时需要按片段分次提交。
<speak>
相传北宋年间,
<say-as interpret-as="date">1121-10-10</say-as>,
<say-as interpret-as="address">开封城</say-as>
郊外的早晨笼罩在一片
<sub alias="双十一">11.11</sub>
前买买买的欢乐海洋中。一支运货的骡队刚进入城门
<soundEvent src="http://nls.alicdn.com/sound-event/bell.wav"/>
一个肤白貌美
<phoneme alphabet="py" ph="de5">地</phoneme>
姑娘便拦下第一排的小哥<say-as interpret-as="name">阿发。</say-as>
</speak>
<speak voice="xiaomei">
“亲,本店今日特惠,鞋履全场
<say-as interpret-as="digits">199</say-as>
减
<say-as interpret-as="cardinal">100</say-as>,
走过路过不要错过”。
</speak>
<speak voice="sicheng" rate="150">
“不啦不啦,赶着上货,已经
<say-as interpret-as="time">09:59:59</say-as>
了,再晚就供应链断裂了”。
</speak>
<speak>
<say-as interpret-as="name">阿发</say-as>
擦了擦汗,带着运货队伍,径直穿过闹巷,耳边充斥着各种叫卖声:
</speak>
<speak voice="ninger" rate="200">
最新花色现染布匹,买两尺送一尺;
</speak>
<speak voice="xiaobei">
爆款纱帽头盔,7天无理由退货;
</speak>
<speak voice="sijia">
专治大小方脉,调理男人妇人疑难杂症。
</speak>
<speak>
突然,一匹马不知怎么受了惊,在路上嘶鸣狂奔
<soundEvent src="http://nls.alicdn.com/sound-event/horse-neigh.wav"/>
一个孩子也吓坏了,跌跌撞撞地扑向大人怀里
<break time="50ms"/>大喊道:
</speak>
<speak voice="sitong" rate="150">
“妈妈,妈妈!”
</speak>
<speak>
这时,
<say-as interpret-as="name">阿发</say-as>
心想
</speak>
<speak effect="robot" pitch="-100">
“吓死宝宝了!”
</speak>
<speak>
于是他赶紧捂住了
<phoneme alphabet="py" ph="he2 bao1">钱包</phoneme>,
继续赶路送货。一路上,
<say-as interpret-as="address">开封城</say-as>
的繁荣景象给
<say-as interpret-as="name">阿发</say-as>
留下了深刻的印象。
</speak>
<speak bgm="http://nls.alicdn.com/bgm/2.wav" backgroundMusicVolume="30" rate="-200">
物换星移,繁华落尽,于是他在购物狂欢之余握起画笔,勾勒出一幅长卷,并命名为《清明上河图》。
</speak>