Function description
Similar to the voice broadcast function when Alipay collects money: when someone scans your payment code, after you receive the money, you will hear the voice broadcast of "Alipay arrives at 12.55 yuan".
problem to be solved
1. Play a single voice file
2. Play the next voice file immediately after playing a single voice file, so as to be continuous
3. When multiple complete voice sequences need to be broadcast (for example, Alipay receives multiple payment pushes in a short time) )
Realize ideas
- To play a single file select MediaPlayer
first create a MediaPlayer instance
MediaPlayer player = new MediaPlayer();
- 1
Then set the data source, where the data source is obtained from assets, of course, the voice file can also be placed in the raw folder
fd = FileUtils.getAssetFileDescription(path);
player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(),
fd.getLength());
- 1
- 2
- 3
Then call the prepareAsync() method, load asynchronously, set the listener, and start playing after loading (different from the prepare method)
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- Since there is more than one voice file to play, it is necessary to monitor the status of the playback completion, and play the next voice after the playback is completed.
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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- Multiple broadcast requests in a short period of time are performed in a synchronous manner. After one broadcast is completed, the next one is played. Here,
synchronized + notifyAll() is used. Of course, other methods can also be used.
code encapsulation
The function code is divided into two parts, one part is the List composed of voice sequences, here is VoiceTemplate; the other
part is the function package for playback, receiving the List, and then playing the voice, which is called VoiceSpeaker here;
see the end of the text for the detailed code.
code usage
For example, to play "Alipay arrives at 12.13 yuan", the code is as follows
final List<String> list = new VoiceTemplate()
.prefix("success")
.numString("12.13")
.suffix("yuan")
.gen();
VoiceSpeaker.getInstance().speak(list);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
source code
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