关于一个语音合成组件封装的正确姿势——支持更换底层实现,上层调用API不变
转载请注明出处:http://blog.youkuaiyun.com/hnytdangyao/article/details/79174449.
本文出自 [ 党耀的博客 ]
目录
用 [TOC]
来生成目录:
最近换了新环境,然后发现公司之前关于语音合成这块底层用的讯飞,但是讯飞的离线语音合成是收费的,咳咳,由于种种原因现在想更换成百度的语音合成(这里不得不夸一下百度爸爸,离线/在线都免费),但是讯飞的又不马上去掉。所以呢我这边就干脆搞一个组件出来,可以自由切换底层的实现,上层直接调用相关API就可以。
干货
架构
首先看一下组件架构
架构说明:组件整体架构用到了Java的策略模式(不懂的同学自行去百度啊,这里篇幅限制就不多做说明)。base里是上层接口以及自定义监听,impl里放的是具体的实现类,media这个可以不用关心,是为了语音组件的完整加入了播放本地资源文件的类。至于具体的管理类,也就是我们需要在代码里调用的,就是SpeakStrategyManager这个类了,所有调用的API定义以及做语音播放分级的操作都在这里完成。
一、定义统一的管理类——SpeakStrategyManager
先看代码,这里用一个全局的单例模式实现这个管理类供外部调用。
现在市面上主流的几个语音合成的SDK在播放时都会做了顺序播放,就是说不会主动打断,而是播放完一个继续播放下一个。
那么如果我们想要的是新的一个语音播放的需求可以打断正在播放的语音,这个时候就需要自定义语音的级别,在播放的时候自己处理分级打断。我这里的处理方式是高级别的可以打断低级别的,同级别的可以选择打断或者顺序播放。
/**
* Created by dangyao on 2017/11/6.
* 语音播报组件支持库的管理类,可以实时更换组件--需实现SpeakStrategy接口
*/
public class SpeakStrategyManager{
private static final String TAG = "SpeakStrategyManager";
//定义语音的等级,这里根据自己的需求自己设置 值为0时为默认状态。
public static final int VOICE_TYPE_IDLE = 0;
public static final int VOICE_TYPE_NOTICE = 2;
public static final int VOICE_OTHER_STATUS = 3;
public static final int VOICE_IM_MESSAGE = 4;
public static final int VOICE_TYPE_NAVI = 5;
//存贮当前播放类型
private int currentType;
private static final SpeakStrategyManager INSTANCE = new SpeakStrategyManager();
private SpeakStrategy mSpeakStrategy;
private Context mContext;
private SpeakStrategyManager() {
//默认使用百度语音播报
mSpeakStrategy = new SpeechSynthesizerStrategy();
}
public static SpeakStrategyManager getInstance() {