Исключение при вызове метода setDataSource (FileDescriptor) (ошибка: состояние = 0x80000000) - PullRequest
30 голосов
/ 25 января 2011

Я занимаюсь разработкой приложения для потоковой передачи видео и застреваю при вызове setDataSource с помощью FileDescriptor.Я хочу, чтобы мое приложение воспроизводило видео во время его загрузки, поэтому, как только я получу минимальное количество байтов, я перенесу эти байты в другой файл, чтобы его можно было воспроизвести в другом файле, пока он загружается в исходном файле.

Итак, я проверяю, могу ли я запускать медиа-пакет для каждого пакета следующим образом:

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).

Я действительно потерян здесь, любая помощь будет очень признательна

Ответы [ 8 ]

38 голосов
/ 16 апреля 2013

Не забыл разрешения

<uses-permission android:name="android.permission.INTERNET" /> 
22 голосов
/ 06 февраля 2011

Хорошо, я пришел к выводу, что такие ошибки, как:

Подготовка не удалась .: статус = 0x1 (при вызове prepare ())

и

setDataSourceFD не удалось .: статус = 0x80000000 (при вызове setDataSourceFD ())

имеет отношение к формату файла и, вероятно, означает, что файл неполный, поврежден или что-то в этом роде ...

Поскольку у меня есть сообщение в этой ссылке, я нашел конкретное видео, которое отлично работает при потоковой передаче (хотя я использую setDataSource, а не setDataSourceFD), но оно не будет работать с большинством видео.

1 голос
/ 22 июня 2015

с той же ошибкой и после прочтения приведенного выше ответа о формате файла я отказался от попытки установить DataSource с моим файлом .mov и вместо этого создал видео с моей камерой Android Telefon Camera, которое дало мне файл .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));
1 голос
/ 05 июля 2012

Из того, что я прочитал, у определенных форматов видеофайлов есть "заголовок" информации о КОНЦЕ файла.Таким образом, ваш FD должен поддерживать функцию поиска, чтобы получить «заголовок» из конца файла.Я подозреваю, что ваш входной файл в медиаплеер не работает, когда он ищет «конец» файла.

Мы работаем над теми же проблемами, вы получили еще?

0 голосов
/ 30 января 2018

Я столкнулся с той же проблемой при загрузке видео из файла расширения obb. я исправил это, заменив:

mPlayer.setDataSource(fd); 

с:

mPlayer.setDataSource(fis.getFileDescriptor(),fis.getStartOffset(),fis.getLength());
0 голосов
/ 14 июня 2017

Если вы нацелены на Зефир или выше, убедитесь, что вы правильно запросили разрешение Manifest.permission.WRITE_EXTERNAL_STORAGE.Я пробовал много разных решений, в том числе другую библиотеку, альтернативную MediaMetadataRetriever, но оказалось, что один из моих путей кода не запрашивал надлежащего разрешения.

0 голосов
/ 28 февраля 2014

В моем случае проблема была из-за неудобной SD-карты, когда устройство было смонтировано как расширенное хранилище на ПК, поэтому проверка наличия файла позволила решить проблему. Может, кому-то это поможет

0 голосов
/ 16 февраля 2013

В моем случае переход с wav-файла на mp3 разрешил это исключение со статусом = 0x80000000

...