我有许多短音频片段,应按顺序播放,延迟时间最短。
如何有效排队这些声音?
答案 0 :(得分:3)
我可以通过两种方式查看此工作:使用MediaPlayer
或SoundPool
<强>的MediaPlayer 强>
您可以将MediaPlayer.OnCompletionListener与文件列表结合使用,只是听取完成情况并播放下一个文件。总的来说这很有效,我用它来播放非常短片段(&lt; 1s)的序列没有问题。
<强>的Soundpool 强>
另一种方法是使用SoundPool类与处理程序相结合,简单地提前排队游戏事件。这假设您知道每个剪辑的长度,但取决于您应该能够找到它的格式。
您选择哪种解决方案取决于多种因素:文件数量,文件有多短,文件格式,获取位置,列表固定或变量等等。
我个人会选择MediaPlayer
,因为这更容易实现,并且可能符合您的需求。
答案 1 :(得分:1)
一种方法是将它们连接成一个音频文件,然后为它创建一个MediaPlayer并设置一个OnSeekCompleteListener。按照您喜欢的顺序搜索每个段,然后在onSeekComplete()中播放它们。它的时间不准确,MediaPlayer使用起来很敏感,所以它可能不是你的最佳选择,但它对我的目的来说已经足够了。
这是我的代码:
private MediaPlayer MP = new MediaPlayer();
@Override
public void onCreate(Bundle savedInstanceState) {
//...
FileDescriptor fd = getResources().openRawResourceFd(R.raw.pronounciations).getFileDescriptor();
try {
setVolumeControlStream(AudioManager.STREAM_MUSIC); // Lets the user control the volume.
MP.setDataSource(fd);
MP.setLooping(false);
MP.prepare();
MP.start(); // HACK! Some playing seems required before seeking will work.
Thread.sleep(60); // Really need something like MediaPlayer.bufferFully().
MP.pause();
MP.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
MP.setOnSeekCompleteListener(new OnSeekCompleteListener() {
public void onSeekComplete(MediaPlayer mp) {
// The clip is queued up and read to play.
// I needed to do this in a background thread for UI purposes.
// You may not need to.
new Thread() {
@Override
public void run() {
MP.start();
try {
Thread.sleep(soundRanges[curWordID][1]);
} catch(InterruptedException e) {}
MP.pause();
}
}.start();
}
});
} catch(Throwable t) {}
}
private void playCurrentWord() {
if(soundRanges != null && !MP.isPlaying() && !silentMode) {
try {
MP.seekTo(soundRanges[curWordID][0]);
}
catch(Throwable t) {}
}
}
您可能需要使用外部声音编辑工具连接剪辑。我使用Audacity查找和编辑我保存在文件中的剪辑开头和长度。
soundRanges [curWordID] [0]是剪辑开头的声音文件中的偏移量,soundRanges [curWordID] [1]是其长度。