Android 实现云知声版离线语音合成
作者: 灵魂的沉浮
简介
科大讯飞:合成速度快,准确度高,模型多。但问题也是相当明显,只有在线合成是免费的,离线则是一笔不小的开销。
百度:是专门为他的导航做的一套,性能相对也还可以,但是他只支持离在线混合模式,默认是在wifi情况下是使用在线模式,4g或无网络情况下使用离线模式。
云知声:则可以实现完全的离线合成模式,相比于前两个,性能可能没那没完美,不过对合成的语音要求不高的应用来说,可以考虑接入,缺点就是模型比较少。
在线合成和离线合成(合成速度)
在线合成必须将数据传到第三方平台,调用他们的服务接口进行合成,这中间牵扯到网络状况,在网络良好的情况下,合成速度和离线模式没有太大的差别,但是有时候服务器也会来开个小差,无法保证网络一直都是畅通无阻的。在线模式虽然不太稳定,但是不需要把模型和合成底层代码放在本地,离线合成虽然稳定快速,但是apk体积增加的有点小夸张。
云知声的解决办法:把语音合成模型放在服务器后端,你要使用的时候下载到本地。
集成方法
注册云知声开发者,创建应用,下载离线语音合成sdk,里面就两个文件。
将这里面的所有东西都拷贝到你的项目的对应的libs下(比如app目录下的libs)
在app模块的 build.gradle的defaultConfig括号下加上
ndk { abiFilters 'armeabi' } sourceSets { main { jniLibs.srcDirs = ['libs'] } }
截图如下:
在AndroidManifest.xml设置所需要的权限
<!-- 网络权限 --> <uses-permission android:name="android.permission.INTERNET"/> <!-- sd卡获得写的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 获取网络状态 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 获取WiFi状态 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!-- 改变网络状态 --> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <!-- 改变WiFi状态 --> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <!--唤醒锁定--> <uses-permission android:name="android.permission.WAKE_LOCK"/> <!--清除应用缓存--> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <!--麦克风权限组--> <uses-permission android:name="android.permission.READ_CALENDAR"/> <!-- 允许应用写(非读)用户的外部存储器 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!--允许读取电话的状态--> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!--允许应用读取用户的联系人数据--> <uses-permission android:name="android.permission.READ_CONTACTS"/> <!--允许使用电源锁定管理以使进程休眠或屏幕变暗--> <uses-permission android:name="android.permission.WAKE_LOCK" />
为了方便使用我这里将云知声语音合成做了进一步的封装,以方便调用,以下是示例,方便大家进行参考
import android.content.Context; import android.media.AudioManager; import android.util.Log; import cn.yunzhisheng.tts.offline.TTSPlayerListener; import cn.yunzhisheng.tts.offline.basic.ITTSControl; import cn.yunzhisheng.tts.offline.basic.TTSFactory; import cn.yunzhisheng.tts.offline.common.USCError; /** * 云知声离线语音封装类 */ public class SpeechUtilOffline implements TTSPlayerListener { public static final String TAG ="SpeechUtilOffline"; public static final String appKey = "_appKey_"; private ITTSControl ittsControl; private Context context; public SpeechUtilOffline(Context context) { this.context = context; init(); } /** * 初始化引擎 */ private void init() { // 初始化语音合成对象 ittsControl = TTSFactory.createTTSControl(context, appKey); // 设置回调监听 ittsControl.setTTSListener(this); // 设置音频流 ittsControl.setStreamType(AudioManager.STREAM_MUSIC); // 设置播报语速,播报语速,数值范围 0.1~2.5 默认为 1.0 ittsControl.setVoiceSpeed(2.5f); // 设置播报音高,调节音高,数值范围 0.9~1.1 默认为 1.0 ittsControl.setVoicePitch(1.1f); // 初始化合成引擎 ittsControl.init(); } /** * 停止播放 */ public void stop(){ ittsControl.stop(); } /** * 播放 */ public void play(String content) { ittsControl.play(content); } /** * 开始缓冲回调 */ @Override public void onBuffer() { Log.i(TAG, "onBuffer"); } /** * 开始播放回调 */ @Override public void onPlayBegin() { Log.i(TAG, "onPlayBegin"); } /** * 取消播放回调 */ @Override public void onCancel() { Log.i(TAG, "onCancel"); } /** * 语音合成错误回调 */ @Override public void onError(USCError uscError) { Log.i(TAG, "onError"); } /** * 播放完成回调 */ @Override public void onPlayEnd() { Log.i(TAG, "onPlayEnd"); ittsControl.stop(); } /** * 初始化成功回调 */ @Override public void onInitFinish() { Log.i(TAG, "onInitFinish"); } }
使用方法
SpeechUtilOffline speechUtilOffline = new SpeechUtilOffline(this); speechUtilOffline.play("此处是需要播放的文本内容")
总结
在集成的时候遇到过很多bug,比如模型文件放在不正确的地方会导致没有声音,模型文件不完整的时候回导致程序崩溃,发音不是预期的效果等等,还有一些参数的设置,具体参数还是得看官方的开发文档。
到此这篇关于Android 实现云知声版离线语音合成的文章就介绍到这了,更多相关Android 语音合成内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!