1. 程式人生 > >Android 語音播報實現方案(無SDK)

Android 語音播報實現方案(無SDK)

功能描述

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

原始碼