web-dev-qa-db-ja.com

MediaPlayer.prepareAsyncのIllegalStateException

05-19 11:52:51.622: ERROR/MediaPlayer(1291): prepareAsync called in state 8
05-19 11:52:51.622: WARN/System.err(1291): Java.lang.IllegalStateException
try {
    mp = MediaPlayer.create(
            Main.this,
            Uri.parse("http://codejanitor.us/good.mp3"));
    mp.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
    try {
        mp.prepareAsync();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
} finally {
    if (mp != null) {
        mp.release();
        mp = null;
    }
}

交互に

私が行った場合:

try {
    mp = MediaPlayer.create(
            AmazonClipActivity.this,
            Uri.parse("http://codejanitor.us/good.mp3"));
    mp.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
} finally {
    if (mp != null) {
        mp.release();
        mp = null;
    }
}

私は得る:

05-19 12:22:57.472: DEBUG/MediaPlayer(1635): Couldn't open file on client side, trying server side
05-19 12:22:57.472: INFO/StagefrightPlayer(68): setDataSource('http://codejanitor.us/good.mp3')
05-19 12:22:57.482: INFO/NuHTTPDataSource(68): connect to codejanitor.us:80/good.mp3 @0
05-19 12:23:00.632: INFO/NuCachedSource2(68): ERROR_END_OF_STREAM
34
hunterp

mp = MediaPlayer.create(...); は、返されるMediaPlayerをすでに準備しているため、prepare(またはそのバリアント)を再度呼び出すことはできません(onPreparedListenerも必要ありません)。

88
MByD

"状態8で準備されたprepareAsync"は、Mediaplayerが既に準備されていることを意味します。

あなたのコードでmp.prepare();を呼んでいますか?

10
Jorgesys

更新された質問:

  1. _AndroidManifest.xml_にインターネットアクセス許可があるかどうかを確認します
  2. インターネットからストリーミングしたいので、何らかのデータ接続が有効になっているかどうかを確認してください
  3. 「このソリューションも失敗する」とはどういう意味ですか? IllegalStateExceptionをスローしますか?私が見るところ、MediaPlayerオブジェクトが準備された後にOnPreparedListenerを登録すると、onPrepared()メソッドが呼び出されないため、まったく何もしません。

より良いアプローチは次のように書くことです:

_MediaPlayer mp = new MediaPlayer();  
mp.setDataSource("http://.../movie.mp4");  
mp.setOnPreparedListener(this);  
mp.prepareAsync();
_
8
Timmos

以下のコードを使用して、httpのサウンドファイルを再生します。

BackgroundSound mBackgroundSound = new BackgroundSound();

public void onSoundRequested(final Uri uri) {
    mBackgroundSound = new BackgroundSound();
    mBackgroundSound.execute(new SoundModel(dicId, uri));
}

public class BackgroundSound extends AsyncTask<SoundModel, Void, Void> {
    MediaPlayer mediaPlayer;

    @Override
    protected Void doInBackground(SoundModel... params) {
        SoundModel model = params[0];
        final Uri uri = model.getUri();

        if (uri == null || uri == Uri.EMPTY) return null;
        if (mediaPlayer != null) mediaPlayer.stop();

        try {
            mediaPlayer = MediaPlayer.create(VocabularyActivity.this, uri);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        } catch (Exception e) {
            // do nothing.
        }
        if (mediaPlayer == null) return null;

        mediaPlayer.setVolume(1.0f, 1.0f);
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mediaPlayer.reset();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        });
        mediaPlayer.start();
        return null;
    }
}

Warnimg W/MediaPlayer: Couldn't open https://something.com/test.mp3: Java.io.FileNotFoundException: No content provider: https://something.com/test.mp3を示していますが、正常に動作します。

0
Youngjae

基本問題は、「許可されていない状態」でMediaPlayerのメソッドを呼び出すことにあります。状態図は ここに表示 です。たとえば、メディアファイルをpreparingなしでstart()メソッドを呼び出すことは許可されておらず、例外をスローします。

MediaPlayergetState()メソッドを公開しないため、状態を外部で追跡する必要があります。サンプル実装は こちら になります。

0