如何在Android中创建和播放声音或音频队列

时间:2013-07-05 08:49:07

标签: android audio

我有许多短音频片段,应按顺序播放,延迟时间最短。

如何有效排队这些声音?

2 个答案:

答案 0 :(得分:3)

我可以通过两种方式查看此工作:使用MediaPlayerSoundPool

<强>的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]是其长度。