2009-10-30 6 views
19

Si je comprends bien, Android ne lira le format audio AAC que s'il est encodé en MPEG-4 ou 3GPP.Diffusion audio AAC avec Android

Je peux lire des fichiers audio AAC encodés en tant que M4A lorsqu'il s'agit d'une application locale, mais cela échoue lorsque je l'obtiens d'un serveur. Les travaux suivants, car le fichier m4a est détenu localement dans le répertoire res/raw.

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

Ce qui suit ne fonctionne pas. (Mais fait avec MP3). Quelqu'un peut-il faire la lumière sur pourquoi il échoue lorsque le fichier audio m4a n'est pas local?

est ici (en partie) l'erreur ...

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) 
... 

je cible SDK 1.6.

+0

Vous confondez l'encodage avec les formats de fichiers. AAC est un format d'encodage audio. M4A est un type de fichier, ou package, qui se trouve autour des données AAC. 3GPP est similaire mais peut contenir d'autres types d'audio codés. Voir ici http://developer.android.com/guide/appendix/media-formats.html et ici http://en.wikipedia.org/wiki/M4a. – greg7gkb

+0

Certes, j'aurais dû décrire 3GPP et M4A comme des «conteneurs» pour l'audio AAC. Je pense que * M4A ne peut être utilisé que pour les fichiers statiques, et que le 3GPP ne peut diffuser qu'avec RTSP plutôt que HTTP? Cela causerait des problèmes pour le streaming HTTP. Corrigez-moi si je me trompe ... – bdls

Répondre

0

Ceci est un tir sauvage dans l'obscurité, mais j'ai vu un comportement similaire avec le lecteur flash où il ignore réellement le nom de fichier et ne dépend que du type MIME envoyé par le serveur. Une idée de ce que les en-têtes sont envoyés à partir de exemple.com? Vous pouvez essayer d'envelopper votre blah.m4a dans une page qui peut définir les en-têtes, puis diffuser les données binaires. Donner à ces types un coup de feu et la communauté apprécierait une confirmation de ce qui fonctionne:

audio/mpeg audio/mp4a audio/mp4a-LATM audio/aac audio/x-aac

+0

Une bonne suggestion - merci. Malheureusement, je n'ai pas eu de chance d'essayer un éventail de types de contenu possibles. Pour référence, j'ai énuméré ceux qui n'ont pas travaillé ci-dessous. Il est toujours possible que ce soit quelque chose à voir avec les en-têtes HTTP - ou quelque chose comme ça - c'est peut-être parce que c'est très difficile de savoir ce qu'on peut en faire. 'audio/m4a audio/aac audio/aacp audio/x-aac audio/mpeg audio/mp4a audio/mp4a-latm audio/mp4' – bdls

+1

J'ai vraiment rencontré un problème avec cela. Pour nos besoins de streaming, le MediaPlayer ne lirait pas le fichier de streaming à moins que le type de contenu de l'en-tête Http ait été correctement défini. Fait intéressant, la longueur du contenu n'était pas nécessaire. – greg7gkb

5

Ce travail -autour vous permet de lire des fichiers M4A à partir du net (et des fichiers AAC dans d'autres conteneurs tels que MP4 & 3GP). Il télécharge simplement le fichier et joue à partir du cache.

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

Bonne idée mais bien sûr cela nécessite que le fichier entier soit téléchargé avant de pouvoir être lu. Peut être utile dans certaines situations mais ne convient évidemment pas comme solution de streaming. – greg7gkb

+0

C'est vrai, bien que ce code puisse être construit pour créer une solution de streaming en utilisant un fichier local ou des fichiers comme tampon circulaire de fortune. Il est regrettable que MediaPlayer ne puisse pas recevoir d'un InputStream ou que vous seriez capable de faire un tampon circulaire de la manière standard. – bdls

-2

essayer -

1) MP.prepareAsync()

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

0

J'ai écrit un blog Smal sur une solution basée sur le cloud J'utilise un lecteur de musique que je développe. Il est basé sur le jeune projet Android Cloud Services (ACS), qui n'est pas encore disponible, mais il montre néanmoins une solution potentielle utilisant le transcodage basé sur le cloud pour diffuser n'importe quel fichier multimédia. Jetez un coup d'oeil: http://positivelydisruptive.blogspot.com/2010/08/streaming-m4a-files-using-android-cloud.html

Joel

+0

Salut Joel. C'est une option possible, mais elle supprime les avantages d'AAC par rapport à d'autres formats (qualité perçue supérieure à un débit binaire plus faible) car vous ne faites que diffuser des fichiers MP3 à la fin. – bdls

2

Il y a un Freeware Advanced Audio (AAC) Decoder for Android. Vous pouvez l'utiliser pour obtenir de l'aide et des conseils ou utiliser la classe multijoueur pour lire l'audio aac. Il y a un exemple d'application et bibliothèque pour vous aider à comprendre

Hope this helps

+0

Il est écrit «VEUILLEZ NOTER que l'utilisation de ce logiciel peut exiger le paiement de redevances de brevets.Vous devez considérer cette question avant de commencer à construire des œuvres dérivées.Nous ne garantissons pas ou vous indemniser en aucune façon pour les royalties de brevets! RESPONSABLE dE VOS ACTIONS EXCLUSIVEMENT PROPRES! pour plus d'informations sur les brevets AAC, s'il vous plaît visitez http://www.vialicensing.com/licensing/aac-fees.aspx » => pas sûr que ce soit une bonne idée de utilisez cette bibliothèque! –

3

Il y a un qui illustre le open source OpenMXPlayer comment gérer audio à la fois pour les fichiers locaux ou en ligne/sources de streaming. Il prend en charge non seulement AAC, mais aussi les autres formats populaires.

L'idée sous-jacente est d'utiliser l'API MEdiaCodec, introduite dans Android 4.1.Espérons que cela constitue un bon point de départ, pour toute personne ayant besoin d'une implémentation de lecteur audio rapide et sans tracas.

1

Je l'ai essayé aussi mais je n'ai pas pu trouver la solution! Lors de la dernière E/S de Google, j'ai vu quelque chose qui m'a beaucoup aidé. Il s'étend de MediaPlayer et améliore beaucoup de choses! Regarde.

EXOPLAYER PEUT VOUS AIDER BEAUCOUP

Cocher cette partie de l'exemple:

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- je peux jouer quelque chose de ruissellements (vidéo et audio)!

FAITES-MOI SI VOUS AVEZ BESOIN D'AIDE POUR LA METTRE EN OEUVRE! :)