用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); 

正如你所看到的,我在这里有三个独特MediaPlaye 实例

因为我被要求,我需要在后台线程中播放这些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(); 

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

事实上, 开始MediaPlayer似乎停止任何以前播放的媒体播放器

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

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

当然,改变曲目开始的顺序不会改变任何东西:只有最后一首曲子会被听到。

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

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

注意:

  • audio文件具有大约大约15分钟的所有相同的持续时间
  • audio文件被压缩成.acc文件的.mp3文件(从320kbps144kbps
  • 我正在C#下的Xamarin Studio工作,但是对于clarety purpouse,我会坚持使用小的Java代码片段。

编辑1

根据这个播放两个MP3歌曲在同一时间我的解决scheme应该工作,对不对?

Solutions Collecting From Web of "用MediaPlayer同时播放多首歌曲:只有一首正在播放"

我使用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; } } } 

你会像这样使用它:

 syncedCommand(mCurrentVideoPlayer, mBackgroundMusic, MP_COMMAND.START); 

如果您有任何媒体播放器可用的要求,您可以轻松实现 – 我的要求只需要两个。

我意识到这个问题是旧的,但是这个页面是我在寻找解决scheme时发现自己的地方,所以我希望这有助于任何人在将来遇到这个问题。

那么,我相信我find了我能命名的“临时解决scheme”。

 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(); 

这个问题是,在播放歌曲时, 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(); 

那么,这些歌是更同步的。 我仍然可以听到一个很小的差距,但是这样会更好。 我发现这个解决scheme很奇怪,也很丑陋。

除非有人有另一个想法,否则我会坚持这个解决scheme。

正如安德烈·尼基沙耶夫 ( Andrey Nikishaev )在评论中写道,似乎有些设备同时使用多个MediaPlayers存在问题。 虽然只有一个人在我的Nexus 5上玩,但它在我的Moto G4上工作(但在播放过程中仍然有短暂的rest时间)。 这两个运行与Android 6.0.1。

我build议使用ExoPlayer来代替这个用例。 它对我来说工作得很好,至less在我的两个设备上。

我转换我的MP3在ogg文件audio(使用Audacity),我已经能够使用2 Mediaplayer的舞台,并听取混合audio。

我没有尝试是可能的超过3。

嗨尝试下面的代码它将工作它的歌曲不会停止你只需要从微调select歌曲,然后单击开始button,然后从微调select下一首歌曲,然后单击开始它将工作。

 public class MainActivity extends AppCompatActivity { Spinner sp; Button bstart; MediaPlayer mp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sp=(Spinner)findViewById(R.id.sp); String [] mys={"demo","democheap","demorehana"}; ArrayAdapter<String> data=new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,mys); sp.setAdapter(data); } public void code(View v) { if(sp.getSelectedItem().toString().equals("demo")) { mp=MediaPlayer.create(this,R.raw.demo); } else if(sp.getSelectedItem().toString().equals("democheap")) { mp=MediaPlayer.create(this,R.raw.democheap); } else if(sp.getSelectedItem().toString().equals("demorehana")) { mp=MediaPlayer.create(this,R.raw.demorehana); } if(v.getId()==R.id.bstart) { mp.start(); } } }