单击按钮时,我需要播放从我的资产加载的多个(正确:2)mp3文件。如果再次单击按钮,则应播放2首新歌曲,并立即停止旧歌曲。这个过程正在进行中...目前,我已经通过在 2 种基本上具有相同主体的独立方法中愚蠢地创建 2 个 mediaPlayer 实例来实现这一点。 调用方是一个 onTouch 方法,在其中,我首先调用方法 1,然后休眠 2 秒,然后调用方法 2。我相信一定有一种方法可以让这成为更优雅的代码?例如,我已经实现了一些只是坐在那里的听众(实际上试图使这项工作,但完全搞砸了非法状态到处都是)。理想情况下,我想使用 1 个媒体播放器和一种方法来播放我的应用程序中的每个声音。
int carouzelIndex = 0
@Override
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
...
if (e.getAction() == MotionEvent.ACTION_UP) {
carouzelIndex++;
Assets.playMusic1("music1.ogg",false);
Thread thread = new Thread(){
public void run(){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assets.playMusic2("music2.ogg",false);
}
}
}
}
现在我的播放器方法 1 和 2(playMusic1() 和 playMusic2() )是相同的。两者都是不同的媒体播放器,为了简单起见,我只在帖子中写了一个副本
Public class Assets
MediaPlayer mediaPlayer;
public static void playMusic(String filename, boolean looping) {
AssetFileDescriptor afd = null;
Log.d("Assets", "playing music");
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
}
try {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
}
afd = GameMainActivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (!mp.isPlaying())
mp.start();
}
});
mediaPlayer.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
}
});
mediaPlayer.setOnInfoListener(new OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
要立即播放,您需要设置两个媒体播放器并通过OnCompletionListener链接在一起
你可以这样做:
请注意,我还删除了一些不必要的覆盖,如果需要,您可以再次添加它们。
Public class Assets{
MediaPlayer mediaPlayer;
MediaPlayer mediaPlayer2;
boolean mediaplayer2prepared = false;
boolean mediaplayer1finished = false;
public static void playMusic(String filename, boolean looping, String filename2, boolean looping2) {
AssetFileDescriptor afd = null;
Log.d("Assets", "playing music");
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
mediaplayer1finished = false;
}
if (mediaPlayer2 == null) {
mediaPlayer2 = new MediaPlayer();
mediaPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer2.setLooping(looping);
mediaplayer2prepared = false;
}
try {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
mediaplayer1finished = false;
}
if (mediaPlayer2 != null) {
mediaPlayer2.stop();
mediaPlayer2.release();
mediaPlayer2 = new MediaPlayer();
mediaplayer2prepared = false;
mediaPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer2.setLooping(looping);
}
afd = GameMainActivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (!mp.isPlaying())
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
if(mediaplayer2prepared)
mediaplayer2.start();
mediaplayer1finished = true;
}
});
mediaPlayer.prepareAsync();
afd2 = GameMainActivity.assets.openFd(filename2);
mediaPlayer2.setDataSource(afd2.getFileDescriptor(),
afd2.getStartOffset(), afd2.getLength());
afd2.close();
mediaPlayer2.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
mediaplayer2prepared = true;
if(mediaplayer1finished && !mp.isPlaying()){
mp.start();
}
}
});
mediaPlayer2.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
}
});
mediaPlayer2.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
}
要连续启动两个媒体播放器,只需执行Assets.playMusic("music1.ogg",false, "music2.ogg",false);
你可以尝试这样的事情。在单个线程中使用单个媒体播放器。这是一个异步操作,因此如果线程暂停,它也将继续。我认为它会起作用。
private Thread t = null;
private MediaPlayer mediaPlayer;
...
Button b=findViewById(R.id.yourButtonId);
b.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//if button had previously clicked stop audio reproduction
if(mediaPlayer.isPlaying()) mediaPlayer.stop();
if(t.isAlive()) t.stop();
String[] files;
//Here you have to set your filenames in the array
...
...
//Now play that audio
playMusic(files, false);
}
});
...
protected static void playMusic(String[] files, boolean looping){
AssetFileDescriptor afd = null;
Log.e("Assets", "Playing music");
t=new Thread(){
@Override
public void run(){
//Initialize mediaPlayer
for(String filename:files){
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
afd = GameMainAcivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),afd.getLength());
afd.close();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp){
if(!mp.isPlaying()) mp.start();
}
});
//while audio is playing wait in this position
while(mediaPlayer.isPlaying()){
this.wait(100);
}
//now loop can restart with the other filename that has
//to be reproduced
}
}
};
t.start();
}