同时使用MediaPlayer播放多首歌曲:只有一首真正在播放

Mac*_*ich 9 audio multithreading android android-mediaplayer xamarin

我需要帮助同时播放多个音轨Android.

我应该在同一时间播放三个音轨Android.Media.MediaPlayer.

昨天我成功地做到了这样做:

MediaPlayer track1 = MediaPlayer.create(this, R.raw.track1);
MediaPlayer track2 = MediaPlayer.create(this, R.raw.track2);
MediaPlayer track3 = MediaPlayer.create(this, R.raw.track3);
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我有3个distincts实例MediaPlaye这里,r.

因为我被要求,我需要MediaPlayer后台线程中播放这些内容.

这是我开始的部分MediaPlayers:

//let's suppose this code snippet is in a run() method inside a Thread (which is the case)
track1.start();
track2.start();
track3.start();
Run Code Online (Sandbox Code Playgroud)

如果我昨天说,那是因为第二天它没有按预期工作.

实际上,启动MediaPlayer似乎会停止任何以前播放的MediaPlayer.

我在调试器模式下测试:显然,track2.start()停止track1的MediaPlayer并遵循相同的模式,track3.start()停止tack2的MediaPlayer.

所以最后,只有track3正在播放,我无法听到任何以前的曲目,无论音量设置如何,而之前可以清楚地听到所有曲目:它应该创造某种氛围.

当然,更改曲目的开始顺序不会改变任何内容:只会听到最后一首曲目.

如果我说"听到",那是因为在调试器模式下,检查属性MediaPlayer.isPlaying正在返回true:所有三个玩家都在说他们正在玩,但只有一个可以听到......!

为什么要改变?为什么之后停止工作一次呢?

注意:

  • 音频文件具有相同的持续时间,大约约15分钟
  • 音频文件进行.mp3文件压缩成.acc文件(从320kbps144kbps)
  • 我正在努力Xamarin Studio,C#但对于clarety purpouse我会坚持小Java代码片段.

编辑1

根据这个Play两首mp3歌曲同时我的解决方案应该正常工作吧?

Car*_*son 8

我使用CyclicBarrier实例和内部类实现实现了您正在寻找的东西.

例:

public enum MP_COMMAND {
    START,
    STOP,
    PAUSE
}

/**
 * Uses threads to execute synced commands for the current video media player and 
 * background music player in tandem.
 */
public void syncedCommand(MediaPlayer player1, MediaPlayer player2, MP_COMMAND command) {
    final CyclicBarrier commandBarrier = new CyclicBarrier(2);
    new Thread(new SyncedCommandService(commandBarrier, player1, command)).start();
    new Thread(new SyncedCommandService(commandBarrier, player2, command)).start();
}

/**
 * Inner class that starts a given media player synchronously
 * with other threads utilizing SyncedStartService
 */
private class SyncedCommandService implements Runnable {
    private final CyclicBarrier              mCommandBarrier;
    private       MediaPlayerTest.MP_COMMAND mCommand;
    private       MediaPlayer                mMediaPlayer;

    public SyncedCommandService(CyclicBarrier barrier, MediaPlayer player, MediaPlayerTest.MP_COMMAND command) {
        mCommandBarrier = barrier;
        mMediaPlayer = player;
        mCommand = command;
    }

    @Override public void run() {
        try {
            mCommandBarrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }

        switch (mCommand) {
            case START:
                mMediaPlayer.start();
                break;

            case STOP:
                mMediaPlayer.stop();
                break;

            case PAUSE:
                mMediaPlayer.pause();
                break;

            default:
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你会像这样使用它:

syncedCommand(mCurrentVideoPlayer, mBackgroundMusic, MP_COMMAND.START);
Run Code Online (Sandbox Code Playgroud)

如果您要求它可以用于任何数量的媒体播放器,您可以轻松实现它 - 我的要求只需要两个.

我意识到这个问题已经过时了,但这个页面是我在寻找解决方案时发现自己的地方,所以我希望这可以帮助任何人在未来坚持这个问题.


Mac*_*ich 2

好吧,我相信我找到了所谓的“临时解决方案”。

MediaPlayer track1 = MediaPlayer.create(this, R.raw.track1);
track1.start();
MediaPlayer track2 = MediaPlayer.create(this, R.raw.track2);
track2.start();
MediaPlayer track3 = MediaPlayer.create(this, R.raw.track3);
track3.start();
Run Code Online (Sandbox Code Playgroud)

这样做的问题是,该create()方法在播放歌曲时会产生明显的间隙。

所以这不是它。

一段时间后,我尝试了以下操作:

MediaPlayer track1 = MediaPlayer.create(this, R.raw.track1);
track1.start();
track1.pause();
MediaPlayer track2 = MediaPlayer.create(this, R.raw.track2);
track2.start();
track2.pause();
MediaPlayer track3 = MediaPlayer.create(this, R.raw.track3);
track3.start();
track3.pause();

// resuming...
track1.start(); 
track2.start();
track3.start();
Run Code Online (Sandbox Code Playgroud)

因此,歌曲更加同步。我仍然能听到很小的间隙,但已经好多了。我发现这个解决方案非常奇怪而且丑陋。

除非有人有其他想法,否则我将坚持该解决方案。