1

我有 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--;
    }
}
4

3 回答 3

0

I think you have to close the first if block befor you check if track==3. But this is just a suggestion i dont try it.

于 2012-08-24T17:29:56.910 回答
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();
于 2012-08-24T18:01:54.900 回答
0

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

另外,从文档中:

请注意,从 Started 状态到 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));
于 2012-08-24T18:03:33.783 回答