是否可以让 MediaPlayer 播放一个音频文件并在播放完后播放下一个?
Is it possible to have MediaPlayer play one audio file and when it finishes play the next?
我希望 MediaPlayer 接受一个 songTitles 数组列表并让它检查出现了哪个歌曲标题,然后播放该歌曲。完成后,我希望它转到循环中的下一首歌曲并播放该歌曲。但是,我的代码只播放最后一首歌。
public void play(Context c, ArrayList<String> songTitles) {
stop();
for (String song: songTitles){
if (song.equalsIgnoreCase("shakeItOff")){
mSongPlayer = MediaPlayer.create(c, R.raw.shaketoff);
} else if (song.equalsIgnoreCase("dropItLow")){
mSongPlayer = MediaPlayer.create(c, R.raw.dropitlow);
} else if (song.equalsIgnoreCase("chachaslide")){
mSongPlayer = MediaPlayer.create(c, R.raw.chachaslide);
}
mSongPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp == mSongPlayer) {
mSongPlayer.start();
}
}
});
mSongPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stop();
}
});
}
}
你需要使用 MediaPlayer.OnCompletionListener
来在前一个曲目结束时开始新的曲目,所以你可以做更多类似下面的事情(我没有编译它,所以可能会有一些语法错误):
public void play(final Context c, ArrayList<String> songTitles) {
stop();
if (songTitles != null && songTitles.size > 0) {
final List<String> playList = new ArrayList<String>(songTitles);
String song = playList.get(0);
playList.remove(0);
mSongPlayer = MediaPlayer.create(c, getSongResourceId(song));
mSongPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp == mSongPlayer) {
mSongPlayer.start();
}
}
});
mSongPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stop();
// Recursively call the play() method with one less
// track in the list.
play(c, playList);
}
});
}
}
public int getSongResourceId(String songTitle) {
if (song.equalsIgnoreCase("shakeItOff")){
return R.raw.shaketoff;
} else if (song.equalsIgnoreCase("dropItLow")){
return R.raw.dropitlow;
} else if (song.equalsIgnoreCase("chachaslide")){
return R.raw.chachaslide;
}
}
第一次播放列表中的第一首曲目,然后在 MediaPlayer.OnCompletionListener
中,它使用包含第一首曲目的列表副本递归调用 play()
方法从中删除。这意味着每次调用 play()
时,列表都会变短,直到到达列表末尾。
我不确定是否有办法只使用一个 MediaPlayer 来完成。
但是,由于以下原因,我确定您只播放了最后一首歌:
- 每次创建 MediaPlayer 时,都会覆盖之前的 MediaPlayer,因此如果您的第一个 MediaPlayer 用于 "shakeItOff",下一个用于 "dropItDown",当您到达最后一个时, "chachaslide",您最终引用了一个将播放 chachaslide 的 MediaPlayer。
- 每次执行循环时,您都会覆盖之前附加的最后一个 OnCompletionListener。因此,您以附加的最后一个听众(您的最后一首歌)结束
- 您将准备好的MediaPlayer声明为当前的MediaPlayer,所以即使您设法准备好每个MediaPlayer来播放,您也只会播放currentOne,因为1是"chachaslide"。
您可以在此处查看 MediaPlayer 的生命周期:http://developer.android.com/reference/android/media/MediaPlayer.html
因此,您可以重用相同的 MediaPlayer 引用的唯一方法是自己管理它,否则您在 MediaPlayer 的内存中至少有 3 个实例
我希望 MediaPlayer 接受一个 songTitles 数组列表并让它检查出现了哪个歌曲标题,然后播放该歌曲。完成后,我希望它转到循环中的下一首歌曲并播放该歌曲。但是,我的代码只播放最后一首歌。
public void play(Context c, ArrayList<String> songTitles) {
stop();
for (String song: songTitles){
if (song.equalsIgnoreCase("shakeItOff")){
mSongPlayer = MediaPlayer.create(c, R.raw.shaketoff);
} else if (song.equalsIgnoreCase("dropItLow")){
mSongPlayer = MediaPlayer.create(c, R.raw.dropitlow);
} else if (song.equalsIgnoreCase("chachaslide")){
mSongPlayer = MediaPlayer.create(c, R.raw.chachaslide);
}
mSongPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp == mSongPlayer) {
mSongPlayer.start();
}
}
});
mSongPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stop();
}
});
}
}
你需要使用 MediaPlayer.OnCompletionListener
来在前一个曲目结束时开始新的曲目,所以你可以做更多类似下面的事情(我没有编译它,所以可能会有一些语法错误):
public void play(final Context c, ArrayList<String> songTitles) {
stop();
if (songTitles != null && songTitles.size > 0) {
final List<String> playList = new ArrayList<String>(songTitles);
String song = playList.get(0);
playList.remove(0);
mSongPlayer = MediaPlayer.create(c, getSongResourceId(song));
mSongPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (mp == mSongPlayer) {
mSongPlayer.start();
}
}
});
mSongPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stop();
// Recursively call the play() method with one less
// track in the list.
play(c, playList);
}
});
}
}
public int getSongResourceId(String songTitle) {
if (song.equalsIgnoreCase("shakeItOff")){
return R.raw.shaketoff;
} else if (song.equalsIgnoreCase("dropItLow")){
return R.raw.dropitlow;
} else if (song.equalsIgnoreCase("chachaslide")){
return R.raw.chachaslide;
}
}
第一次播放列表中的第一首曲目,然后在 MediaPlayer.OnCompletionListener
中,它使用包含第一首曲目的列表副本递归调用 play()
方法从中删除。这意味着每次调用 play()
时,列表都会变短,直到到达列表末尾。
我不确定是否有办法只使用一个 MediaPlayer 来完成。 但是,由于以下原因,我确定您只播放了最后一首歌:
- 每次创建 MediaPlayer 时,都会覆盖之前的 MediaPlayer,因此如果您的第一个 MediaPlayer 用于 "shakeItOff",下一个用于 "dropItDown",当您到达最后一个时, "chachaslide",您最终引用了一个将播放 chachaslide 的 MediaPlayer。
- 每次执行循环时,您都会覆盖之前附加的最后一个 OnCompletionListener。因此,您以附加的最后一个听众(您的最后一首歌)结束
- 您将准备好的MediaPlayer声明为当前的MediaPlayer,所以即使您设法准备好每个MediaPlayer来播放,您也只会播放currentOne,因为1是"chachaslide"。
您可以在此处查看 MediaPlayer 的生命周期:http://developer.android.com/reference/android/media/MediaPlayer.html
因此,您可以重用相同的 MediaPlayer 引用的唯一方法是自己管理它,否则您在 MediaPlayer 的内存中至少有 3 个实例