Android 语音播报实现方案(无SDK)

作者:姜康
链接:https://www.jianshu.com/p/df2022b3937d
声明:本文是 姜康 原创。转载请联系作者获得授权。

功能描述

类似支付宝收款时候的语音播报功能:当别人扫描你的收款码,你收到钱之后,就会听到“支付宝到账12.55元”的语音播报。

要解决的问题

1.播放单个语音文件
2.播放完单个语音文件之后立即播放下一条,这样才能连续
3.当多个完整的语音序列都需要播报时的处理(比如支付宝短时间内收到多条收款推送)

实现思路

  1. 播放单个文件选择MediaPlayer
    首先创建一个MediaPlayer实例

MediaPlayer player = new MediaPlayer();

然后设置数据源,这里数据源从assets中获取,当然也可以将语音文件放在raw文件夹里

fd = FileUtils.getAssetFileDescription(path);
player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(),fd.getLength());

然后调用 prepareAsync() 方法,异步加载,并设置监听,加载完毕之后开始播放(与 prepare 方法区别开来)

player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                       @Override
                       public void onPrepared(MediaPlayer mp) {
                           mp.start();
                       }
                   });
  1. 由于播放的语音文件不止一个,因此需要监听播放完成的状态,在播放完成之后播放下一条语音

player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                       @Override
                       public void onCompletion(MediaPlayer mp) {
                           mp.reset();
                           counter[0]++;
                           if (counter[0] < list.size()) {
                               try {
                                   AssetFileDescriptor fileDescriptor = FileUtils.getAssetFileDescription(String.format("sound/tts_%s.mp3", list.get(counter[0])));
                                   mp.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
                                   mp.prepare();
                               } catch (IOException e) {
                                   e.printStackTrace();
                                   latch.countDown();
                               }
                           } else {
                               mp.release();
                               latch.countDown();
                           }
                       }
                   });
  1. 短时间多次播报请求,开采用同步方式进行,一条播完播放下一条,这里采用
    synchronized + notifyAll() 实现,当然也可以用别的方法。

代码封装

功能代码分为两部分,一部分是语音序列组成的 List,这里是 VoiceTemplate;
一部分是播放的功能封装,接收 List,然后播放语音,这里叫做 VoiceSpeaker;
详细代码见文末。

代码使用

比如要播放“支付宝到账十二点一三元”,代码如下

final List<String> list = new VoiceTemplate()
               .prefix("success")
               .numString("12.13")
               .suffix("yuan")
               .gen();
VoiceSpeaker.getInstance().speak(list);

源码

KTools:
https://link.jianshu.com/?t=https://github.com/jiangkang/KTools
https://github.com/jiangkang/KTools/blob/master/app/src/main/java/com/jiangkang/ktools/audio/VoiceSpeaker.java

https://github.com/jiangkang/KTools/blob/master/app/src/main/java/com/jiangkang/ktools/audio/VoiceTemplate.java


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值