在Android开发中,语音播报经常使用,但是,在使用过程中会发现,如果语音来源过于块,频率过高,在前一条没有播放完的情况下会执行第二条播放,本篇文章用来解决这个问题。

一、科大讯飞语音集成:
1、在科大讯飞的开发者平台(科大讯飞开放平台)注册。我这里使用的是在线语音合成,下载SDK包。
2、将SDK包里面的libs里面的.so文件和jar包复制到你的项目中,并且引用.so文件和jar包,这里要注意的是,个人建议将所有CPU类型的.so文件都放到你的项目中,这样保证在所有设备中都能播放,虽然这样会导致项目变大。

3、在MyApplication中初始化:
SpeechUtility.createUtility(this, SpeechConstant.APPID + "=******"); 注意这里的APPID,不要丢了这个“=”号。

4、在使用到语音播放的地方,初始化语音引擎:
private SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer(context, mTtsInitListener);

5、初始化中有两个参数,第一个是上下文,第二个是初始化回调:

private InitListener mTtsInitListener = new InitListener() {@Overridepublic void onInit(int code) {if (code != ErrorCode.SUCCESS) {Toast.showToast(context, "语音初始化失败,错误码:" + code);} else {AppLog.i("语音初始化成功");// 初始化成功,之后可以调用startSpeaking方法// 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,// 正确的做法是将onCreate中的startSpeaking调用移至这里}}};

6、播放:

 public void playVoice(String msg) {mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");mTts.setParameter(SpeechConstant.SPEED, "60");   //播放速度mTts.setParameter(SpeechConstant.VOLUME, "80");   //播放音量mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);   //引擎类型mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflyket.pcm");    //声音文件地址mTts.startSpeaking(msg, mTtsListener);}

这里面可以配置播放人声(SpeechConstant.VOICE_NAME)、声音大小(peechConstant.VOLUME)、语速(SpeechConstant.SPEED),如果你发现你选择的人声无法通过手机系统声音控制声音大小时,将人声换成系统默认的“xiaoyan”,在mTts.startSpeaking(msg, mTtsListener); 配置中,第一个参数就是要播放的内容,第二个是播放回调:

private SynthesizerListener mTtsListener = new SynthesizerListener() {@Overridepublic void onSpeakBegin() {// AppLog.i("onSpeakBegin");}@Overridepublic void onSpeakPaused() {//  AppLog.i("onSpeakPaused");}@Overridepublic void onSpeakResumed() {// AppLog.i("onSpeakResumed");}@Overridepublic void onBufferProgress(int percent, int beginPos, int endPos, String info) {}@Overridepublic void onSpeakProgress(int percent, int beginPos, int endPos) {}@Overridepublic void onCompleted(SpeechError error) {if (error == null) {if (!queue.isEmpty()) {presenter.playVoice(queue.poll());} else {isFirst = true;}} else if (error != null) {AppLog.i(error.getPlainDescription(true));}}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因// 若使用本地能力,会话id为null//  if (SpeechEvent.EVENT_SESSION_ID == eventType) {//      String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);//      Log.d(TAG, "session id =" + sid);//  }}};

播放回调看法不言而喻了。

二、重点来了 解决播放跳跃问题:

1、首先来看下这个场景:比如有一个收银系统消息接受终端,每收一笔钱都播放一条“收款成功xxx元”,如果收银速度过款人客流大,当还没播放完第一条语音的时候,第二次收银已经结束了,此时一般情况就会每次播放都直接调用playVioce(String msg)这个这个方法,此时第一条没完,知己播放第二条了。还有一个情景就是,集成高德地图,语音是要自己合成的,同样用科大讯飞来播放路况,当路况复杂的情况下会出现一样的问题。

2、解决问题:解决这个问题的方法就是使用队列:

Queue<String> queue = new LinkedList<String>();

在我的项目的场景就是,每次收款一次,都会受到一次推送一串String,我要播放的就是这条String

//EvenBus接受推送过来的消息广播@Subscribe(threadMode = ThreadMode.MAIN)public void getMessage(PushEvent pushEvent) {Log.i("tag","收款:" + pushEvent.getMessage());String msg = pushEvent.getMessage();queue.offer(msg);//此处需要将语音添加到队列,保证一条播放完再播放下一条//必须第一次收到消息才能在这播放,以后每次收到消息将消息添加到队列,每次播放完后去队列里面取;if (isFirst) {playVoice(queue.poll());//保证播放方法这里只执行第一次isFirst = !isFirst;}}

明白的童鞋知道我这里使用的EvenBus来接受推送的消息,可以忽略。将推送过来的消息,放到队列queue中,注意,这里使用的是queue.offer(msg); offer()这个方法,队列添加还有add()这个方法,这两个方法的不同之处就是offer在添加失败的时候不抛异常,所以不建议使用add()方法。使用
queue.poll()来出去队列中的数据,队列是先进先出的,每次poll都会将该条消息从队列中清除。
这里使用的一个变量isFirst来控制播放,只有初次播放的时候才在getMessage()中使用playVoice()方法,这里解决了每次收到消息后都会触发getMessage()这个方法里面的playVoice()。如果每次收到推送消息都调用playVoice(queue.poll());方法会导致少播放一条消息。

在播放回调的onCompleted()方法中继续取出队列里的消息播放,

  @Overridepublic void onCompleted(SpeechError error) {if (error == null) {if (!queue.isEmpty()) {presenter.playVoice(queue.poll());} else {isFirst = true;}} else if (error != null) {AppLog.i(error.getPlainDescription(true));}}

看代码,当队列不为空的时候就继续取出队列里的消息播放,知道为空的时候将isFirst 置为true,否则在全部播放完后不能再次播放了。

三、这样就很完美的解决了播放跳跃问题,这样,无论有多少条消息,多频繁,每次播放都从队列里面取出,这样就达到了播放完一条再播放下一条的问题了。

四、由于这个例子是从自己项目中抽取出来的,没办法上源码,抱歉,写的不好的话请多指正!

Android科大讯飞语音按队列播报相关推荐

  1. Android 科大讯飞 语音转文字

    Android 科大讯飞 语音转文字 语音听写SDK适配安卓6.0需要手动申请权限,各位可以自信查询资料实现,关于语音听写SDK的开发,参考科大讯飞开放平台官网为准 第一,首先去科大讯飞官网注册一个账 ...

  2. Android 科大讯飞语音SDK集成步骤

    前言 科大讯飞语音虽好,其严格的认证与校验确实精密,不过也大大提高了开发者的集成难度,并非危言耸听,我想大多数人都有经历过 11210(用户ID与离线资源不匹配) 21480( 离线引擎GUID不一致 ...

  3. Android 科大讯飞 语音听写

    这几天在搞一个语音识别的项目 用到i的是科大讯飞的语音服务,第一次搞语音识别,在这里记录一下,也希望对大家有用.废话不多说进入正题 一.要用到科大讯飞的语音识别功能,肯定是要他的开发者平台申请账号,创 ...

  4. 集成Android 科大讯飞免费在线语音合成播报功能(附源码)

    概述 开篇先介绍一下'科大讯飞',毕竟是我家乡合肥的科技公司,我感到骄傲,更重要的是它在语音识别行业也是佼佼者,在如今人工智能横飞的时代,依然能够保持着较高水准的技术优势.在此,希望科大在AI之战中能 ...

  5. android 科大讯飞语音唤醒demo

    demo地址:https://gitee.com/longlyblack_admin/VoiceCallSecondDemo API文档地址:http://mscdoc.xfyun.cn/androi ...

  6. Android科大讯飞语音集成,非常详细的使用讲解

    讯飞语音开发集成地址http://www.xfyun.cn/ 解压后的doc文件夹下的msc develop 文件中有详细集成步骤    AppId:   1.先要注册开发者账户, 添加我的应用 , ...

  7. 教你用Android做二次开发,识别率达到科大讯飞语音输入水平 | 原力计划

    作者 | Pek_KuaiJia 责编 | 夕颜 头图 | CSDN 下载自视觉中国 出品 | CSDN(ID:CSDNnews) 随着目前用户需求的精细化和智能化,很多时候我们需要在App内集成语音 ...

  8. 教你用 Android 做二次开发,识别率达到科大讯飞语音输入水平 | 原力计划

    作者 | Pek_KuaiJia 责编 | 夕颜 头图 | CSDN 下载自视觉中国 出品 | CSDN(ID:CSDNnews) 随着目前用户需求的精细化和智能化,很多时候我们需要在App内集成语音 ...

  9. 科大讯飞语音无限制录音、识别功能的实现:Android studio(一)

    最近想要做一款语音听写APP,在网上搜索关于如何使用科大讯飞语音的Demo少之又少,又或者是只是单纯的按照文档来实现简单的语音听写,远远不能满足需求,看了几天的文档和自己搜索的一些资料,还有这几天中遇 ...

最新文章

  1. 【好文】带你用Python开发个机器学习软件!
  2. matlab GM(2,1)模型
  3. python代码基础题-python3的基础练习题
  4. [你必须知道的.NET]第二十七回:interface到底继承于object吗?
  5. 尝鲜Ubuntu Server 12.04 LTS
  6. Boost:bimap双图的突变的测试程序
  7. jQuery 入门教程(5): 显示/隐藏内容
  8. python面试总结(五)内存管理与MYSQL引擎选择
  9. 最大数max(x,y,z)(信息学奥赛一本通-T1152)
  10. shell脚本和linux命令,Linux shell脚本全面学习(一)
  11. 雷军回应小米新 Logo 争议;马化腾排名第 15 位,2021 全球亿万富豪榜出炉!谷歌将停止使用甲骨文的财务软件|极客头条...
  12. 给Android SDK设置环境变量
  13. 多元统计分析朱建平pdf_应用多元统计分析课后答案朱建平版[精心整理].doc
  14. CentOS7镜像下载地址
  15. ubuntu16.04修改鼠标按键功能
  16. 如何转换视频格式?推荐这3款视频格式转换工具
  17. html代码 通用代码,html5可以通用的几段代码 | 睿客网
  18. linux中etc下的hosts(本地IP解析)文件详解
  19. 这是用原声js编写的地址选择器,使用select编写的三联选择器
  20. 关于心跳ajax请求pending状态(被挂起),stalled时间过长的问题。涉及tcp连接异常。

热门文章

  1. 根治偏头痛及各种头痛病症
  2. chrome浏览器怎么设置编码
  3. C语言心语,心语,心缘
  4. C# MVC 微信支付教程系列之公众号支付
  5. 李嘉璇:技术人如何深入人工智能
  6. css 各种高度和宽度
  7. Golang 依赖包下载时候代理设置
  8. 熟练的“猎手”使用新的脉冲波 DDoS 攻击来打击多个目标
  9. 专硕计算机学院排名,考研计算机院校排名
  10. pma连接,报错10061