Monday, June 28, 2010

Raw AAC Player for Android

This blog (and project) was written for those developers spending hours of googling the internet to answer a simple question:

How to make Android to play raw AAC files (streams) ?

I've spent many hours by it and I want to save other's time to public what I found.

I tried to:


  • invoke MediaPlayer on raw AAC http:// URL (error)

  • invoke MediaPlayer on raw AAC file (error in emulator, OK on HTC Desire)

  • pass a NetSocket FileHandle to MediaPlayer (error)

  • filter the stream using local ServerSocket and:

    • discard HTTP header (error)

    • change content-type to several possibilities like audio/mpeg (error)

    • sync ADTS header (icecast does not do it) (error)

  • split the AAC stream into small file chunks (OK, but not excellent)

  • use 3rd party native library (FAAD2) to decode AAC (OK on HTC Desire, working on emulator - but slow)



Using FAAD2 library works on my HTC Desire phone without problems. I tried 32kbit AAC stream served by www.play.cz (the exact URL you can find in the sources). It failed when trying 128kbit AAC stream served by the same server - but it also failed when using mplayer or when I saved it to a file and tried the internal HTC Desire's AAC player.

On the emulator it works, but it is not smooth (performance problems).
I tried Android 1.5 (cupcake) and Android 2.1 (Eclair) versions - both with the same results (working, but not perfect).

So the result is that playing raw AAC on Android devices (er even on the emulator) is possible, but there are several "buts":

  • although Android contains AAC decoder, you cannot use it / access it natively

  • if you create your own AAC decoder, then as a developer you must obtain a license from the patent holders - and you must pay for it



The sources you can find here:
http://code.google.com/p/aacplayer-android/




Updated 2011-05-05
I've added OpenCORE aacdec library/decoder and rewrote both Java and C parts of the player. Now I am able to play streams smoothly even on the emulator (using no more than 60% of my host CPU)!
You can download the sources and compiled shared libraries from the Downloads section (aacplayer-android-r20.zip).

How to compile it ? Just unzip the archive, edit local.properties, copy sample.ant.properties to .ant.properties (oh, yes in rev20 you must change the name of the property "loglevel" to "jni.loglevel") and run Apache Ant (beginners please consult Android SDK and NDK documentation - you need to have installed Apache Ant and GNU Make - Windows users also Cygwin). Or read the README file :-)




Updated 2011-05-26
I've created a follow-up project "AACDecoder" which uses only OpenCORE aacdec library and allows using the working library in other 3rd party Android projects.

http://code.google.com/p/aacdecoder-android/

Thank you all for your feedback!

