1

トラック 0、トラック 1、およびトラック 2 の 3 つの MediaPlayer があります。各トラックが終了する前に 1 回開始し、最後のトラックが終了したら、曲 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

率直に言って、私はループ全体の概念を放棄し、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

私が推測しなければならなかったのは、MediaPlayer の状態を一時停止または停止に設定した場合isPlaying()のみです。falseつまり、音楽がいつストリームの最後に到達したかを判断して、いつ終了したかを判断するために単純に信頼することはできません。

また、ドキュメントから:

開始状態から一時停止状態への遷移、およびその逆の遷移は、プレーヤー エンジンで非同期に発生することに注意してください。isPlaying() の呼び出しで状態が更新されるまでに時間がかかる場合があり、ストリーミング コンテンツの場合は数秒かかる場合があります。

したがって、このようなユースケースでは信頼できない指標です。

代わりにできることは、を利用することですMediaPlayer.OnCompletionListener。利用可能な MediaPlayer ごとに 1 つ登録すると、完了時に次の 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 に答える
0

track==3 かどうかを確認する前に、最初の if ブロックを閉じる必要があると思います。しかし、これは私が試していない単なる提案です。

于 2012-08-24T17:29:56.910 に答える