美文网首页爱上Android基础知识Android 开发技术分享
Android 语音播报实现方案(无SDK)

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

作者: 姜康 | 来源:发表于2017-11-28 21:28 被阅读1357次

    功能描述


    类似支付宝收款时候的语音播报功能:当别人扫描你的收款码,你收到钱之后,就会听到“支付宝到账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://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

    公众号

    相关文章

      网友评论

        本文标题:Android 语音播报实现方案(无SDK)

        本文链接:https://www.haomeiwen.com/subject/jvxybxtx.html