为什么这个循环无法通过我的第一个MediaPlayer

时间:2012-08-24 16:37:58

标签: android loops media-player android-mediaplayer playlist

我有3个MediaPlayers:Track 0,Track 1和Track 2.我希望每首曲目在完成之前启动一次,一旦最后一首曲目结束,我想回到歌曲0并开始循环过度。这是我做的循环没有做到这一点:

public void myMusic() {
    while (y > 0) {
        music.get(track).start();

        if (music.get(track).isPlaying() == false) {
            music.get(track).stop();
            track++;

            if (track == 3) {
                track = 0;
                for (int i = 0; i < 3; i++) {
                    try {
                        music.get(i).prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    music.get(i).seekTo(0);
                }
            }
        }
        y--;
    }
}

3 个答案:

答案 0 :(得分:0)

我认为你必须在检查track == 3之前关闭第一个if块。但这只是一个我不尝试的建议。

答案 1 :(得分:0)

坦率地说,我放弃了整个循环概念并使用OnCompletionListener。像这样的东西可能会起作用 - 我没有测试过这个,只是把它从我疯狂的头脑中拉出来,但把它作为概念:

private class LoopingCompletionListener implements OnCompletionListener {
    private int index;
    private int count;
    private int[] ids;
    private Resources res;

    public LoopingCompletionListener(int[] musicIds, Resources res) {
        //start on the second ID since you start the player with
        //the first one
        index = 1;
        count = musicIds.length();
        this.ids = ids;
        this.res = res;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        //Basically, just keep it between 0-2 -- this might need tweaking
        index = ((index + 2) % count) - 1;

        AssetFileDescriptor afd = res.openRawResourceFd(ids[index]);
        FileDescriptor fd = afd.getFileDescriptor();

        mp.reset();
        mp.setDataSource(fd, afd.getStartOffset(), afd.getLength());
        mp.prepare();
        mp.start();
    }
}

//Meanwhile, in onCreate()...
int[] musicIds = { R.raw.track01, R.raw.track02, R.raw.track03 };

MediaPlayer mediaPlayer = MediaPlayer.create(this, musicIds[0]);
mediaPlayer.setOnCompletionListener(
        new LoopingCompletionListener(musicIds, getResources());
mediaPlayer.start();

答案 2 :(得分:0)

如果我不得不猜测,当您将MediaPlayer状态设置为暂停或停止时,isPlaying()仅为false。换句话说,你不能简单地依靠它来确定音乐何时到达流的末尾以确定它何时完成。

另外,来自文档:

  

请注意,从START状态到Paused状态的转换(反之亦然)在播放器引擎中异步发生。在调用isPlaying()时更新状态可能需要一些时间,对于流内容,它可能需要几秒钟。

因此,对于像这样的用例来说,这是一个不可靠的指标。

您可以做的是利用MediaPlayer.OnCompletionListener。为每个可用的MediaPlayer注册一个,完成后,您将前进到下一个MediaPlayer。

这样的事情:

public class PlayUponCompleteListener implements MediaPlayer.OnCompletionListener {
   WeakReference<MediaPlayer> mNextPlayer;

   public PlayUponCompleteListener(MediaPlayer mp) {
     mNextPlayer = new WeakReference<MediaPlayer>(mp);
   }

   @Override
   public void onCompletion(MediaPlayer mp) {
     mp.stop();
     mp.reset();
     if(mNextPlayer.get() != null) {
       mNextPlayer.start();
     }
   }
}

然后,像这样注册:

mp1.setOnCompletionListener(new CompletionListener(mp2));
mp2.setOnCompletionListener(new CompletionListener(mp3));
mp3.setOnCompletionListener(new CompletionListener(mp1));