在 Android/Eclipse 上使用 3 个 MediaPlayer 对象同步播放音乐
Play music synchronous using 3 MediaPlayer Objects on Android/Eclipse
我有:
我在我的应用程序中实现了三个 MediaPlayer.Objects。
这三个都是使用线程创建的:
protected void onResume() {
// Threads
mTT1 = new TrackThread(this, R.raw.audiofile1, 1, mHandler);
mTT2 = new TrackThread(this, R.raw.audiofile2, 2, mHandler);
mTT3 = new TrackThread(this, R.raw.audiofile3, 3, mHandler);
// start thread
mTT1.start();
mTT2.start();
mTT3.start();
super.onResume();
}
"simplified" 线程中用于创建的代码:
public class TrackThread extends Thread implements OnPreparedListener {
...
...
...
public void run() {
super.run();
try {
mMp.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getDeclaredLength());
mMp.prepare();
} catch (IllegalArgumentException | IllegalStateException
| IOException e) {
Log.e(TAG, "Unable to play audio queue do to exception: "
+ e.getMessage(), e);
}
}
正如我在几个教程中所读到的,"prepare()" 方法需要一点时间才能完成。因此我实现了一个 "Waiting loop" 等待所有 MP 准备和创建。
"prepare and create" 完成后,我启用“开始”按钮,我想同时启动所有 3 个媒体播放器。
我再次使用线程来这样做:
public void onClick(View v) {
// Button 1
if (mBtn.getId() == v.getId()) {
mTT1.startMusic();
mTT2.startMusic();
mTT3.startMusic();
}
线程中的代码:
public class TrackThread extends Thread implements OnPreparedListener {
...
...
...
// start
public void startMusic() {
if (mMp == null)
return;
mMp.start();
}
请注意,上面的代码不是完整代码,但应该足以定义我的问题。
我想要的,我的问题:
所有议员都应该同步播放他们的音乐,不幸的是,有时当我开始播放音乐时,它们之间会有时间延迟。
MP 必须与 3 个音频文件同时播放(并且完全同步)的时间完全相同
我已经尝试过的:
+) 使用 SoundPool:对于 SoundPool
,我的音频文件太大(5MB 或更大)
+) seekTo(msec): 我想搜索每个 MP 到特定时间:例如:0,但这并没有解决问题。
+) 接触更多的程序员 我也问过这个问题:coderanch.com
希望有人能帮助我!
提前致谢
因为没有人能帮助我,所以我自己找到了解决方案。 MediaPlayer
没有满足我的要求,但是 Android JETPlayer
结合 JETCreator
满足了。
注意:安装 Python 以使用 JETCreator 非常棘手,因此
关注 this tutorial。请注意 python 和 wxpython
的版本,并非所有版本都支持 JETCreator。
我用过:
- Python 版本 2.5.4 (python-2.5.4.msi)
- wxPython 2.8 (wxPython2.8-win32-unicode-2.8.7.1-py25.exe)
对于那些不知道如何实现 Jetplayer 手表的人 this video
(在第 5 分钟,他开始对 Jetplayer 进行编程)。
不幸的是,我不会说法语,所以我只是遵循了对我有用的代码。
使用 Android JETCreator
您可以创建自己的 JET 文件并将它们用作您的资源。
有用的链接:
这里的瓶颈肯定是准备播放媒体播放器。 Android 框架提供了一种异步方法来执行此加载,因此通过一些同步代码,您应该能够让这些音频源大致同时播放。为避免声音失真,您需要少于 10 毫秒的延迟。
将原子计数器 C 初始化为要加载的事物数。
使用 MediaPlayer 中的 prepareAsync() 函数准备所有三个。在调用 prepareAsync 之后,立即使用 setOnPreparedListener(listener) 提供一个监听器。
在此侦听器中,递减 C 并检查值。如果该值大于 0,则使用 java 对象 .wait() 函数等待对象。如果该值等于 0,则在对象上调用 notifyAll() 以唤醒所有其他媒体播放器准备好的侦听器回调线程。
public void startMediaPlayers(List<MediaPlayer> mediaPlayers) {
private AtomicInteger counter = new AtomicInteger(mediaPlayers.size());
Object barrier = new Object();
/* start off all media players */
for (MediaPlayer player : mediaPlayers) {
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mediaPlayer) {
int value = counter.decrementAndGet();
if (value == 0) {
// all media players are done loading.
// wake up all the ones that are asleep
barrier.notifyAll();
} else {
while (value > 0) {
try {
// wait for everyone else to load
barrier.wait();
} catch (InterruptedException e) {
// ignore
}
}
}
mediaPlayer.start();
callback.success(true);
}
player.prepareAsync();
}
}
我有: 我在我的应用程序中实现了三个 MediaPlayer.Objects。 这三个都是使用线程创建的:
protected void onResume() {
// Threads
mTT1 = new TrackThread(this, R.raw.audiofile1, 1, mHandler);
mTT2 = new TrackThread(this, R.raw.audiofile2, 2, mHandler);
mTT3 = new TrackThread(this, R.raw.audiofile3, 3, mHandler);
// start thread
mTT1.start();
mTT2.start();
mTT3.start();
super.onResume();
}
"simplified" 线程中用于创建的代码:
public class TrackThread extends Thread implements OnPreparedListener {
...
...
...
public void run() {
super.run();
try {
mMp.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getDeclaredLength());
mMp.prepare();
} catch (IllegalArgumentException | IllegalStateException
| IOException e) {
Log.e(TAG, "Unable to play audio queue do to exception: "
+ e.getMessage(), e);
}
}
正如我在几个教程中所读到的,"prepare()" 方法需要一点时间才能完成。因此我实现了一个 "Waiting loop" 等待所有 MP 准备和创建。
"prepare and create" 完成后,我启用“开始”按钮,我想同时启动所有 3 个媒体播放器。
我再次使用线程来这样做:
public void onClick(View v) {
// Button 1
if (mBtn.getId() == v.getId()) {
mTT1.startMusic();
mTT2.startMusic();
mTT3.startMusic();
}
线程中的代码:
public class TrackThread extends Thread implements OnPreparedListener {
...
...
...
// start
public void startMusic() {
if (mMp == null)
return;
mMp.start();
}
请注意,上面的代码不是完整代码,但应该足以定义我的问题。
我想要的,我的问题:
所有议员都应该同步播放他们的音乐,不幸的是,有时当我开始播放音乐时,它们之间会有时间延迟。
MP 必须与 3 个音频文件同时播放(并且完全同步)的时间完全相同
我已经尝试过的:
+) 使用 SoundPool:对于 SoundPool
,我的音频文件太大(5MB 或更大)+) seekTo(msec): 我想搜索每个 MP 到特定时间:例如:0,但这并没有解决问题。
+) 接触更多的程序员 我也问过这个问题:coderanch.com
希望有人能帮助我!
提前致谢
因为没有人能帮助我,所以我自己找到了解决方案。 MediaPlayer
没有满足我的要求,但是 Android JETPlayer
结合 JETCreator
满足了。
注意:安装 Python 以使用 JETCreator 非常棘手,因此
关注 this tutorial。请注意 python 和 wxpython
的版本,并非所有版本都支持 JETCreator。
我用过:
- Python 版本 2.5.4 (python-2.5.4.msi)
- wxPython 2.8 (wxPython2.8-win32-unicode-2.8.7.1-py25.exe)
对于那些不知道如何实现 Jetplayer 手表的人 this video (在第 5 分钟,他开始对 Jetplayer 进行编程)。 不幸的是,我不会说法语,所以我只是遵循了对我有用的代码。
使用 Android JETCreator
您可以创建自己的 JET 文件并将它们用作您的资源。
有用的链接:
这里的瓶颈肯定是准备播放媒体播放器。 Android 框架提供了一种异步方法来执行此加载,因此通过一些同步代码,您应该能够让这些音频源大致同时播放。为避免声音失真,您需要少于 10 毫秒的延迟。
将原子计数器 C 初始化为要加载的事物数。
使用 MediaPlayer 中的 prepareAsync() 函数准备所有三个。在调用 prepareAsync 之后,立即使用 setOnPreparedListener(listener) 提供一个监听器。
在此侦听器中,递减 C 并检查值。如果该值大于 0,则使用 java 对象 .wait() 函数等待对象。如果该值等于 0,则在对象上调用 notifyAll() 以唤醒所有其他媒体播放器准备好的侦听器回调线程。
public void startMediaPlayers(List<MediaPlayer> mediaPlayers) {
private AtomicInteger counter = new AtomicInteger(mediaPlayers.size());
Object barrier = new Object();
/* start off all media players */
for (MediaPlayer player : mediaPlayers) {
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mediaPlayer) {
int value = counter.decrementAndGet();
if (value == 0) {
// all media players are done loading.
// wake up all the ones that are asleep
barrier.notifyAll();
} else {
while (value > 0) {
try {
// wait for everyone else to load
barrier.wait();
} catch (InterruptedException e) {
// ignore
}
}
}
mediaPlayer.start();
callback.success(true);
}
player.prepareAsync();
}
}