4

我有许多简短的音频片段,应该以最小的延迟顺序播放。

如何有效地排队这些声音?

4

2 回答 2

3

我可以通过两种方式看到它的工作原理:使用 aMediaPlayer或 aSoundPool

媒体播放器

您可以将MediaPlayer.OnCompletionListener与文件列表结合使用,以简单地侦听完成并播放下一个。总的来说,这工作得很好,我用它来播放非常短的剪辑(< 1s)序列而没有问题。

声池

另一种方法是使用SoundPool类和一个处理程序来简单地提前排队播放事件。这假设您知道每个剪辑的长度,但根据格式,您应该能够找到它。

您选择哪种解决方案取决于许多因素:文件的数量、文件的长度、文件的格式、从哪里获取文件、列表的固定或可变程度等。

就我个人而言,我会选择这样做,MediaPlayer因为这更容易实现,并且可能会满足您的需求。

于 2013-07-05T09:42:28.403 回答
1

一种方法是将它们连接成一个音频文件,然后为其创建一个 MediaPlayer 并设置一个 OnSeekCompleteListener。以您喜欢的任何顺序查找 tern 中的每个片段,然后在 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] 是它的长度。

于 2013-07-05T09:25:44.537 回答