Исключение при вызове метода setDataSource (FileDescriptor) (не удалось: status = 0x80000000)
Я разрабатываю приложение для потоковой передачи видео, и я застреваю при вызове setDataSource с помощью FileDescriptor.
Я хочу, чтобы мое приложение воспроизводило видео по мере его загрузки, поэтому, как только я получу минимальное количество байтов, я перемещаю эти байты в другой файл, чтобы он мог воспроизводиться в другом файле, когда он загружается в исходный файл.
Итак, я проверяю, могу ли я запустить media palyer для каждого пакета следующим образом:
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)
Я весь вечер застрял здесь, и я действительно не нашел никакой информации об этой ошибке. Некоторые люди сказали мне использовать путь к файлу, но я получаю другое исключение, о котором я говорю в комментариях (прямо над созданием FileInputStream).
Я действительно потерялся здесь, любая помощь будет очень оценена
Ответы
Ответ 1
Хорошо, я пришел к выводу, что такие ошибки, как:
Не удалось выполнить команду: status = 0x1 (при вызове prepare())
и
setDataSourceFD failed: status = 0x80000000 (при вызове setDataSourceFD())
имеют отношение к формату файла и, вероятно, означают, что файл неполный, поврежден или что-то в этом роде...
Как я уже писал в этой ссылке, я нашел конкретное видео, которое отлично работает при потоковой передаче (хотя я использую setDataSource
, а не setDataSourceFD
), но он не будет работать с большинством видео.
Ответ 2
Не забывайте разрешения
<uses-permission android:name="android.permission.INTERNET" />
Ответ 3
с той же ошибкой и, прочитав ответ выше в формате файла, я отказался от попыток setDataSource с моим файлом .mov и вместо этого создал видео с моей Android-телефонией Telefon, которая дала мне файл .mp4.
Я помещаю это в каталог Pictures/.
Это сработало - я заставляю 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));
Ответ 4
Из того, что я прочитал, некоторые форматы видеофайлов имеют заголовок "заголовка в END файла. Таким образом, ваш FD должен быть поддержкой функции поиска, чтобы получить" заголовок "с конца файла. Я подозреваю, что ваш входной файл для медиаплеера терпит неудачу, когда он ищет" конец" файла.
Мы работаем над тем же вопросом, что вы получили дальше?
Шон
Ответ 5
В моем случае переключение с wav файла на mp3 разрешило это исключение со статусом = 0x80000000
Ответ 6
В моем случае проблема была из-за beasy sdcard, когда устройство было установлено как exteranl-хранилище на ПК, поэтому проверяя, доступен ли файл, решена проблема. Возможно, это помогает кому-то
Ответ 7
Если вы нацеливаетесь на Marshmallow или выше, убедитесь, что вы правильно запросили разрешение Manifest.permission.WRITE_EXTERNAL_STORAGE
. Я пробовал много разных решений, в том числе другую библиотеку, альтернативу MediaMetadataRetriever
, но оказалось, что один из моих кодов кода не запрашивал правильное разрешение.
Ответ 8
Я столкнулся с такой же проблемой при загрузке видео из файла расширения obb. я исправил его, заменив:
mPlayer.setDataSource(fd);
с:
mPlayer.setDataSource(fis.getFileDescriptor(),fis.getStartOffset(),fis.getLength());