是否可以让MediaPlayer播放一个音频文件,当它完成下一个播放时?

时间:2015-07-14 23:56:35

标签: java android audio android-mediaplayer

我希望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();
            }
        });


    }
}

2 个答案:

答案 0 :(得分:3)

你需要使用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()时,列表都会缩短,直到我们到达列表的末尾。

答案 1 :(得分:0)

我不确定是否有办法只使用一个MediaPlayer。 但是,由于以下原因,我确信你只播放了最后一首歌:

  1. 每次创建MediaPlayer时,你都会覆盖之前的那个,所以如果你的第一个MediaPlayer用于“shakeItOff”,那么下一个用于“dropItDown”,当你到达最后一个时,“chachaslide”,你结束引用将播放chachaslide的MediaPlayer。
  2. 每次进行循环时,都会覆盖之前附加的最后一个OnCompletionListener。所以,你结束了你附加的最后一个听众(你的最后一首歌)
  3. 您正在将准备好的MediaPlayer断言到当前的MediaPlayer,因此即使您设法准备每个MediaPlayer,您也只会播放currentOne,因为1是“chachaslide”。
  4. 您可以在此处查看MediaPlayer的生命周期:http://developer.android.com/reference/android/media/MediaPlayer.html

    因此,您可以重复使用相同MediaPlayer引用的唯一方法是自己管理它,其他方式是在MediaPlayer内存中至少有3个实例