Linux下,使用Python调用讯飞TTS离线SDK,源代码:
/cch96/iflytek_tts具体使用方法参照readme解决过程
Windows
Windows的SDK有编译好的可以直接被python用ctypes模块调用的动态链接库。可以直接根据科大讯飞的接口文档以及错误码进行开发调试。
bin文件夹下的dll
接口文档:/windows/api/iFlytekMSCReferenceManual/files.html错误码:/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()
第一次写博客,若有哪里不对请大家斧正
参考
/weizehua/article/details/88305752
/u013783095/article/details/79639754
/hello–the-world/archive//05/31/2528326.html
/help/show-7989