在 Azure 语音服务的 REST 接口上送 SSML 给 zh-CN-XiaoxiaoNeural,版本是 2024-04-01,文本里写了
一开始怀疑是「转义后的尖括号被服务端过滤,只剩正文」,查了一圈,方向不对。
真正麻烦的地方在于,几个原因的现象几乎一样。该声音在部分区域端点不支持 break 标签的毫秒时长。也可能是SSML 被 SDK 二次转义,标签当成普通文本读了出来。
少数情况下是输出格式用的是低码率 mp3,静音被编码器裁掉了。
先用最简 SSML 确认 break 是否生效
curl -X POST "https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1" -H "Ocp-Apim-Subscription-Key: $KEY" -H "Content-Type: application/ssml+xml" -H "X-Microsoft-OutputFormat: riff-24khz-16bit-mono-pcm" --data-binary @ssml.xml -o out.wav
接着把输出改成无损 wav 排除编码器裁静音
ffprobe -v error -show_entries stream=codec_name,sample_rate out.wav
再往下用静音检测量出停顿长度
ffmpeg -i out.wav -af silencedetect=noise=-40dB:d=0.3 -f null -
等前面都确认过,再改用 prosody 的 rate 参数控制节奏再对比
curl -X POST "https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1" -H "Ocp-Apim-Subscription-Key: $KEY" -H "Content-Type: application/ssml+xml" --data-binary @ssml2.xml -o out2.wav
改完先别撤,确认这几项。silencedetect 输出的静音区间长度接近设定的 800ms,两个版本合成的音频在波形上能看到明显间隙。
mp3 编码会裁掉首尾静音,用 break 调停顿一定要输出 wav 验证,只看播放效果容易把编码问题当成标签不生效。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