78 comments:

  1. Hi Vaclav -- thanks for posting this... Have you tried playing an aac file directly from the SD card?
    I tested on two samsung moments one having android 1.5 (cupcake) and the second having 2.0 (donut) both yield the same "choppy" results using the FAAD2 decoder (the other option doesn't work at all). hmmmm the moment has 1GHZ processor
    shouldn't that be enough to handle a decoder?

    ReplyDelete
  2. Hi, thanks for sharing your insights. Q: when you split the stream into chunks, what container format did you use?
    I read that it should be able to support the ADIF format as well, which is basically just a header in front of the stream, and not in front of every aac frame.

    So perhaps it is possible to put an ADIF header in front of the raw stream and make the player believe it's an ADIF file...?

    Just an idea....

    ReplyDelete
  3. Hello, Vaclav!

    Thank you for this post.
    You wrote "split the AAC stream into small file chunks (OK, but not excellent)".

    Please tell/mail me (silvanovich.michael@gmail.com) how you did it (split AAC stream into small file chunks, and how you played these chunks).

    Thank you.

    ReplyDelete
  4. Hi Vaclav,

    I've been trying to use the aacPlayer project put up in the google code. I must say that it was a big relief to find a working solution :)

    One question, the streams do not appear to play continuously. I assume that the delay is because of the need to decode and play. But is there any strategy to refine this?

    Regards,
    Hari

    ReplyDelete
  5. Hi,

    Thanks for sharing your project.

    I am working on a similar where i should use ffmpeg to encode the audio file into G726 format. Can I use directly your ffmpeg compiled code or should I have to compile once again for Android using Linux. Since I am developing application in windows. Please help me if you have some suggestions for my question.

    Thanks
    KARUMANCHI

    ReplyDelete
  6. Hi,

    I'm new on Android development (I do iPnoe dev).

    Can you please provide an working exaple code with latest build (r14), that would help me a lot.

    Thanks!

    ReplyDelete
  7. Hi all !

    I've added OpenCORE aacdec library/decoder and rewrote both Java and C parts of the player. Now I am able to play streams smoothly even on the emulator (using no more than 60% of my host CPU)!
    You can download the sources and compiled shared libraries from the Downloads section (aacplayer-android-r20.zip).

    How to compile it ? Just unzip the archive, edit local.properties, copy sample.ant.properties to .ant.properties (oh, yes in rev20 you must change the name of the property "loglevel" to "jni.loglevel") and run Apache Ant (beginners please consult Android SDK and NDK documentation - you need to have installed Apache Ant and GNU Make - Windows users also Cygwin).

    Thanks all for feedback !

    Vaclav

    ReplyDelete
  8. Hi KARUMANCHI,

    no, you should compile it yourself, because I restrict the compilation process only to files related to AAC.
    See jni/ffmpeg/Android.mk

    Vaclav

    ReplyDelete
  9. Hi Hari,

    there were three problems there: first - FAAD2/FFmpeg are quite slow (but only on older devices/emulator).

    Second - the original algorithm of decoding was wrong. The input buffer was passed to the decode() function and the ouput buffer was supposed to be filled in - like 1:1. But this did not work unless you were very careful about the sizes of the buffers. Now the decode() function is called only with the output buffer and the decode() function requests (callback to Java) input data on-demand.

    Third - the AudioTrack object was badly initialized. AudioTrack object is able to buffer audio data - just call method write() first and the the method play(). Also the size of the audio buffer should be initialized according to some rules.

    Now the last two problems were solved (Revision 20).

    Generally speaking we have 3 buffers - IN (input), DEC (decoded data), AU (buffer in AudioTrack). I recommend the following:
    1. Set AU to some value to overcome networking problems (e.g. 2 seconds)
    2. Must: DEC < AU, should: 2*DEC < AU (e.g. 0.75 sec)
    3. Should: IN [bytes] = bitrate / 8 * DEC

    I'll try to explain this later as a separate post or on project's Wiki.

    Vaclav

    ReplyDelete
  10. Hi Vaclav,

    Must say its a great work !!

    Are you planning to do something similar for WMA as well? Meaning support the playing out of WMA streams on Android device?

    ReplyDelete
  11. Hi "Mobile",

    thanks.
    Regarding WMA - yes, I just committed initial version into the SVN trunk of (rev23 - see http://code.google.com/p/aacplayer-android/issues/detail?id=3#c4)
    It is not a final version yet. I will continue working on it after getting back from my vacation (end of June).

    Vaclav

    ReplyDelete
  12. Looks great !
    Can you upload .apk file ?
    I have problems installing apache Ant , unable to compile the project

    ReplyDelete
  13. Hi Amit,
    unfortunately I cannot upload APK. As for the AAC decoder one must pay license fees. So I only published the source code / libraries, but not the final audio player.
    Several people were able to compile it, so I hope it would not be a big issue for you.
    Vaclav

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. Hi, can i use
    http://code.google.com/p/aacplayer-android/
    in commercial applications ? (to ask fee for application, to put banner service in it)

    ReplyDelete
  16. Hi Vaclav,

    I just looked at the WMA support and tried using the code. This is awesome, it plays well for 90 % of the streams. However, for 10 %, I observed app crashes. Have also raised this issue at the google code project. Can you please address this

    Thanks in Advance

    ReplyDelete
  17. Hi Alex,

    the project http://code.google.com/p/aacplayer-android/ is licensed under GPL, so you can create commercial apps on top of it, but you need to fullfill the GPL - mainly it means to publish your code as well.

    If you use the second project http://code.google.com/p/aacdecoder-android/ , then you do not need to publish your code (the library is licensed under LGPL).

    Vaclav

    ReplyDelete
  18. Hi Mobile,

    yes, I know - the problem is somewhere inside the libmms library.

    Vaclav

    ReplyDelete
  19. Hi Vaclav,

    Thanks for the reply

    Any recent efforts are you making to address this?

    Thanks

    ReplyDelete
  20. Hi Mobile,

    I am not going to fix it soon. The main reason is that it is located in the libmms - 3rd party library. Also I don't have much time for this project now. Sorry.

    Vaclav

    ReplyDelete
  21. hi Vaclav!
    first of all,deep appreciate for your project,i am newbie of android app develop.after finished to build AACplayer project,i have a question
    how to make a universal player that can be autodectect the format and play the audio. is this possible to do that just use the FFMpeg open source? can you tell me the procedure or guideline.thanks a lot.

    ReplyDelete
  22. Hi firebird,
    unfortunately there exists no simple answer/solution for doing it. You need to port all audio related parts of FFMpeg to Android. Then to connect it with Android's audiotrack for playing. In Android NDK r5 you can use native audiotrack functions, so the whole code could be probably written in pure C/C++.
    I expect a lot of obstacles when porting such a big piece of code. Good luck !
    Vaclav

    ReplyDelete
  23. Hi Vaclav,

    Big thanks for your efforts!

    We've been playing with similar stuff in FFMPEG at https://github.com/mikebevz/AFPlayer - mainly to support HLS.

    Recently I've been investigating the built in OpenCode AAC decoder that all phones are bundled with from the Android system.

    It seems it is actually possible to load the shared libraries on the phone (in /system/lib/), and so also load libomx_aacdec_sharedlibrary.so containing the AAC decoder.

    The a hazzle is that the .so file isnt always callled the same thing.

    SE_XPeria_mini libomx_aacdec_sharedlibrary.so
    HTC_Wildfire libomx_aacdec_sharedlibrary.so

    Samsung_Galaxy_SII libsaaceomxoc.so

    Android4 libstagefright_soft_aacdec.so


    My questions is, did you look into this possibility?

    Regards,
    Jacob Nordfalk

    ReplyDelete
  24. Hi Vaclav,

    My name is Duško, and i'm trying to build Internet radio player, for devices with Froyo as minimal platform. As all of the people here, i'm stuck with aac decoding.
    I'm using your library with OpenCORE (0.5.1 version), and it's working of course. The problem is, when using ACCPlayer CPU is heavy utilized, and application gets unresponsive for any interface action (although it plays radio stream in background). It does not happening with MPEG stream when using MediaPlayer.

    For testing purposes i've created one activity with one button (play/stop) and two methods (play() and stop()). AACPlayer is intialized by following your instructions
    AACPlayer aac=new AACPlayer();
    aac.play(aacStream);

    When presing button to stop streaming ..debug window comes with info " Key dispatching timed out sending to ..." and after few seconds, application gives "Force close / Wait" dialog.

    Is there something that i'am doing wrong, because there is no difference between running app. in emulator or real device (i suppose device performanse is not the reason for this issue).

    Thank you for your work.
    Best regards!

    ReplyDelete
  25. Hi Duško,

    is the same problem hapenning also when using the example application ? On emulator or on device (or both?).

    I suppose that you need to use the "playAsync" method instead "play" method. Maybe this is your problem ?

    Vaclav

    ReplyDelete
  26. Hi Vaclav,

    I just checked your latest OpenCore AAC Libraries and they are awesome.

    The only question I have is. What should I do if I include them in my project. Meaning, I wanted to know about the licensing etc.

    -Hari

    ReplyDelete
    Replies
    1. Hi Hari,

      if you include the libraries as is, then you don't need to do anything. LGPL license allows you to use it as-is. You can use the compiled binaries or recompile the source yourself if you wish. Does not matter if your final application will be free or payed.

      Vaclav

      Delete
    2. Thanks Vaclav :)

      What about the AAC Licensing. Do I have to worry about that?

      Delete
    3. Yes, you should conform to the AAC licenses as I wrote in the README/Project wiki. But I am not a layer, so I cannot tell you what exactly you may and must.
      You should probably ask AAC License holders if you have any doubts.

      V.

      Delete
  27. I deleted my first comment as I've made it a little further :)

    I now have the app opening and running, but when I put in a URL that works (via the command line build of the your aacplayer code) I'm getting the following three lines before getting a socketException


    01-21 16:05:59.859: D/dalvikvm(392): Trying to load lib /data/data/com.XXX/lib/libaacdecoder.so 0x4817af40
    01-21 16:05:59.859: D/dalvikvm(392): Added shared lib /data/data/com.XXX/lib/libaacdecoder.so 0x4817af40
    01-21 16:05:59.859: D/dalvikvm(392): No JNI_OnLoad found in /data/data/com.XXX/lib/libaacdecoder.so 0x4817af40, skipping init

    Any help would be greatly appreciated :-)

    ReplyDelete
  28. OK... I have once again made a newbie mistake. Helps if I actually let the app use the internet :)

    Thanks for this great code. Now I need to figure out the rest of my app :)

    ReplyDelete
  29. Vaclav

    Do you have any idea where to look to start pulling streaming metadata along with the AACP audio?

    ReplyDelete
  30. Hello Vaclav, thank you again for your awesome work on this. I'm no expert in decoders and such so this definitely is a great learning experience for me.

    I do have a question though. I'm studying your aacdecoder-int and was wondering if there's a way to tinker this a bit so it can parse m4a-contained streams. I know your code only plays raw AAC streams with an ADTS header present, but was wondering if its possible to leverage this to play m4a streams as well. Again, I'm no expert on codecs and decoders, but how would I do so on m4a streams? I've been googling to see what how to strip the m4a container programmatically but haven't had much luck .... most searches simply redirects me to aac streams with ADTS header present (unless I'm searching for the wrong keywords)

    If you can provide some pointers that will surely help!

    ReplyDelete
    Replies
    1. Hi,

      unfortunately I don't think it could be as easy as adding few lines of code. In the aacplayer project I added possibility to play also WMA streams, but I had to use the ffmpeg library in deep. So in that case it would not have much in common with this aacdec code.
      But of course it would be possible. The question is if it is really needed - probably standard Android's MediaPlayer should play it, or shouldn't ?

      Vaclav

      Delete
  31. HI -

    I'm also curious about how to pull metadata from a AAC stream.

    Thanks

    Rich

    ReplyDelete
  32. |HI, Vaclav

    It was playAsync trouble..it's a newbie mistake, but now i got a little further and it's out of my knowledge. aacdecoder works great on Froyo platform. I tested it on emulator and on real device, and it's playing perfectly. The trouble is with Gingerbread. This is the stacktrace i'm getting from users with real devices, and dont know what to do (it has been tested on gingerbread inside emulator, and its working).

    Caused by: java.lang.UnsatisfiedLinkError: Couldn't load aacdecoder: findLibrary returned null
    at java.lang.Runtime.loadLibrary(Runtime.java:429)
    at java.lang.System.loadLibrary(System.java:554)
    at com.spoledge.aacdecoder.Decoder.loadLibrary(Decoder.java:167).

    library is included (armeabi and armeabiv7) in libs folder and aacdecoder.jar is imported via build path. I must say, the same version, works on Froyo, but not on Gingerbread.

    In your guide, you said only to import armeabi (only with aacdecoder.so) folder in libs and include jar file. In player example, i've found armeabi (but there are extra files included, besides aacdecoder.so) and armeabiv7 folder without aacdecoder.so. And i must admit, i've tried all variants of importing libraries and Gingerbread wont load them.

    Best regards.

    ReplyDelete
  33. This is one of the nice post.I like your blog features.Try to get more this kind of information.supper.
    Android app developer

    ReplyDelete
  34. Hi Vaclav,

    Another question to you. Does your decoder support aacPlus v1 encoded streams? I have an audio file encoded to aacPlus v1 (64kbps @ 44100 KHz, contained in an ADTS container) and when I tried to play this file to your player/decoder, it is throwing an exception because the decoder is reporting a sampling rate of 96000Hz, even though I've explicitly encoded it at 44100Hz (and other players like VLC and Quicktime are reporting an output sample rate of 44100Hz). I'm trying to determine whether the fault is the transcoder tool that I'm using, but thought I'd ask you in case you know this offhand and can provide a quicker response. I'm also not sure if this is a bug in your decoder or the tool itself. When I encoded the file using AAC codec (NOT aacPlus v1), it works fine.

    Can you help? Would really appreciate that. Thanks.

    JL

    ReplyDelete
    Replies
    1. Hi,

      I'm quite sure AAC+ v1 (SBR) is supported as far as the underlying OpenCORE library supports it. My decoder is only a kind of wrapper on top of it.

      I've found that AAC+ v2 (resp. Parametric Stereo enhacement) was not working even though I've been using the latest OpenCORE code (directly from GIT repos).

      Anyway, the latest OpenCORE code was better (producing better quality sound for some streams) than the one I'm using in this project. The problem is that one must have checked-out all GIT tree for the OpenCORE so it is not so easy to compile it as it is now. And I had no time to put it (including how-to) to the SVN yet.

      Vaclav

      Delete
    2. Hmm, really? I think I was able to play an AACv2 @40kbps stream (on ADTS container) with your encoder just fine. Its the AACv1 that I continue to have issues with. I'm using aacPlusEnc tool for Windows to encode some of my test wav files. I think the decoder is able to parse the ADTS header, but for some reason its receiving a 96KHz sampling rate even though I've encoded the wav at 44.1KHz. If I manually change the sampling rate to 44.1KHz when I instantiate the AudioTrack, the decoder throws an exception during playback.

      What version of OpenCore are you using in your project?

      Thanks again for all your help.

      JL

      Delete
  35. Hi,

    I'm currently using my htc amaze 4g playing AAC files(.m4a, coded with nero aac codec) with the default music player(HTC) and it is good and smooth.....dont see the problem you or others have.

    Does it mean that HTC phones are capable of playing AAC files by default, with the android built in decoder?

    ReplyDelete
  36. Hi Vaclav,

    I just went through the opencore-aacdec site and noticed that it supports configuration options to enable aac+ SBR decoding. This probably is the problem I'm encountering on why I can't stream aac+ v1 streams, but the question is, do you know how to enable this before I invoke ndk-build? The opencore-aacdec source code that came with the site doesn't provide a configure script and I'm not familiar on how to generate one. I tried running 'autoconf' in the opencore directory but it gave me an error.

    This might be beyond the scope of this topic, but if you can help I will greatly appreciate that!

    JL

    ReplyDelete
    Replies
    1. It can be configured by the config.h file which also comes together with my project. The AAC+ options are enabled by default:

      /* SBR decoding */
      #define AAC_PLUS 1

      /* High-Quality SBR */
      #define HQ_SBR 1

      /* Parametric-Stereo decoding */
      #define PARAMETRICSTEREO 1

      I've been preparing a newer version of the decoder using newer version of the opencore library (which I could found only at http://crepedroid.git.sourceforge.net/git/gitweb-index.cgi - it disappeared from the official Android's source pages).
      When using this new version, the quality of some streams is improved a lot (mono->stereo etc.), but I had to disable parametric stereo option, because there was a bug in the opencore.

      I hope I have time to commit my changes soon.

      Vaclav

      Delete
  37. Hi,
    I'm using your aacdecoder and adding shoutcast metadata decoder to it, using this:
    http://www.smackfu.com/stuff/programming/shoutcast.html

    Do you want to integrate the changes maybe? Using git I would do a fork and a pull request but I'm not sure how to do it using svn ;-)

    ReplyDelete
  38. Radek

    I would be interested in testing your modification!

    ReplyDelete
  39. Hi Radek,

    thank you, but meantime I have been developing the same feature as well :)
    When I have time, I'll commit the changes with other improvements.
    I'm not familiar with git, so I don't want to switch to it now.

    Vaclav

    ReplyDelete
  40. I eagerly await the commit :-)

    ReplyDelete
  41. Hello. I get these errors when running app on android.

    05-25 09:20:35.929: W/dalvikvm(437): threadid=1: thread exiting with uncaught exception (group=0x40015560)
    05-25 09:20:35.967: E/AndroidRuntime(437): FATAL EXCEPTION: main
    05-25 09:20:35.967: E/AndroidRuntime(437): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.spoledge.aacplay/com.spoledge.aacplay.AACPlayerActivity}: java.lang.ClassNotFoundException: com.spoledge.aacplay.AACPlayerActivity in loader dalvik.system.PathClassLoader[/data/app/com.spoledge.aacplay-1.apk]
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1569)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.os.Handler.dispatchMessage(Handler.java:99)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.os.Looper.loop(Looper.java:123)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread.main(ActivityThread.java:3683)
    05-25 09:20:35.967: E/AndroidRuntime(437): at java.lang.reflect.Method.invokeNative(Native Method)
    05-25 09:20:35.967: E/AndroidRuntime(437): at java.lang.reflect.Method.invoke(Method.java:507)
    05-25 09:20:35.967: E/AndroidRuntime(437): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    05-25 09:20:35.967: E/AndroidRuntime(437): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    05-25 09:20:35.967: E/AndroidRuntime(437): at dalvik.system.NativeStart.main(Native Method)
    05-25 09:20:35.967: E/AndroidRuntime(437): Caused by: java.lang.ClassNotFoundException: com.spoledge.aacplay.AACPlayerActivity in loader dalvik.system.PathClassLoader[/data/app/com.spoledge.aacplay-1.apk]
    05-25 09:20:35.967: E/AndroidRuntime(437): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
    05-25 09:20:35.967: E/AndroidRuntime(437): at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
    05-25 09:20:35.967: E/AndroidRuntime(437): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
    05-25 09:20:35.967: E/AndroidRuntime(437): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1561)
    05-25 09:20:35.967: E/AndroidRuntime(437): ... 11 more


    Can you pls help me with this? I'm trying it for a school project, and i'm kind of new to this. Thanks!

    ReplyDelete
    Replies
    1. It seems that the JAR library is not included in your APK.
      Put it to the libs/ directory.
      Vaclav

      Delete
  42. There are no other way to get the current song title?
    I tried http://www.smackfu.com/stuff/programming/shoutcast.html
    but it does not work on slow connections... so...

    ReplyDelete
  43. Just wondering iwhen you might be able to update with the metadata commit? Thanks for the great code!

    ReplyDelete
    Replies
    1. Hi,

      in trunk it is since May 25. Today I just tagged version 0.6 and uploaded libs and sources to the project's download tab.
      Vaclav

      Delete
    2. Thanks! Works like a charm. Now I just need parse our our now playing... since it's not standard (I've had to do this for every platform for 3 years... getting good at it! :)

      Delete
  44. Hi Vaclav,

    Can i stream .m4a Urls like http://a2.mzstatic.com/us/r1000/044/Music/e9/40/ec/mzm.evyxvimp.aac.p.m4a using this library. Now i can stream AAC links like http://http.yourmuze.com:8000/play/paradise/l.aac. But using .m4a urls ceate an error java.io.FileNotFoundException: http://a2.mzstatic.com/us/r1000/044/Music/e9/40/ec/mzm.evyxvimp.aac.p.m4a. Your help will be appreciated. Thank you :)

    ReplyDelete
    Replies
    1. Hi Ajmal,

      m4a / mp4 is an audio stream encapsulated in an MPEG container. So it is not a raw AAC stream and therefore it cannot be played by our player. I recommend to use standard Android's MediaPlayer class for playing.

      Vaclav

      Delete
  45. Morning Vaclav. Just noticed .6.1 and wanted to try it out. It built fine, but when I am trying to run it on my device I'm seeing this thrown. Can you point me in the right direction to find a fix.


    07-30 11:04:56.409: E/AndroidRuntime(27849): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.spoledge.aacplay/com.spoledge.aacplay.AACPlayerActivity}: java.lang.ClassNotFoundException: com.spoledge.aacplay.AACPlayerActivity
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1891)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread.access$600(ActivityThread.java:127)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.os.Handler.dispatchMessage(Handler.java:99)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.os.Looper.loop(Looper.java:137)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread.main(ActivityThread.java:4511)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at java.lang.reflect.Method.invokeNative(Native Method)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at java.lang.reflect.Method.invoke(Method.java:511)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:976)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:743)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at dalvik.system.NativeStart.main(Native Method)
    07-30 11:04:56.409: E/AndroidRuntime(27849): Caused by: java.lang.ClassNotFoundException: com.spoledge.aacplay.AACPlayerActivity
    07-30 11:04:56.409: E/AndroidRuntime(27849): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.Instrumentation.newActivity(Instrumentation.java:1026)
    07-30 11:04:56.409: E/AndroidRuntime(27849): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1882)
    07-30 11:04:56.409: E/AndroidRuntime(27849): ... 11 more

    ReplyDelete
    Replies
    1. Hi bob,

      it seems there is a problem in the build file - the java library from the decoder subproject is not correctly included when creating final apk.
      Try "dexdump" utility and search for "Class descriptor" lines:

      dexdump bin/classes.dex | grep "Class desc"
      Class descriptor : 'Landroid/annotation/SuppressLint;'
      Class descriptor : 'Landroid/annotation/TargetApi;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/AACPlayer$1;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/AACPlayer;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/BufferReader$Buffer;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/BufferReader;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/Decoder$Info;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/Decoder;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/IcyInputStream;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/MP3Player;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/MultiPlayer;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/PCMFeed;'
      Class descriptor : 'Lcom/spoledge/aacdecoder/PlayerCallback;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$1;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$2;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$3;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$4$1;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$4;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity$5;'
      Class descriptor : 'Lcom/spoledge/aacplay/AACPlayerActivity;'
      Class descriptor : 'Lcom/spoledge/aacplay/BuildConfig;'
      Class descriptor : 'Lcom/spoledge/aacplay/History;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$attr;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$color;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$drawable;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$id;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$layout;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$string;'
      Class descriptor : 'Lcom/spoledge/aacplay/R$style;'
      Class descriptor : 'Lcom/spoledge/aacplay/R;'

      Sometimes (first time when the project is clean) it happens that the classes of the package com.spoledge.aacdecoder are missing.
      If so, try to rebuild the "player" subproject - or even try to "touch libs/aacdecoder-android-0.6.1.jar" and then rebuild it (try more than once).
      Check when dexdump is reporting the decoder's classes - then retry running the APK.
      I know I should fix it in the build process, but I cannot see the root cause yet.
      Let me know if this was your case.
      Thanks.

      Vaclav

      Delete
  46. Thanks Vaclav... that worked great. Now on to redoing some apps :)

    ReplyDelete
  47. Hello. I have a app with multiple radio stations. But sometimes when i switch between station the encoder fails to start. I get this: "Failed to start encoder". Then if i click another station it works. Any ideea?

    ReplyDelete
  48. ok let me give you more details:
    SOMETIMES (not always) when i switch between stations i get this error:

    08-06 13:12:36.991: E/AACPlayer(538): playAsync():
    08-06 13:12:36.991: E/AACPlayer(538): java.lang.RuntimeException: Cannot start native decoder
    08-06 13:12:36.991: E/AACPlayer(538): at com.spoledge.aacdecoder.Decoder.start(Decoder.java:217)
    08-06 13:12:36.991: E/AACPlayer(538): at com.spoledge.aacdecoder.AACPlayer.playImpl(AACPlayer.java:351)
    08-06 13:12:36.991: E/AACPlayer(538): at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:313)
    08-06 13:12:36.991: E/AACPlayer(538): at com.spoledge.aacdecoder.AACPlayer.play(AACPlayer.java:283)
    08-06 13:12:36.991: E/AACPlayer(538): at com.spoledge.aacdecoder.AACPlayer$1.run(AACPlayer.java:248)
    08-06 13:12:36.991: E/AACPlayer(538): at java.lang.Thread.run(Thread.java:1019)


    Is there a way i can make the aacPlayer.playAsync command retry until it plays if i get this error? Thanks

    ReplyDelete
    Replies
    1. Hi Florin,

      retrying is done in the native layer, so if native decoder cannot start playing, then the Java part just throws the exception.

      It would be fine to know the root cause of this problem, so I recommend to capture the stream into file(s) (few seconds each) and retry using the files. Then you can log an issue to the project with attached stream samples.

      Vaclav

      Delete
  49. This comment has been removed by the author.

    ReplyDelete
  50. First of all, thank you for your great work.

    It would be great if you an add to accdecoder the possibility of using pause/resume functions (as in Android MediaPlayer). It is very useful for streaming for example (for making a pause when hearing something and then continue...) I will need it in my app.

    Thank you again,

    ReplyDelete
  51. thanks for this great app, one question its possible to have multi streams? i mean have like a list of stations then a play button at the right of each station ?

    thanks.

    ReplyDelete
  52. Hi Vaclav,

    Im unable to find aacplayer-android-r20.zip.Could you please help me.Looking forward for your reply.

    Thank you

    ReplyDelete
  53. Hi Vaclav, GREAT WORK!!! I want to bind a Visualizer with the AACPlayer class. I know that in the MediaPlayer class there is a method named "getAudioSessionId()". Then I create Visualizer class with this argument: mPlayer.getAudioSessionId. But in the AACPlayer class there isn't a familiar method like that in the MediaPlayer class. So is there any solution for my problem?
    Thanks

    ReplyDelete
  54. Hi, my name is Matheus and I used the AAC Decoder to make a simply app to hear a local web radio that have AAC+ format.
    I read it:

    PLEASE NOTE that the use of this software may require the payment of patent royalties. You need to consider this issue before you start building derivative works. We are not warranting or indemnifying you in any way for patent royalities! YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN ACTIONS!

    And I want to ask you if i can have problems if I distribute this application, even gaining nothing with it. I dont know about patents and etc.

    Awaiting your answer.
    Thanks. Great work.

    ReplyDelete
  55. Nice work on the aacdecoder! It's working fine for me with the exception of two minor issues:
    1) Encoded strings in the metadata get truncated at the semi-colon. For example, if I have "Rock & Roll" as part of the metadata, the client only receives, "Rock &amp". Has anyone else encountered this?
    2) Stopping audio has a noticable latency. Is there way to interrupt playback immediately?

    ReplyDelete
    Replies
    1. In my example, the data inserted into the stream was the encoded version of ampersand
      (& amp; without the space)

      Delete
  56. Thanks for sharing the code, I have a question with it.
    I try to use AACplayer to play online radio stream like SHOUTcast.
    but went i new AACplayer it throws an error: java.lang.UnsatisfiedLinkError: Library aacdecoder not found
    error

    is it not work on emulator?

    ReplyDelete
  57. nvm i find out the problem i have to copy armeabi file and armeabi-v7a file to libs also.
    thanks for the code.

    ReplyDelete
  58. First of all many thanks for this project.

    you can change the package name com.spoledge.aacplayer another?

    as I do?

    ReplyDelete
  59. Hie ... Great Project indeed, I need help. I am using streaming in one of my android activities and I wanna be able to controll the streaming from other activities as well. I am following this source http://code.google.com/p/aacdecoder-android/source/browse/trunk/player/src/com/spoledge/aacplay/AACPlayerActivity.java .

    Thank You!

    ReplyDelete
  60. Hello, i am trying this project with rtmp, in which i receives AAC audio from Red5 server, i need to decode them, so when i start decoding, after doing decoder.start(..) it shows values for samplerate, channels , but during decoding it shows errors like "Invalid channel configuration", "PCE shall be the first element in a frame","Invalid number of channels","Bitstream value not allowed by specification", "Channel coupling not yet implemented", etc... number of samples is -1 always after decoding...
    So my question is will this work with RTMP streams as the code work correctly with HTTP streams.

    ReplyDelete
  61. Hi, I'm using this library and I added it in my project using Android Studio 0.5.5 but when I run the project I got this error:

    java.lang.UnsatisfiedLinkError: Couldn't load aacdecoder from loader dalvik.system.PathClassLoader[DexPathList[[zip file

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  62. GeoDeveloper, I'm having the same problem. I see you posted this question only two days ago, I wonder if that's a coincidence. Although I'm using Eclipse ADT

    ReplyDelete