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
:所有三个玩家都在说他们正在玩,但只有一个可以听到......!
为什么要改变?为什么之后停止工作一次呢?
注意:
.mp3
文件压缩成.acc
文件(从320kbps
到144kbps
)Xamarin Studio
,C#
但对于clarety purpouse我会坚持小Java
代码片段.编辑1
根据这个Play两首mp3歌曲同时我的解决方案应该正常工作吧?
我使用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)
如果您要求它可以用于任何数量的媒体播放器,您可以轻松实现它 - 我的要求只需要两个.
我意识到这个问题已经过时了,但这个页面是我在寻找解决方案时发现自己的地方,所以我希望这可以帮助任何人在未来坚持这个问题.
好吧,我相信我找到了所谓的“临时解决方案”。
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)
因此,歌曲更加同步。我仍然能听到很小的间隙,但已经好多了。我发现这个解决方案非常奇怪而且丑陋。
除非有人有其他想法,否则我将坚持该解决方案。
归档时间: |
|
查看次数: |
11372 次 |
最近记录: |