2010-05-09 4 views
13

J'ai une application qui va enregistrer et lire des fichiers audio. Certains fichiers audio sont téléchargés à l'aide de simples téléchargements HTTP standard à l'aide de httpclient. Cela a fonctionné comme un charme pendant longtemps. Maintenant, tout à coup, je ne peux pas lire les fichiers que je télécharge. Il échoue avec cette pile. Je stocke les fichiers sur la carte SD et je rencontre le problème à la fois sur un combiné et un périphérique USB connecté.Android Mediaplayer: problème de setDataSource pour le fichier multimédia téléchargé

J'ai vérifié que le fichier téléchargé est cool sur le serveur, et je peux le lire sans aucun problème.

Ce sont les extraits de code que j'utilise (je sais que recordingFile est un chemin valide pour le fichier).

// inside the activity class 
    private void playRecording() throws IOException{ 
     File recordingFile = new File(recordingFileName); 
     FileInputStream recordingInputStream = new FileInputStream(recordingFile); 
     audioMediaPlayer.playAudio(recordingInputStream); 
    } 

Voici le code du lecteur multimédia:

// inside my media player class which handles the recordings 
    public void playAudio(FileInputStream audioInputStream) throws IOException { 
     mediaPlayer.reset(); 
     mediaPlayer.setDataSource(audioInputStream.getFD()); 
     mediaPlayer.prepare(); 
     mediaPlayer.start(); 
} 

est ici l'exception:

E/MediaPlayerService( 555): offset error 
E/MediaPlayer( 786): Unable to to create media player 
W/System.err( 786): java.io.IOException: setDataSourceFD failed.: status=0x80000000 
W/System.err( 786): at android.media.MediaPlayer.setDataSource(Native Method) 
W/System.err( 786): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:632) 
W/System.err( 786): at net.xxx.xxx.AudioMediaPlayer.playAudio(AudioMediaPlayer.java:69) 
W/System.err( 786): at net.xxx.xxx.Downloads.playRecording(Downloads.java:299) 
W/System.err( 786): at net.xxx.xxx.Downloads.access$0(Downloads.java:294) 
W/System.err( 786): at net.xxx.xxx.Downloads$1.onClick(Downloads.java:135) 

J'ai essayé chercher une réponse de l'erreur de décalage, mais pas vraiment clair que cela problème pourrait être.

PS je télécharger le fichier avec ce code:

public FileOutputStream executeHttpGet(FileOutputStream fileOutputStream) throws ClientProtocolException, IOException{ 
     try {  
      // Execute HTTP Post Request 
      httpResponse = httpClient.execute(httpPost, localContext); 
      int status = httpResponse.getStatusLine().getStatusCode(); 

      // we assume that the response body contains the error message 
      if (status != HttpStatus.SC_OK) { 
       ByteArrayOutputStream ostream = new ByteArrayOutputStream(); 
       httpResponse.getEntity().writeTo(ostream); 
       fileOutputStream = null; 
      } else { 
       InputStream content = httpResponse.getEntity().getContent(); 

       byte[] buffer = new byte[1024]; 
       int len = 0; 
       while ((len = content.read(buffer)) > 0) { 
        fileOutputStream.write(buffer,0, len); 
       } 
       fileOutputStream.close(); 
       content.close(); // this will also close the connection 
      } 

     } catch (ClientProtocolException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
      fileOutputStream = null; 
     } catch (IOException e2) { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
      fileOutputStream = null; 
     } 
     return fileOutputStream; 
    } 

Répondre

3

Je l'ai résolu seul. Comme je l'ai mis mon commentaire ci-dessus la solution était la suivante:

Lorsque j'ai refacturé une partie du code, j'ai fait une faute de frappe sur un code de hachage que j'utilise pour autoriser les téléchargements et non. Malheureusement, je n'avais pas la bonne capture lorsque j'ai téléchargé le fichier, forçant le fichier à être vide. Fondamentalement, j'envoie un mauvais en-tête de demande si vous essayez de récupérer un fichier sans un code d'activation approprié.

Le coupable était ici:

 if (status != HttpStatus.SC_OK) { 
      ByteArrayOutputStream ostream = new ByteArrayOutputStream(); 
      httpResponse.getEntity().writeTo(ostream); 
      fileOutputStream = null; 
     } else { 
      InputStream content = httpResponse.getEntity().getContent(); 

      byte[] buffer = new byte[1024]; 
      int len = 0; 
      while ((len = content.read(buffer)) > 0) { 
       fileOutputStream.write(buffer,0, len); 
      } 
      fileOutputStream.close(); 
      content.close(); // this will also close the connection 
    } 

Pour les cas où le code d'état est revenue un aussi mauvais (à savoir mauvaise tête de demande d'accès bloqués). Ce qui m'a manqué était de capturer le cas d'un pointeur nul là-bas et cela a provoqué une mise à jour d'une entrée SQLite en affirmant à l'application que le téléchargement a réussi mais que ce n'était pas le cas.

Leçon apprise: Toujours mettre les vérifications nuls pour ces cas, même pour les prototypes. :-)

1

Tout d'abord, assurez-vous que votre appareil n'est pas monté. Soit Android ou le PC hôte peut accéder à la carte SD, mais pas les deux simultanément. En second lieu, il n'est pas clair pourquoi vous utilisez un et getFD(). Il suffit de passer le chemin d'accès au fichier sur la carte SD au MediaPlayer (par exemple, new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")) et de laisser le lecteur ouvrir le fichier.

+0

Merci pour la réponse. Pourtant, j'ai trouvé le problème, qui n'était pas lié ne vérifiant pas un pointeur nul pour le fileOutputStream après l'appel. J'ai un serveur web qui synchronise différentes listes de lecture. Quand j'ai refacturé une partie du code j'ai fait une faute de frappe sur un code de hachage que j'utilise pour autoriser les téléchargements et non. Malheureusement, je n'avais pas la bonne capture lorsque j'ai téléchargé le fichier, forçant le fichier à être vide. Fondamentalement, j'envoie un mauvais en-tête de demande si vous essayez de récupérer un fichier sans un code d'activation approprié. Il est maintenant résolu et fonctionne bien.:-) – Erik

+0

J'utilise getFD pour m'assurer que je peux ouvrir des fichiers et ne pas avoir à me soucier des permissions. J'ai trouvé cela pour être "plus sûr" lorsque vous travaillez avec des fichiers sur la carte SD. – Erik

+0

Sur certains appareils (vraiment!), Le mediaplayer (qui vit sur un processus séparé) ne peut pas accéder aux fichiers privés de l'application. J'ai essayé de lire un fichier MIDI téléchargé dans le cache interne de l'application. Et le mediaplayer émet "(Permission denied)" au logcat. – yuku

Questions connexes