如何在XSwitch中使用Edge TTS

如何使用XSwitch内置的离线ASR及TTS中我们已经学会如何使用离线ASR及TTS,但由于espeak-ng放出来的声音不好听,在我们不屑努力下,终于找到一个声音更加清晰流畅且可以免费使用的的TTS引擎edge-tts

文末有edge-ttsespeak-ng生成的音频实例,以供大家参考。

本文中所讲TTS是基于mod_tts_commandline模块实现的,上一篇文章已经说明如何使用该模块,不再赘述。

为了防止XSwitch镜像体积过大,XSwitch中默认不带edge-tts,如果需要使用,可以自行安装:

make bash                            # 进入XSwitch容器
apt-get update                       # 更新Linux软件源数据
apt-get install python3-pip          # 安装Python pip
pip install edge-tts                 # 安装edge-tts

安装完成后,可以在容器内使用以下命令测试是否成功:

edge-tts --text "Hello world" --write-media /tmp/hello.mp3

可以在宿主机上使用如下命令将该文件从容器中Copy出来:

docker cp xswitch:/tmp/hello.mp3 .

如果这个声音文件正常,那表示edge-tts已经安装成功了。如果有其它问题可以参见edge-tts

接下来我们开始改造它,目的是能让它根据Voice类型自动选择需要使用的TTS模型。

修改tts_commandline.conf.xml

若你使用的XSwitch版本为4.0.2及以上,可跳过此步骤,直接进行配置路由规则

  • 将原始的espeak-ng -v ${voice} -w ${file} ${text}修改为sh $${scripts_dir}/scripts/tts.sh ${voice} ${file} ${text}

  • tts_commandline.conf.xml新增auto-unlink:

	<param name="auto-unlink" value="false"/>

auto-unlinktrue时,通话结束后会自动删除生成的音频文件,为false时,则不删除音频文件。

  • tts_commandline.conf.xml新增voice map
<ext-maps>
	<map ext="mp3" voice="zh-CN-YunxiNeural"/>
	<map ext="mp3" voice="zh-CN-YunyangNeural"/>
	<map ext="mp3" voice="zh-CN-XiaoxiaoNeural"/>
	<map ext="mp3" voice="zh-CN-XiaoyiNeural"/>
	<map ext="mp3" voice="zh-CN-YunjianNeural"/>
	<map ext="mp3" voice="zh-CN-YunxiaNeural"/>
	<map ext="mp3" voice="zh-TW-HsiaoChenNeural"/>
	<map ext="mp3" voice="zh-HK-HiuMaanNeural"/>
	<map ext="mp3" voice="en-IE-EmilyNeural"/>
	<map ext="mp3" voice="en-US-AriaNeural"/>
	<map ext="mp3" voice="en-US-GuyNeural"/>
	<map ext="mp3" voice="en-US-JennyNeural"/>
	<map ext="mp3" voice="en-GB-SoniaNeural"/>
	<map ext="mp3" voice="cy-GB-NiaNeural"/>
</ext-maps>

退出保存,在命令行上重新加载模块:

reload mod_tts_commandline

其中$${scripts_dir}/xui/tts.shtts.sh脚本存放路径。该脚本和tts_commandline.conf.xml实例见文末。

当然,也可以在XUI界面上重新加载。

注意,如果我们想使用edge-tts提供的其他Voice,则需将对应的ShortName如以上方式新增到配置文件内,并重新加载mod_tts_commandline即可。

若仍然使用espeak-ng,无需修改配置文件!

edge-tts提供的Voice列表,可通过edge-tts --list-voice查询,下方为edge-tts常用Voice

ShortNameGenderLocale
zh-CN-XiaoxiaoNeuralFemalezh-CN
zh-CN-XiaoyiNeuralFemalezh-CN
zh-CN-YunjianNeuralMalezh-CN
zh-CN-YunxiNeuralMalezh-CN
zh-CN-YunxiaNeuralMalezh-CN
zh-CN-YunyangNeuralMalezh-CN
zh-TW-HsiaoChenNeuralFemalezh-TW
zh-HK-HiuMaanNeuralFemalezh-HK
en-IE-EmilyNeuralFemaleen-IE
en-US-AriaNeuralFemaleen-US
en-US-GuyNeuralMaleen-US
en-US-JennyNeuralFemaleen-US
en-GB-SoniaNeuralFemaleen-GB
cy-GB-NiaNeuralFemalecy-GB

