2009-10-30 4 views
19

Wie ich es verstehe, wird Android nur Audio im AAC-Format abspielen, wenn es als MPEG-4 oder 3GPP codiert ist.Streaming von AAC-Audio mit Android

Ich kann AAC Audio als M4A codiert, wenn es lokal in der App ist, aber es schlägt fehl, wenn Sie es von einem Server erhalten.

Folgendes funktioniert, da die m4a-Datei lokal im res/row-Verzeichnis gespeichert ist.

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

Folgendes funktioniert nicht. (Aber tut mit MP3's).

Kann irgendjemand etwas Licht darüber werfen, warum es fehlschlägt, wenn die m4a Audiodatei nicht lokal ist?

Hier ist (einige) den Fehler ...

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

Ich bin Targeting SDK 1.6.

+0

Sie verwirren die Kodierung mit Dateiformaten. AAC ist ein Audiocodierungsformat. M4A ist ein Dateityp oder ein Paket, der die AAC-Daten umgibt. 3GPP ist ähnlich, kann aber auch andere Arten von codiertem Audio enthalten. Siehe http://developer.android.com/guide/appendix/media-formats.html und hier http://en.wikipedia.org/wiki/M4a. – greg7gkb

+0

Stimmt, ich hätte 3GPP und M4A als "Container" für AAC-Audio beschreiben sollen. Aus der Spitze meines Kopfes denke ich * M4A kann nur für statische Dateien verwendet werden, und 3GPP kann nur mit RTSP statt HTTP streamen? Dies würde Probleme beim HTTP-Streaming verursachen. Korrigieren Sie mich, wenn ich falsch liege ... – bdls

Antwort

0

Dies ist ein wilder Schuss im Dunkeln, aber ich habe ein ähnliches Verhalten mit dem Flash Player gesehen, wo es den Dateinamen ignoriert und nur auf den vom Server gesendeten MIME-Typ angewiesen ist. Irgendeine Idee, welche Header von example.com gesendet werden? Vielleicht möchten Sie versuchen, Ihre blah.m4a in eine Seite einzufügen, die die Header festlegen und dann die Binärdaten streamen kann. Geben Sie diese Typen einen Schuss und die Gemeinde würde es begrüßen, eine Bestätigung dessen, was funktioniert:

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

+0

Ein guter Vorschlag - danke. Leider hatte ich kein Glück, eine Reihe möglicher Inhaltstypen auszuprobieren. Als Referenz habe ich diejenigen aufgelistet, die unten nicht funktioniert haben. Es ist immer noch möglich, dass es etwas mit HTTP-Headern zu tun hat - oder so etwas - es könnte sein, dass es sehr wählerisch ist, was es essen kann. 'Audio/M4A Audio/AAC Audio/AACP Audio/X-AAC Audio/Mpeg Audio/MP4A Audio/MP4A-LATM Audio/MP4' – bdls

+1

Ich habe definitiv ein Problem mit diesem Problem. Für unsere Streaming-Zwecke würde der MediaPlayer die Streaming-Datei nur abspielen, wenn der Http-Header content-type korrekt eingestellt wurde. Interessanterweise wurde die Inhaltslänge nicht benötigt. – greg7gkb

5

Diese Arbeit -around können Sie M4A-Dateien aus dem Netz (und AAC-Dateien in anderen Containern wie MP4 & 3GP) spielen. Es lädt einfach die Datei herunter und spielt aus dem 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

Gute Idee, aber das erfordert natürlich, dass die gesamte Datei zuerst heruntergeladen wird, bevor sie abgespielt werden kann. Kann in einigen Situationen nützlich sein, aber offensichtlich nicht als Streaming-Lösung geeignet. – greg7gkb

+0

Das stimmt, obwohl dieser Code darauf aufbauen kann, eine Streaming-Lösung zu erstellen, die eine lokale Datei oder Dateien als provisorischen Ringpuffer verwendet. Es ist schade, dass der MediaPlayer nicht von einem InputStream empfangen werden kann oder Sie in der Lage sind, einen Ringpuffer auf die übliche Weise zu erstellen. – bdls

-2

try -

1) MP.prepareAsync()

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

0

Ich schrieb einen Smal Blog auf einer Cloud-basierte Lösung, die ich für einen Musik-Player verwenden, die ich entwickle. Es basiert auf dem jungen Android Cloud Services (ACS) -Projekt, das noch nicht verfügbar ist, aber dennoch zeigt es eine mögliche Lösung mit cloud-basierter Transcodierung zum Streamen von Mediendateien. Werfen Sie einen Blick: http://positivelydisruptive.blogspot.com/2010/08/streaming-m4a-files-using-android-cloud.html

Joel

+0

Hallo Joel. Es ist eine mögliche Option, aber es entfernt die Vorteile von AAC gegenüber anderen Formaten (höhere wahrgenommene Qualität bei einer niedrigeren Bitrate), da Sie am Ende nur MP3 streamen. – bdls

2

Es gibt eine Freeware Advanced Audio (AAC) Decoder for Android ist. Sie können dies für Hilfe und Anleitung verwenden oder Multiplayer-Klasse verwenden, um AAC-Audio wiederzugeben. Es gibt eine Beispielanwendung und die Bibliothek darin, Ihnen zu helfen

Hoffnung verstehen

hilft
+0

Es steht geschrieben "BITTE BEACHTEN SIE, dass die Verwendung dieser Software die Zahlung von Patentgebühren erfordern kann. Sie müssen dieses Problem berücksichtigen, bevor Sie damit beginnen, abgeleitete Werke zu bauen. Wir garantieren oder entschädigen Sie in keiner Weise für Patentrechte! SOFORT VERANTWORTLICH FÜR IHRE EIGENEN MASSNAHMEN! Weitere Informationen zu den AAC-Patenten finden Sie unter http://www.vialicensing.com/licensing/aac-fees.aspx " => nicht sicher, ob es eine gute Idee ist Benutze diese Bibliothek! –

3

Es ist eine der open source OpenMXPlayer, die zeigt, wie Audio-Handhabung sowohl für lokale Dateien oder Online/Streaming-Quellen. Es unterstützt nicht nur AAC, sondern auch die anderen gängigen Formate.

Die Idee dahinter ist die Verwendung der MEdiaCodec API, die in Android 4.1 eingeführt wurde.

Hoffen, das dies ein guter Ausgangspunkt für alle, die eine schnelle und problemlose Audio-Player-Implementierung benötigen.

1

Ich habe es auch versucht, aber ich konnte die Lösung nicht finden!

Bei der letzten Google I/O sah ich etwas, das mir sehr geholfen hat. Es erweitert sich vom MediaPlayer und verbessert viele Dinge! Schau mal.

EXOPLAYER KÖNNEN SIE helfen, eine Menge

Überprüfen dieser Teil des Beispiels:

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- Ich kann alles von Streamings (Video und Audio) spielen!

LASSEN SIE MICH, WENN SIE HILFE BENÖTIGEN, UM ES ZU UMSETZEN! :)