MediaPlayer setDataSource, mejor utilizar path o FileDescriptor?

Digamos que tengo un camino completo a un archivo. ¿Cuál es el mejor enfoque para cargar ese archivo en un MediaPlayer?

String filePath = "somepath/somefile.mp3"; mediaPlayer.setDataSource(filePath); 

O

 String filePath = "somepath/somefile.mp3"; File file = new File(filePath); FileInputStream inputStream = new FileInputStream(file); mediaPlayer.setDataSource(inputStream.getFD()); inputStream.close(); 

¿Importa? Simplemente el uso de la ruta parece más fácil, pero ¿hay una razón para hacer el trabajo extra para utilizar un FileDescriptor?

En realidad, resulta que hay una diferencia en ciertas situaciones.

mediaPlayer.setDataSource(String path) fallará cuando llame a mediaPlayer.prepare() , si está intentando cargar un archivo de getApplicationContext().getFilesDir() , dependiendo de cómo se guardó el archivo. Por ejemplo, si escribo un archivo utilizando new RandomAccessFile(filePath, "rw") , el archivo no es realmente legible por mediaplayer si usa mediaPlayer.setDataSource(String path) . El prepare() disparará inmediatamente el error(1, -2147483648) desde el reproductor de medios; Esencialmente un error de permiso de archivo. SDK 9 introdujo file.setReadable (boolean readable, boolean ownerOnly) que presumiblemente le permitiría resolver este problema estableciendo ownerOnly a false … pero eso no le ayudará si necesita soportar SDK antiguos.

SIN EMBARGO, mediaPlayer.setDataSource(FileDescriptor fd) NO tiene este problema y mediaplayer preparará con éxito el mismo archivo exacto sin un problema de permiso.

MediaPlayer.java tiene firmas setDataSource () que aceptan tanto un String (ruta) como un FD. Ambos finalmente entran en el código nativo de C. Aunque uno de estos puede ser ligeramente más eficiente que será insignificante a menos que esté configurando su fuente de datos más de una vez por segundo.

 /** * Sets the data source (file-path or http/rtsp URL) to use. Call this after * reset(), or before any other method (including setDataSource()) that might * throw IllegalStateException in this class. * * @param path the path of the file, or the http/rtsp URL of the stream you want to play * @throws IllegalStateException if it is called * in an order other than the one specified above */ public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException; /** * Sets the data source (FileDescriptor) to use. It is the caller's responsibility * to close the file descriptor. It is safe to do so as soon as this call returns. * Call this after reset(), or before any other method (including setDataSource()) * that might throw IllegalStateException in this class. * * @param fd the FileDescriptor for the file you want to play * @throws IllegalStateException if it is called * in an order other than the one specified above */ public void setDataSource(FileDescriptor fd) throws IOException, IllegalArgumentException, IllegalStateException { // intentionally less than LONG_MAX setDataSource(fd, 0, 0x7ffffffffffffffL); } /** * Sets the data source (FileDescriptor) to use. It is the caller's responsibility * to close the file descriptor. It is safe to do so as soon as this call returns. * Call this after reset(), or before any other method (including setDataSource()) * that might throw IllegalStateException in this class. * * @param fd the FileDescriptor for the file you want to play * @param offset the offset into the file where the data to be played starts, in bytes * @param length the length in bytes of the data to be played * @throws IllegalStateException if it is called * in an order other than the one specified above */ public native void setDataSource(FileDescriptor fd, long offset, long length) throws IOException, IllegalArgumentException, IllegalStateException; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.