配置路由规则

上一篇文章中我们提到在“文本”框中填入以下内容:

answer
speak tts_commandline|zh|你好,欢迎致电烟台小樱桃网络科技有限公司

上面这种方式使用的是默认TTS引擎是espeak-ng,XSwitch内置,但是不大好听。

接下来我们修改“文本”框中的内容如下:

answer
speak tts_commandline|zh-CN-XiaoxiaoNeural|你好,欢迎致电烟台小樱桃网络科技有限公司

其中zh-CN-XiaoxiaoNeuraledge-tts提供的Voice

然后当我们呼叫tts测试时,mod_tts_commandline会识别到我们使用的Voicezh-CN-XiaoxiaoNeural,它会自动选用edge-tts为我们播放离线TTS语音。

注意,由于edge-tts合成的音频文件格式为.mp3,需要确保在XSwitch中提前加载了mod_shout模块,否则会出现不支持mp3格式的报错!

tts.sh实例如下,也可根据你的实际需要进行修改:

#!/bin/sh

voice=$1;
file=$2;
text=$3;

if [ -f "$file" ]; then
    exit
fi

case "$voice" in
    "zh-CN-XiaoxiaoNeural" \
    | "zh-CN-YunyangNeural" \
    | "zh-CN-YunxiNeural" \
    | "zh-CN-XiaoyiNeural" \
    | "zh-CN-YunjianNeural" \
    | "zh-CN-YunxiaNeural" \
    | "zh-TW-HsiaoChenNeural" \
    | "zh-HK-HiuMaanNeural" \
    | "en-IE-EmilyNeural" \
    | "en-US-AriaNeural" \
    | "en-US-GuyNeural" \
    | "en-US-JennyNeural" \
    | "en-GB-SoniaNeural" \
    | "cy-GB-NiaNeural")
        edge-tts --text "$text" --voice "$voice"  --write-media "$file"
        ;;
    *)
        espeak-ng -s 220 -v "$voice" -w "$file" "$text";
esac

exit

tts_commandline.conf.xml配置如下:

<configuration name="tts_commandline.conf" description="TextToSpeech Commandline configuration">
    <settings>
    <!--
    Some variables will be replaced :
    ${text}: input text (quoted)
    ${rate}: sample rate (example: 8000)
    ${voice}: voice_name passed to TTS(quoted)
    ${file}: output file (quoted, including .wav extension)

    Example commands can be found at:
    https://freeswitch.org/confluence/display/FREESWITCH/mod_tts_commandline#mod_tts_commandline-Examplecommands
    -->
    <param name="command" value="sh $${scripts_dir}/scripts/tts.sh ${voice} ${file} ${text}"/>
    <param name="auto-unlink" value="false"/>
    </settings>
    <ext-maps>
		<map ext="mp3" voice="zh-CN-YunxiNeural"/>
		<map ext="mp3" voice="zh-CN-YunyangNeural"/>
		<map ext="mp3" voice="zh-CN-XiaoxiaoNeural"/>
		<map ext="mp3" voice="zh-CN-XiaoyiNeural"/>
		<map ext="mp3" voice="zh-CN-YunjianNeural"/>
		<map ext="mp3" voice="zh-CN-YunxiaNeural"/>
		<map ext="mp3" voice="zh-TW-HsiaoChenNeural"/>
		<map ext="mp3" voice="zh-HK-HiuMaanNeural"/>
		<map ext="mp3" voice="en-IE-EmilyNeural"/>
		<map ext="mp3" voice="en-US-AriaNeural"/>
		<map ext="mp3" voice="en-US-GuyNeural"/>
		<map ext="mp3" voice="en-US-JennyNeural"/>
		<map ext="mp3" voice="en-GB-SoniaNeural"/>
		<map ext="mp3" voice="cy-GB-NiaNeural"/>
    </ext-maps>
</configuration>

音频示例

俗话说百闻不如一见,但这里,不管怎么说都不如一“闻”,听听有什么区别。

  • edge-tts
  • espeak-ng

小结

  • edge-tts好听,但需要连网
  • espeak-ng可以离线使用,但听着有点难受
  • 两者都支持中、英文等多种语言
  • 两者都可以免费使用,在开发、测试时用起来很方便

相关文章