MediaPlayer.prepareAsync 的 IllegalStateException

Posted

技术标签:

【中文标题】MediaPlayer.prepareAsync 的 IllegalStateException【英文标题】:IllegalStateException for MediaPlayer.prepareAsync 【发布时间】:2011-08-29 00:28:51 【问题描述】:
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

【问题讨论】:

【参考方案1】:

mp = MediaPlayer.create(...); 已经在准备返回的 MediaPlayer,因此您不能再次调用 prepare(或其变体)(也不需要 onPreparedListener)。

【讨论】:

我用同样失败的替代代码路径更新了我的问题,感谢您的输入 请参考此链接:code.google.com/p/cyanogenmod/issues/detail?id=1023 @BinyaminSharet 您的链接已损坏。 这个答案可能会帮助到这里的人:***.com/a/53390067/826946【参考方案2】:

“在状态 8 中调用prepareAsync” 表示 Mediaplayer 已经准备好。

您是否在代码中调用mp.prepare();

【讨论】:

我用同样失败的替代代码路径更新了我的问题,感谢您的输入【参考方案3】:

您更新的问题:

    检查你的androidManifest.xml是否有INTERNET权限 检查您是否启用了某些数据连接,因为您想从 Internet 流式传输 “此解决方案也失败”是什么意思?它会抛出 IllegalStateException 吗?据我所知,它根本不会做任何事情,因为您在 MediaPlayer 对象准备好自己之后注册了 OnPreparedListener,从而导致永远不会调用 onPrepared() 方法。

更好的方法是写:

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

【讨论】:

【参考方案4】:

我使用下面的代码来播放 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;
    

它显示警告 W/MediaPlayer: Couldn't open https://something.com/test.mp3: java.io.FileNotFoundException: No content provider: https://something.com/test.mp3 但工作正常。

【讨论】:

【参考方案5】:

基本问题在于在“不允许的状态”下调用 MediaPlayer 的方法。状态图是shown here。例如,在没有准备媒体文件的情况下调用start()方法是不允许的,并且会抛出异常。

由于MediaPlayer 没有公开getState() 方法,您应该在外部跟踪状态。示例实现可以是found here。

【讨论】:

以上是关于MediaPlayer.prepareAsync 的 IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章