androids 語音播報實現方案


功能描述


類似支付寶收款時候的語音播報功能:當別人掃描你的收款碼,你收到錢之後,就會聽到“支付寶到賬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

   

小禮



作者:薑康
鏈接:https://www.jianshu.com/p/df2022b3937d
來源:簡書
著作權歸作者所有。商業轉載請聯係作者獲得授權,非商業轉載請注明出處。


上一篇 下一篇