使用 MediaPlayer 同时播放多首歌曲:只有一首真正在播放 [英] Playing multiple songs with MediaPlayer at the same time: only one is really playing

查看:34
本文介绍了使用 MediaPlayer 同时播放多首歌曲:只有一首真正在播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 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);

如您所见,我有 MediaPlayer 的三个不同实例.

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

这是我启动 MediaPlayers 的部分:

//让我们假设这个代码片段在线程内的 run() 方法中(就是这种情况)track1.start();track2.start();track3.start();

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

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

我在调试器模式下进行了测试:很明显,track2.start() 停止了 track1 的 MediaPlayer,并遵循相同的模式,track3.start() 停止了 Tack2 的 MediaPlayer.>

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

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

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

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

注意:

  • 音频文件的时长完全相同,大约 15 分钟
  • 音频文件是.mp3文件压缩成.acc文件(从320kbps144kbps)
  • 我在 C# 中的 Xamarin Studio 下工作,但为了清楚起见,我将坚持使用小的 Java 代码片段.

编辑 1

根据这个同时播放两首mp3歌曲 我的解决方案应该有效,对吗?

解决方案

我使用 CyclicBarrier 实例和内部类实现实现了您想要的.

示例:

公共枚举 MP_COMMAND {开始,停止,暂停}/*** 使用线程为当前视频媒体播放器执行同步命令和*串联的背景音乐播放器.*/public void syncedCommand(MediaPlayer player1, MediaPlayer player2, MP_COMMAND 命令) {最终 CyclicBarrier commandBarrier = new CyclicBarrier(2);新线程(新 SyncedCommandService(commandBarrier,player1,command)).开始();新线程(新 SyncedCommandService(commandBarrier,player2,command)).开始();}/*** 同步启动给定媒体播放器的内部类* 与其他线程使用 SyncedStartService*/私有类 SyncedCommandService 实现 Runnable {私人最终 CyclicBarrier mCommandBarrier;私有 MediaPlayerTest.MP_COMMAND mCommand;私有媒体播放器 mMediaPlayer;公共 SyncedCommandService(CyclicBarrier 屏障,MediaPlayer 播放器,MediaPlayerTest.MP_COMMAND 命令){mCommandBarrier = 屏障;mMediaPlayer = 播放器;mCommand = 命令;}@Override public void run() {尝试 {mCommandBarrier.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}开关(mCommand){案例开始:mMediaPlayer.start();休息;案例停止:mMediaPlayer.stop();休息;案例暂停:mMediaPlayer.pause();休息;默认:休息;}}}

你会像这样使用它:

syncedCommand(mCurrentVideoPlayer, mBackgroundMusic, MP_COMMAND.START);

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

我意识到这个问题很旧,但是我在寻找解决方案时发现了这个页面,所以我希望这可以帮助任何人在未来遇到这个问题.

I need help with playing multiple audio tracks at the same time in Android.

I am supposed to play three audio tracks at the exact same time using Android.Media.MediaPlayer.

Yesterday I managed to make it work doing so :

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

As you can see, I have three distincts instances of MediaPlayer here.

Because I am asked to, I need to have these MediaPlayer being played in a background thread.

Here is the part where I start the 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();

If I say yesterday, it's because the next day, it did not work as supposed to.

Indeed, starting a MediaPlayer seems to stop any previous playing MediaPlayer.

I tested in debugger mode : clearly, track2.start() stops track1's MediaPlayer and following the same pattern, track3.start() stops tack2's MediaPlayer.

So at the end, only track3 is being played, I cannot hear any of the previous tracks, whatever the volume settings are whereas I could cleary hear all of them before : it is supposed to create some sort an ambiance.

Of course, changing the order in which the tracks are started does not change anything : only the last track will be heard.

If I say "heard" it is because in debugger mode, checking the property MediaPlayer.isPlaying is returning true : all three players are saying they are playing but only one can be heard... !

Why the change ? Why did it work once to stop working afterwards ?

NOTE:

  • the audio files have all the same duration which is approximately about 15 minutes
  • the audio files were .mp3 files compressed into .acc files (from 320kbps to 144kbps)
  • I am working under Xamarin Studio in C# but for clarety purpouse I will stick to small Java code snippets.

EDIT 1

According to this Play two mp3 song at the same time my solution should be working, right ?

解决方案

I achieved what you're looking for using a CyclicBarrier instance and an inner class implementation.

Example:

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;
        }
    }
}

You'd utilize it like so:

syncedCommand(mCurrentVideoPlayer, mBackgroundMusic, MP_COMMAND.START);

If you had the requirement that it be usable for any number of media players, you could easily implement it - my requirements just call for two.

I realize this question is old, but this page is where I found myself while searching for a solution, so I hope this helps anyone stuck on this issue in the future.

这篇关于使用 MediaPlayer 同时播放多首歌曲:只有一首真正在播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