2009-10-30 21 views
19

Según tengo entendido, Android solo reproducirá audio en formato AAC si está codificado como MPEG-4 o 3GPP.Transmisión de audio AAC con Android

Puedo reproducir audio AAC codificado como M4A cuando es local para la aplicación, pero falla al obtenerlo de un servidor.

Lo siguiente funciona, ya que el archivo m4a se guarda localmente en el directorio res/raw.

MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*); 
mp.start(); 

Lo siguiente no funciona. (Pero lo hace con MP3).

Uri uri = Uri.parse("http://*example.com*/blah.m4a"); 
MediaPlayer mp = MediaPlayer.create(this, uri); 
mp.start(); 

¿Alguien puede arrojar alguna luz sobre por qué falla cuando el archivo de audio m4a no es local?

Aquí es (parte de) el error ...

ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus 
ERROR/MediaPlayer(769): error (200, -32) 
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete 
DEBUG/MediaPlayer(769): create failed: 
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.prepare(Native Method) 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.create(MediaPlayer.java:530) 
DEBUG/MediaPlayer(769):  at android.media.MediaPlayer.create(MediaPlayer.java:507) 
... 

estoy focalización SDK 1.6.

+0

Estás confundiendo la codificación con formatos de archivo. AAC es un formato de codificación de audio. M4A es un tipo de archivo, o paquete, que se ubica alrededor de los datos de AAC. 3GPP es similar pero puede contener otros tipos de audio codificado. Vea aquí http://developer.android.com/guide/appendix/media-formats.html y aquí http://en.wikipedia.org/wiki/M4a. – greg7gkb

+0

Cierto, debería haber descrito 3GPP y M4A como "contenedores" para audio AAC. En lo alto de mi cabeza, * creo que * M4A solo puede usarse para archivos estáticos, y 3GPP solo puede transmitir usando RTSP en lugar de HTTP. Esto causaría problemas para la transmisión HTTP. Corrígeme si estoy equivocado ... – bdls

Respuesta

0

Este es un tiro desenfrenado en la oscuridad, pero he visto un comportamiento similar con el reproductor flash donde ignora el nombre del archivo y solo se basa en el tipo MIME enviado por el servidor. ¿Alguna idea de qué encabezados se envían desde example.com? Es posible que desee tratar de envolver su blah.m4a en una página que puede establecer los encabezados y luego transmitir los datos binarios. Dar a estos tipos un tiro y la comunidad agradecería una confirmación de lo que funciona:

audio/mpeg de audio/MP4A de audio/MP4A-LATM de audio/AAC de audio/x-aac

+0

Una buena sugerencia, gracias. Desafortunadamente no he tenido suerte probando una variedad de posibles tipos de contenido. Como referencia, he enumerado los que no han funcionado a continuación. Todavía es posible que tenga algo que ver con los encabezados HTTP, o algo así, puede ser que sea muy quisquilloso sobre lo que se puede alimentar. 'audio/m4a audio/aac audio/aacp audio/x-aac audio/audio mpeg/mp4a audio/mp4a-latm audio/mp4' – bdls

+1

Definitivamente tuve un problema con esto. Para nuestros propósitos de transmisión, MediaPlayer no reproduciría el archivo de transmisión a menos que el tipo de contenido del encabezado Http se haya configurado correctamente. Curiosamente, la longitud del contenido no fue requerida sin embargo. – greg7gkb

5

Este trabajo -Ruta le permite reproducir archivos M4A de la red (y archivos AAC en otros contenedores como MP4 & 3GP). Simplemente descarga el archivo y se reproduce desde el caché.

private File mediaFile; 

