2010-05-09 23 views
13

Tengo una aplicación que grabará y reproducirá archivos de audio. Algunos de los archivos de audio se descargan usando descargas HTTP estándar simples usando httpclient. Funcionó como un encanto por mucho tiempo. Ahora, de repente, no puedo reproducir los archivos que descargo. Falla con esta pila Guardo los archivos en la tarjeta SD y experimento el problema tanto en un teléfono como en un dispositivo conectado por USB.Reproductor de Android: problema de setDataSource para el archivo multimedia descargado

He comprobado que el archivo descargado es genial en el servidor, y puedo jugarlo sin problemas.

Estos son los fragmentos de código que uso (sé que recordingFile es una ruta válida para el archivo).

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

Este es el código del reproductor multimedia:

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

Aquí es la excepción:

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) 

he intentado buscando alguna respuesta del error de desplazamiento, pero no realmente claro lo que esto problema podría ser.

PD descargar el archivo con el código:

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

Respuesta

3

Lo resolví solo. Como dije antes, la solución fue esta:

Cuando refactoreé parte del código hice un error tipográfico en un código hash que uso para permitir descargas y no. Lamentablemente no tuve la captura adecuada cuando descargué el archivo forzando que el archivo esté vacío. Básicamente, envío un encabezado de solicitud incorrecta si intentas recuperar un archivo sin un código de activación adecuado.

El culpable era aquí:

 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 
    } 

Para los casos en que el código de estado volvimos a unas tan malo (es decir, mala encabezado de la solicitud de accesos bloqueados). Lo que me perdí fue capturar el caso de un puntero nulo allí y eso causó que se actualizara una entrada de SQLite al reclamar a la aplicación que la descarga había sido exitosa pero aún no lo era.

Lección aprendida: Siempre ponga las comprobaciones nulas para estos casos, incluso para prototipos. :-)

1

En primer lugar, asegúrese de que el dispositivo no está montado. O Android o la PC host pueden acceder a la tarjeta SD, pero no a ambas simultáneamente.

En segundo lugar, no está claro por qué está utilizando un FileInputStream y getFD(). Simplemente pase la ruta al archivo en la tarjeta SD al MediaPlayer (por ejemplo, new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")) y deje que el reproductor abra el archivo.

+0

Gracias por la respuesta. Sin embargo, encontré el problema, que no estaba relacionado, no buscando un puntero nulo para el archivoOutputStream después de la llamada. Tengo un servidor web que mantiene listas de reproducción diferentes sincronizadas. Cuando refactore una parte del código hice un error tipográfico en un código hash que uso para permitir descargas y no. Lamentablemente no tuve la captura adecuada cuando descargué el archivo forzando que el archivo esté vacío. Básicamente, envío un encabezado de solicitud incorrecta si intentas recuperar un archivo sin un código de activación adecuado. Ahora está resuelto y funciona bien.:-) – Erik

+0

Uso el archivo getFD para asegurarme de poder abrir archivos y no tener que preocuparme por los permisos. He encontrado que esto es "más seguro" cuando trabajo con archivos en la tarjeta SD. – Erik

+0

En algunos dispositivos (¡en serio!) El reproductor de medios (que vive en un proceso separado) no puede acceder a los archivos privados de la aplicación. Traté de reproducir un archivo MIDI descargado a la caché interna de la aplicación. Y el reproductor de medios emite "(Permiso denegado)" al logcat. – yuku

Cuestiones relacionadas