Android MediaPlayer 在2.1版本上抛出 "Prepare failed.: status=0x1" 错误,但在2.2版本上正常工作

37

我一直在尝试使用MediaPlayer类在Android 2.1上播放H.264编码的视频,但一直没有进展。我的代码非常简单:

  AssetFileDescriptor fileDescriptor = getResources().openRawResourceFd(R.raw.my_movie);
  introMoviePlayer = new MediaPlayer();
  introMoviePlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getDeclaredLength());
  introMoviePlayer.prepare();

这总是在prepare()处抛出异常,异常信息为java.io.IOException:Prepare failed .: status=0x1。通过使用带有URI的MediaPlayer.create(),我获得了更多信息,它也在prepare()处抛出异常,实际上由MediaPlayer.create()调用,并显示消息Command PLAYER_PREPARE completed with an error or info PVMFErrResourceConfiguration

相同的代码在Froyo(2.2)中完美运行。这些视频在视频播放器应用程序中也可以正常播放。是否有人可能有一个有用的提示,可以帮助解决这个问题?

编辑:仍然没有解决方案-非常令人沮丧的问题。但是,我发现通过创建一个VideoView并为原始视频设置URI可行。这非常令人困惑,因为将完全相同的URI通过MediaPlayer类发送将导致异常。


你尝试过将文件存储在SD卡中并传递其自身路径的代码吗? - Pedriyoo
有点晚了,但我猜MediaPlayer的构造函数有一个重载,可以接受资源ID作为参数。 - Samuel
在我的情况下,我在网址信息处启用了Gzip压缩。在Android上可能无法解码压缩的媒体文件。 - İlker Elçora
15个回答

32

这是我的解决方案:

MediaPlayer mediaPlayer = new MediaPlayer();
FileInputStream fis = null;
try {
    File directory = new File("android.resource://com.example.myapp/raw/");
    fis = new FileInputStream(directory);
    mediaPlayer.setDataSource(fis.getFD());
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.prepare();
}   finally {
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException ignore) {
        }
    }

}

3
仅仅是对本地文件的提醒。如果MediaPlayer.setDataSource(String path)出现准备错误,则此解决方法也无法奏效。因为在MediaPlayer.setDataSource(String path)的后台逻辑中,它也使用了setDataSource(FileDescriptor fd)。 - Hexise

20

我已经不在同一家公司工作了,所以无法确定这个解决方案是否能够解决这个问题。然而,我会将其标记为正确答案,因为这是我迄今为止看到的关于这个相当晦涩的错误的最佳资源。 - Nik Reiman
我认为那个博客已经不存在了。请将答案移植到这里。 - Jason Robinson
我设法从存档网站中找到了这篇博客。一旦你上了网,它就永远存在。 - Ryan Heitner

8
我知道我来晚了,但希望这能帮助其他人。我通过设置一个setOnCompletionListener回调来解决了这个问题,在媒体播放完成后明确释放MediaPlayer对象。
我不能为此解决方案负责,因为最初是由Ronny在这里发布的: 如何检测声音文件何时完成? 但由于这是我在搜索Android + Failed Status 0x1时的第一个答案,这是我的代码,解决了这个问题:
 public void playSound(String soundPath){
    MediaPlayer m = new MediaPlayer();

    m.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
        }

    });

    try {

        AssetFileDescriptor descriptor = mContext.getAssets().openFd(soundPath);
        m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(),
                        descriptor.getLength());            

        descriptor.close();

        m.prepare();
        m.setVolume(100f, 100f);
        m.setLooping(false);
        m.start();

    } catch (Exception e) {
        //Your catch code here.
    }
 }   

7

如果从远程URL读取时遇到此问题,

我的URL都是非安全的(即http而不是https),

由于我无法访问服务器URL(第三方),

我不得不在Android清单中添加以下内容。

<application
    ...
    android:usesCleartextTraffic="true"
    ...
</application>

4

如果您正在使用多个MediaPlayer实例,请确保在尝试在另一个实例中使用资源之前执行了release()


3

初始化文件名和媒体播放器实例:

private MediaPlayer mp;
private final static String fileName = "ring";

从res/raw目录播放/启动音频文件的方法:

        try 
        {   
            mp = new MediaPlayer();
            mp.setAudioStreamType(AudioManager.STREAM_RING); //set streaming according to ur needs
            mp.setDataSource(Context, Uri.parse("android.resource://yourAppPackageName/raw/"+fileName));
            mp.setLooping(true);
            mp.prepare();
            mp.start();

        } catch (Exception e) 
        {
            System.out.println("Unable to TunePlay: startRingtone(): "+e.toString());
        }

最终停止音频文件:

    try
    {
        if (!(mp == null) && mp.isPlaying())
        {
            mp.stop();
            mp.release(); //its a very good practice
        }       
    }
    catch (Exception e)
    {
        System.out.println("Unable to  TunePlay: stopRingtone():"+e.toString());
    }

2

我知道可能已经晚了。我成功地使用了资源中的视频,就像这样:

MediaPlayer mp = ...;
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/" + R.raw.my_movie);
mp.setDataSourceUri(this, uri);

2

我找到了这个错误的最佳和清晰的解决方法:java.io.IOException: Prepare failed.: status=0x1

注意

如果你想从SD卡中读取文件并遇到了这个错误,那么你需要在Manifest文件中添加:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 权限。

注意2

如果你想从URL播放媒体文件并遇到了这个错误,可能是因为你在setDataSource中使用了如下形式的URL:https://www.android.com。请将其中的https改为http即可,像这样:http://www.android.com


2

在我看来,我建议您检查媒体文件的位置 <<歌曲路径或电影路径>>。我曾遇到过这个异常,但通过正确的“歌曲路径”解决了它。


2
我遇到了类似的问题。我有一个包含压缩声音文件的zip文件。为了传递给MediaPlayer,它们需要被解压缩。当我把它们放在应用程序的缓存目录(context.getCacheDir())中时,MediaPlayer返回了你描述的相同错误。
但是当我把它们放在外部存储中(Environment.getExternalStorageDirectory()),一切都开始正常工作了。

我也将它们放在外部存储上(Environment.getExternalStorageDirectory()),一切都开始正常工作了。 - Ram G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接