private void playAudio(String mediaUrl) { 
    try { 
     URLConnection cn = new URL(mediaUrl).openConnection(); 
     InputStream is = cn.getInputStream(); 

     // create file to store audio 
     mediaFile = new File(this.getCacheDir(),"mediafile"); 
     FileOutputStream fos = new FileOutputStream(mediaFile); 
     byte buf[] = new byte[16 * 1024]; 
     Log.i("FileOutputStream", "Download"); 

     // write to file until complete 
     do { 
      int numread = is.read(buf); 
      if (numread <= 0) 
       break; 
      fos.write(buf, 0, numread); 
     } while (true); 
     fos.flush(); 
     fos.close(); 
     Log.i("FileOutputStream", "Saved"); 
     MediaPlayer mp = new MediaPlayer(); 

     // create listener to tidy up after playback complete 
     MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() { 
      public void onCompletion(MediaPlayer mp) { 
       // free up media player 
       mp.release(); 
       Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released"); 
      } 
     }; 
     mp.setOnCompletionListener(listener); 

     FileInputStream fis = new FileInputStream(mediaFile); 
     // set mediaplayer data source to file descriptor of input stream 
     mp.setDataSource(fis.getFD()); 
     mp.prepare(); 
     Log.i("MediaPlayer", "Start Player"); 
     mp.start(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+5

Buena idea, pero por supuesto, esto requiere que todo el archivo se descargue antes de poder reproducirlo. Podría ser útil para algunas situaciones, pero obviamente no es adecuado como una solución de transmisión. – greg7gkb

+0

Eso es cierto, aunque este código se puede construir para crear una solución de transmisión usando un archivo local o archivos como un búfer circular improvisado. Es desafortunado que MediaPlayer no pueda recibir de un InputStream o usted podría hacer un buffer circular de la manera estándar. – bdls

-2

intento -

1) MP.prepareAsync()

2) onPrepared() { mp.start() }

0

me escribió un blog Smal en una solución basada en la nube que utilizo para un reproductor de música que estoy desarrollando. Se basa en el proyecto de Android Cloud Services (ACS), que todavía no está disponible, pero aún así, muestra una posible solución mediante la transcodificación basada en la nube para transmitir cualquier archivo multimedia. Echar un vistazo: http://positivelydisruptive.blogspot.com/2010/08/streaming-m4a-files-using-android-cloud.html

Joel

+0

Hola Joel. Es una opción posible, sin embargo, elimina las ventajas de AAC sobre otros formatos (calidad percibida más alta a una tasa de bits más baja) ya que al final solo estás transmitiendo MP3. – bdls

2

Hay una Freeware Advanced Audio (AAC) Decoder for Android. Puede usar esto para ayuda y orientación o usar la clase de multijugador para reproducir audio aac. Hay una aplicación de ejemplo y una biblioteca en ella para ayudarle a entender

Esperanza esto ayuda

+0

Está escrito "TENGA EN CUENTA que el uso de este software puede requerir el pago de regalías de patentes. Debe tener en cuenta este problema antes de comenzar a construir obras derivadas. ¡No le estamos garantizando ni indemnizando en modo alguno por los royalties de patentes! ¡EXCLUSIVAMENTE RESPONSABLE DE SUS PROPIAS ACCIONES! Para obtener más información sobre las patentes de AAC, visite http://www.vialicensing.com/licensing/aac-fees.aspx " => no estoy seguro de que sea una buena idea usa esta biblioteca! –

3

Hay una open source OpenMXPlayer el que muestra cómo controlar el audio tanto para archivos locales o en línea/fuentes de transmisión. No solo es compatible con AAC, sino también con otros formatos populares.

La idea detrás de esto es utilizar la API MEdiaCodec, presentada en Android 4.1.

Espero que esto ofrezca un buen punto de partida para cualquier persona que necesite una implementación de reproductor de audio rápida y sin problemas.

1

¡Lo intenté también pero no podría encontrar la solución!

En el último Google I/O vi algo que me ayudó mucho. ¡Se extiende desde MediaPlayer y mejora muchas cosas! Echar un vistazo.

EXOPLAYER CAN ayudará mucho

Marque esta parte del ejemplo:

private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; 
private static final int BUFFER_SEGMENT_COUNT = 256; 
... 

// String with the url of the radio you want to play 
String url = getRadioUrl(); 
Uri radioUri = Uri.parse(url); 
// Settings for exoPlayer 
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); 
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo"); 
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent); 
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT); 
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); 
// Prepare ExoPlayer 
exoPlayer.prepare(audioRenderer); 

EXOPLAYER- puedo jugar nada de streamings (vídeo y audio)!

AVISARME SI NECESITA AYUDA PARA IMPLEMENTARLO! :)

Cuestiones relacionadas