web-dev-qa-db-fra.com

Exception lors de l'appel de la méthode setDataSource (FileDescriptor) (échec: status = 0x80000000)

Je développe une application de diffusion vidéo en continu et je reste bloquée lorsque j'appelle setDataSource avec un FileDescriptor . Je veux que mon application lise la vidéo pendant son téléchargement, de déplacez ces octets vers un autre fichier afin de pouvoir le lire dans un autre fichier pendant son téléchargement dans le fichier d'origine.

Donc, je vérifie si je peux démarrer le média palyer chaque paquet comme ceci:

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();
                }
}

Voici le code de la méthode 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;
}

Je déplace le fichier avec le code suivant:

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());
        }
    }
}

Et je crée enfin l'objet MediaPlayer ici:

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;
    }

C’est l’exception que je reçois:

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)

Je suis resté coincé toute la matinée ici et je ne trouve aucune information sur cette erreur. Certaines personnes m'ont dit d'utiliser le chemin du fichier, mais je reçois l'autre exception dont je parle dans les commentaires (juste au-dessus de la création FileInputStream).

Je suis vraiment perdu ici, toute aide serait très appréciée

29
Pedriyoo

Ok, je suis arrivé à la conclusion que des erreurs comme:

La préparation a échoué .: status = 0x1 (lors de l'appel de prepare ())

et

setDataSourceFD a échoué .: status = 0x80000000 (lors de l'appel de setDataSourceFD ())

avoir avec le format de fichier et probablement signifier que le fichier est incomplet, corrompu ou quelque chose comme ça ...

Comme j'ai posté dans this link, j'ai trouvé une vidéo spécifique qui fonctionne correctement tout en la diffusant (bien que j'utilise setDataSource, pas setDataSourceFD), mais cela ne fonctionnera pas avec la plupart des vidéos.

22
Pedriyoo

N'oubliez pas la permission

<uses-permission Android:name="Android.permission.INTERNET" /> 
38
Crossle Song

D'après ce que j'ai lu, certains formats de fichiers vidéo ont leur "en-tête" des informations sur la FIN du fichier. Ainsi, votre FD doit être une fonction de recherche de support pour obtenir "l'en-tête" à la fin du fichier. Je suspecte que votre fichier d’entrée sur le lecteur multimédia échoue s’il cherche à atteindre la "fin" du fichier.

Nous travaillons sur les mêmes problèmes, êtes-vous allés plus loin?

Sean 

1
Sean

ayant la même erreur et ayant lu la réponse ci-dessus sur le format de fichier, j’ai abandonné l’essai de setDataSource avec mon fichier .mov et créé à la place une vidéo avec mon appareil photo Android Telefon qui m’a donné un fichier .mp4 le répertoire Pictures /. Cela a fonctionné - j'ai créé setDataSource sans erreur. J'espère que cela est utile à quelqu'un.

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
Lawn

Dans mon cas, le passage de fichier wav à mp3 a résolu cette exception avec status = 0x80000000

0
Hemant

Si vous ciblez Marshmallow ou une version supérieure, assurez-vous d'avoir demandé l'autorisation Manifest.permission.WRITE_EXTERNAL_STORAGE correctement. J'ai essayé de nombreuses solutions différentes, y compris une autre bibliothèque alternative à MediaMetadataRetriever, mais il est apparu qu'un de mes chemins de code ne demandait pas l'autorisation appropriée.

0
hansonchris

Je faisais face au même problème lors du chargement de la vidéo à partir du fichier d’extension obb . Je l’ai corrigé en remplaçant:

mPlayer.setDataSource(fd); 

avec:

mPlayer.setDataSource(fis.getFileDescriptor(),fis.getStartOffset(),fis.getLength());
0
Usama Saeed US

Dans mon cas, le problème était dû à une carte SD occupée lorsque le périphérique est monté en tant que stockage externe sur un ordinateur. La vérification du fichier disponible a donc résolu le problème. Peut-être que ça aide quelqu'un

0
vir us