如何使用 MediaPlayer 同时播放多个曲目?

Posted

技术标签:

【中文标题】如何使用 MediaPlayer 同时播放多个曲目?【英文标题】:How to play several tracks simultaneously, using MediaPlayer? 【发布时间】:2014-01-23 16:09:52 【问题描述】:

我有 8 个 mp3 文件。而且我必须同时播放它(几乎不会。肯定会)。 我正在使用“AudaCity”来控制精度。但是我的代码没有给我想要的结果...(异步 = 30~90 毫秒) 所以,这是我的代码:(第一次开始玩)

public void start() 
//songInfo.getMediaPlayer() - it's array of MediaPlayers, source already setted
        for (MediaPlayer player : songInfo.getMediaPlayer()) 
            try 
                if (player != null) 
                    player.prepare();
                    player.seekTo(0);
                
             catch (Exception ex) 
                ex.printStackTrace();
                   
        
        songInfo.getMediaPlayer()[0]
                .setOnCompletionListener(new OnCompletionListener() 
                        @Override
                        public void onCompletion(MediaPlayer mp) 
                            //code for play next setlist
                        
        );
        resume();

(暂停)

public void pause() 
        for (MediaPlayer player : songInfo.getMediaPlayer()) 
            if (player != null)
                player.pause();
        

(用于暂停后继续播放,用于开始播放(用于第一种方法))

public void resume()   
        int pos = songInfo.getMediaPlayer()[0].getCurrentPosition();
        long iTime = System.currentTimeMillis();
        for (MediaPlayer player : songInfo.getMediaPlayer()) 
            if (player != null) 
                player.seekTo(pos + (int)(System.currentTimeMillis()-iTime));
                player.start();
            
        

如果我第一次开始玩,它会给我带来异步 ~ 30ms+ 然后在暂停/恢复后播放完美。

【问题讨论】:

【参考方案1】:

经过大量研究,问题解决了。 要同时播放多个曲目,您应该使用AsyncTask 并在 THREAD_POOL_EXECUTOR 上执行它。 如何做到这一点:线程类

class PlayThread extends AsyncTask<MediaPlayer, Void, Void>

    @Override
    protected Void doInBackground(MediaPlayer... player) 

        player[0].start();          
        return null;
    

媒体播放器

MediaPlayer[] players = new MediaPlayer[5];
//Then set source to each player...
//...
//Create objects of Thread class
PlayThread[] playThreads = new PlayThread[5];
for (int i = 0; i < 5; i++)
    playThreads[i] = new PlayThread();
//Set Media Players there and start play
for (int i = 0; i < 5; i++)
    playThreads[i].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, players[i]);

AsyncTask只能同时执行5个线程,其他的要排队。


SoundPool 缓冲区限制为 1Mb,因此根本不是解决方案。


这很重要: 要同时播放更多音轨,您应该将它们混合到 1 个缓冲区中。 实现方式:将mp3解码为pcm(流模式下到小缓冲区),混合成一个字节的缓冲区,放到AudioTrack播放。

【讨论】:

您是否尝试过使用SoundPool in accordance to google's developer 文档,它应该用于同时播放各种曲目,但我在设置时遇到问题。 @cooervo 是的,但 SoundPool 不是一个好的选择。它只能播放小音频文件 (***.com/questions/13377604/…) @cooervo 在我的例子中,我使用 NDK 混合了 8 个解码的 mp3 文件的缓冲区。

以上是关于如何使用 MediaPlayer 同时播放多个曲目?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xamarin 中使用 MediaPlayer 获取曲目的持续时间

是否可以创建同时播放多个曲目的javascript音频播放器?

使用 MediaPlayer 多次播放音频

Android MediaPlayer:同时播放多个声音。我的代码是

如何保存同时播放两个曲目的wav文件?在不同的体积

如何同时播放多个 ogg 或 mp3 ..?