调用setDataSource(FileDescriptor)方法时出现exception(失败:状态= 0x80000000)

我正在开发一个video流应用程序,并且在使用FileDescriptor调用set setDataSource时遇到困难。 我希望我的应用程序在下载时播放video,所以一旦我得到最小字节数,我将这些字节移动到另一个文件,这样当它被下载到原始文件中时,它可以在另一个文件中播放。

所以,我检查一下我是否可以像这样启动每个数据包的媒体:

if (mediaPlayer == null) { // Only create the MediaPlayer once we have the minimum // buffered data if (totalKbRead >= INTIAL_KB_BUFFER) { try { startMediaPlayer(); } catch (Exception e) { Log.e(getClass().getName(), "Error copying buffered conent.", e); } } } else if (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000) { transferBufferToMediaPlayer(); } } 

这是startMediaPlayer方法代码:

 private void startMediaPlayer() { try { File bufferedFile = new File(context.getCacheDir(), "playingMedia" + (counter++) + ".dat"); // bufferedFile is the one that'll be played moveFile(downloadingMediaFile, bufferedFile); mediaPlayer = createMediaPlayer(bufferedFile); mediaPlayer.start(); playButton.setEnabled(true); } catch (IOException e) { Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e); return; } 

我使用以下代码移动文件:

 public void moveFile(File oldLocation, File newLocation) throws IOException { if (oldLocation.exists()) { BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation)); BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false)); try { byte[] buff = new byte[8192]; int numChars; while ((numChars = reader.read(buff, 0, buff.length)) != -1) { writer.write(buff, 0, numChars); } } catch (IOException ex) { throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); } finally { try { if (reader != null) { writer.flush(); writer.close(); reader.close(); } } catch (IOException ex) { Log.e(getClass().getName(), "Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); } } } else { throw new IOException( "Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); } } } 

我最终在这里创建了MediaPlayer对象:

 private MediaPlayer createMediaPlayer(File mediaFile) throws IOException { if(mediaPlayer != null){ mediaPlayer.release(); } MediaPlayer mPlayer = new MediaPlayer(); mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer mp, int what, int extra) { Log.e(getClass().getName(), "Error in MediaPlayer: (" + what + ") with extra (" + extra + ")"); return false; } }); // It appears that for security/permission reasons, it is better to pass // a FileDescriptor rather than a direct path to the File. // Also I have seen errors such as "PVMFErrNotSupported" and // "Prepare failed.: status=0x1" if a file path String is passed to // setDataSource(). FileInputStream fis = new FileInputStream(mediaFile); mPlayer.reset(); FileDescriptor fd = fis.getFD(); mPlayer.setDataSource(fd); // IM GETTING THE EXCEPTION HERE mPlayer.setDisplay(mHolder); mPlayer.prepare(); return mPlayer; } 

这是我得到的例外情况:

 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): Error initializing the MediaPlayer. 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): java.io.IOException: setDataSourceFD failed.: status=0x80000000 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.media.MediaPlayer.setDataSource(Native Method) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:854) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at org.pfc.utils.StreamingMediaPlayer.createMediaPlayer(StreamingMediaPlayer.java:266) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at org.pfc.utils.StreamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:226) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at org.pfc.utils.StreamingMediaPlayer.access$4(StreamingMediaPlayer.java:203) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at org.pfc.utils.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:183) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.os.Handler.handleCallback(Handler.java:587) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.os.Handler.dispatchMessage(Handler.java:92) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.os.Looper.loop(Looper.java:144) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at android.app.ActivityThread.main(ActivityThread.java:4937) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at java.lang.reflect.Method.invokeNative(Native Method) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at java.lang.reflect.Method.invoke(Method.java:521) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): at dalvik.system.NativeStart.main(Native Method) 

我整个上午都被困在这里,我真的没有find关于这个错误的信息。 有些人告诉我使用文件路径,但是我得到了我在评论中讨论的另一个例外(正好在FileInputStream创建中)。

我真的迷失在这里,任何帮助都会非常感激

别忘了许可

  

好的,我得出的结论是:

准备失败:status = 0x1(调用prepare()时)

setDataSourceFD失败:status = 0x80000000(调用setDataSourceFD()时)

与文件格式有关,可能意味着文件不完整,已损坏或类似…

正如我在这个链接中发布的那样,我发现了一个特定的video在流式播放时工作正常(虽然我使用的是setDataSource ,而不是setDataSourceFD ),但它不适用于大多数video。

有同样的错误,并且已经阅读了上面的文件格式的答案,我放弃尝试使用我的.mov文件setDataSource,而是用我的Android Telefon Camera创建了一个video,它给了我一个.mp4文件。 我把它放在图片/目录中。 这工作 – 我没有错误地setDataSource。 我希望这对某人有用。

 File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyDirectoryUnderPictures"); File mediaFile_mp4_android; mediaFile_mp4_android = new File(mediaStorageDir.getPath() + File.separator + "mp4_test" + ".mp4"); //video taken with android camera String filePath_mp4_android = String.valueOf(mediaFile_mp4_android); File file_mp4_android = new File(filePath_mp4_android); Uri contentUri = Uri.fromFile(file_mp4_android); MediaMetadataRetriever mmr = new MediaMetadataRetriever(); mmr.setDataSource(String.valueOf(contentUri)); 

根据我的阅读,某些video文件格式在文件的END上有“标题”信息。 因此,您的FD必须是支持搜索function才能从文件末尾获取“标题”。 我怀疑你的媒体播放器输入文件在寻找文件的“结尾”时失败了。

我们正在研究同样的问题你有进一步的发展吗?

肖恩

在我的情况下,从wav文件切换到mp3解决了状态= 0x80000000的此exception

在我的情况下,问题是因为当设备作为外部存储器安装到PC时因为易于使用的SD卡,因此检查文件是否可用解决了问题。 也许它有助于某人

如果您要定位Marshmallow或更高版本,请确保您已正确请求Manifest.permission.WRITE_EXTERNAL_STORAGE权限。 我尝试了许多不同的解决方案,包括另一个可以替代MediaMetadataRetriever库,但事实certificate我的一个代码路径没有请求适当的权限。

从obb扩展文件加载video时我遇到了同样的问题。 我通过替换修复它:

 mPlayer.setDataSource(fd); 

有:

 mPlayer.setDataSource(fis.getFileDescriptor(),fis.getStartOffset(),fis.getLength());