概述
Linux下,使用Python调用讯飞TTS离线SDK,源代码:
- https://github.com/cch96/iflytek_tts
- 具体使用方法参照readme
解决过程
Windows
Windows的SDK有编译好的可以直接被python用ctypes模块调用的动态链接库。可以直接根据科大讯飞的接口文档以及错误码进行开发调试。
- bin文件夹下的dll
- 接口文档: http://mscdoc.xfyun.cn/windows/api/iFlytekMSCReferenceManual/files.html
- 错误码: https://www.xfyun.cn/document/error-code
Linux
Linux版的SDK没有编译好的so,但是Linux的SDK中有一些函数库的动态链接库。
- libs文件夹下的so
于是开始尝试使用这个库来调用接口,实现功能。在此期间出现了一些问题。
问题1:
在导入libmsc.so时出现异常
OSError: libs/x64/libmsc.so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
该异常是由于讯飞的tts是由c++实现了,需要链接c++的一些基础依赖库。这里是少了lstdc++.so
解决1:
在ctypes
中有两种加载动态链接库的方式ctype.CDLL()
或者ctypes.cdll.load_libary()
,
CDLL
有一个mode的可选参数,mode=ctypes.RTLD_GLOBAL
,可以全局引入动态链接,如果调用的动态库有其它依赖库时,提前加载的功能
把lstdc++.so提前导入即可ctypes.CDLL("lstdc++.so", mode=ctypes.RTLD_GLOBAL)
问题2:
解决了依赖库问题,在调用接口时出现异常
segmentation fault
段错误,访问了不存在或者受限的内存,这个问题涉及到ctypes与c的交互的内部机制,不好解决,于是换了个思路
解决2:
放弃原来的思路,即用ctypes
调用动态链接库中的接口,完成语言合成的逻辑。
改用,用c封装语音合成的逻辑,由它去调用动态链接库中的函数,而python只需要简单调用这些c封装好的接口。
其实官方的sdk中的c语言demo是可用的,把它稍加改造就可以满足我们的要求,就不用自己封装了。
最终解决
-
官方demo改成接口模块,并编译成so
$gcc -c -fPIC -o mylib.o tts_offline_sample.c
$gcc -shared -o libtts.so mylib.o -
将libstdc++.so, libmsc.so, libtts.so都加载进来
def __new__(cls, *args, **kwargs): # 加载库 ctypes.CDLL("libstdc++.so.6", mode=ctypes.RTLD_GLOBAL) plat = platform.architecture() if plat[0] == '32bit': dll = CDLL(os.path.join(WORK_ROOT, 'libs/x86/libmsc.so'), mode=ctypes.RTLD_GLOBAL) else: dll = CDLL(os.path.join(WORK_ROOT, 'libs/x64/libmsc.so'), mode=ctypes.RTLD_GLOBAL) cls.dll = cdll.LoadLibrary(os.path.join(WORK_ROOT, "libtts.so")) cls.lock = threading.RLock() return super(IflytekTTS, cls).__new__(cls)
-
python去调用libtts.so中的接口
def text2wav(self, text, filename): """文字合成语音""" # 底层的c是不支持多线程的,所以这里限制一下 with self.lock: ret = self.dll.msp_login(None, None, self.login_params) if (self.MSP_SUCCESS != ret): # 如果登陆验证失败 print("MSPLogin failed, error code: %d.n", ret) return # 登陆成功 # print("开始合成 ...n") ret = self.dll.text_to_speech(text, filename, self.session_begin_params) # print("合成完毕n") # 退出登录 self.dll.msp_logout()
第一次写博客,若有哪里不对请大家斧正
参考
https://blog.csdn.net/weizehua/article/details/88305752
https://blog.csdn.net/u013783095/article/details/79639754
https://www.cnblogs.com/hello–the-world/archive/2012/05/31/2528326.html
https://www.landui.com/help/show-7989
最后
以上就是发嗲路灯为你收集整理的Linux下 python调用讯飞离线语音合成(tts)的全部内容,希望文章能够帮你解决Linux下 python调用讯飞离线语音合成(tts)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复