Saturday, June 4, 2011

Streaming Radio Stations on Android

Streaming radio stations or audio files hosted on streaming servers on Android is pretty straight-forward. But then, Android has it's limitations. It won't stream just any file or radio station. In this post, I would not be specifying the formats or protocols that Android supports. Rather, this example is just a walk through of how the MediaPlayer class should be used to stream audio files/radio stations.

For an example here, I have used a SHOUTcast radio station. The URL for the source is:
http://shoutcast2.omroep.nl:8104/

The accompanying sample project contains a ProgressBar, two Buttons (for playing and stopping the MediaPlayer).

Before running the example, one should look into the documentation of the MediaPlayer class. A look at the state diagram would perhaps help you clear to understand how it actually works.

To initialize the MediaPlayer, you need a few lines of code. There you go:
MediaPlayer player = new MediaPlayer();
player.setDataSource("http://shoutcast2.omroep.nl:8104/");
Now that the MediaPlayer object is initialized, you are ready to start streaming. Ok, not actually. You will need to issue the MediaPlayer's prepare command. There are 2 variations of this.

  1. prepare(): This is a synchronous call, which is blocked until the MediaPlayer object gets into the prepared state. This is okay if you are trying to play local files that would take the MediaPlayer longer, else your main thread will be blocked.
  2. prepareAsync(): This is, as the name suggests, an asynchronous call. It returns immediately. But, that obvisouly, doesn't mean that the MediaPlayer is prepared yet. You will still have to wait for it to get into the prepared state, but since this method will not block your main thread, you can use this method when you are trying to stream some content from somewhere else. You will get a callback, when the MediaPlayer is ready through onPrepared(MediaPlayer mp) method, and then, the playing can start.
So, for our example, the best choice would be:
player.prepareAsync();
You need to attach a listener to the MediaPlayer to receive the callback when it is prepared. This is the code for that.
player.setOnPreparedListener(new OnPreparedListener(){
            public void onPrepared(MediaPlayer mp) {
                     player.start();
            }
 
});
Once, it goes into the prepared state, you can now start playing. Simple???? Yes, of course. Just to wrap it up, to stop the MediaPlayer, you need to call the stop() method.

There are several other helper methods which lets you query the progress or status of the player. Jump to the docs page and you will find more information on them. You can checkout the source code here.

Project source for the new Eclipse + Android tool chain. Download here.

NOTE: This sample project is tested on Gingerbread(2.3) and should work on Froyo(2.2) and above.

56 comments:

  1. Great tutorial.

    Simple and neat. Thank you!.

    ReplyDelete
  2. Simple and Awesome tutorial!

    ReplyDelete
  3. how to retrieve the metadata from shoutcast and show?

    ReplyDelete
  4. @Erik: That I haven't looked at. Sorry.

    ReplyDelete
  5. exactly what i was looking for... but one issue i ran into is when internet signal is lost, the stream stops and does not reconnect automatically. how to ensure an automatic/timed reconnect attempts?? many thanks!

    ReplyDelete
  6. is this tutorial work with android 2.1 OS ?

    ReplyDelete
  7. hello i have tried the source code everything goes right but i dont receive any audio out, i tried also to chnge the url to another streaming channel but the same thing

    ReplyDelete
  8. hello excuse me how to go abt putting in the radio station website like http://shoutcast2.omroep.nl:8104/

    i cant seem to get a stream for mine
    http://adio.listen2myradio.com/

    i need a solution to this for my android project , a bit of help would help me alot quite lost now

    ReplyDelete
  9. alright i have solved my problem already realised it was a network address mistake,

    now i cant seem to make my progress bar work the stream works but the progress bar doesn't show any buffer animation

    ReplyDelete
  10. @Roy: Seems to be that the source is not properly configured for streaming. Any errors you are getting in your logs?

    ReplyDelete
  11. in this example,the url like this http://shoutcast2.omroep.nl:8104/ .
    can i streaming with otomatic port..?? so, the port not write like that. but it automatically..
    (sory if my english is bad)
    please help me..

    ReplyDelete
  12. does this work on android 1.6?

    ReplyDelete
  13. @ankz: I haven't tried it. But my guess is that it won't work on 1.6. Give it a try though. It might just work on a few devices.

    ReplyDelete
  14. Ok I downloaded it test it emulator works fine but on the samsung glaxy any version, nothing happens. No audio whatsoever. The " buttonRecord.setEnabled(true);" after calling start never runs the button is always false. I wait for some time to see if ever starts streaming, but no audio and status never changes. Nothing strange in log cat. Could you please suggest what could be an issue since there is nothing to debug obviously.

    ReplyDelete
  15. Hi, your code does not work well, recording throws unexpected error almost on all emulators and froyo 2.2 seems to be an issue particularly on Samsung i5800 with froyo 2.2. It seems on prepared listener creates an issue. Cat log mostly shows errors such as (1, -1) at the end. I did not have time to debug... would love to see a fix sometime :) Anyway remarkable work regardless, Cheers mate.

    ReplyDelete
  16. Hello Kumar,

    Great thanks, for such a helpful tutorial. Can you please check why it not works for this url:
    http://ib3.islambox.tv:8011/

    Waiting for your response.

    Regards.

    ReplyDelete
    Replies
    1. Solution is here: http://stackoverflow.com/a/8833346/265167

      Delete
  17. Was this done in Eclipse? I'm a little confused on what are the files are and do you have them in a zip file to download.

    Thanks

    ReplyDelete
  18. Yes it was done in eclipse. But I guess you will have problems with the new adt and android tools. I will attach a zip file here that should work on the new tool chain as well.

    ReplyDelete
  19. @BigMarkess: Source attached. Check the updated post.

    ReplyDelete
  20. Any idea how to make this app run as a services too? Such as if I hit the home screen it runs in the background?

    ReplyDelete
  21. Hello I have a question. How can I play this URL using this code ??

    http://109.123.116.114:7015/

    ReplyDelete
  22. Helo, how can i stream this URL (http://109.123.116.114:7015/). I tried it in app, but nothing happens :(

    ReplyDelete
  23. is nice simple concept but is missing a service and wont play on background when u exit th the app or phone goes off

    ReplyDelete
  24. Hello Kumar,

    your code working fine on emulator, but when i tried to run it on my galaxy S2 (gingerbread), it didn't play. Log cat said something like below:

    02-23 06:18:25.324: I/NuHTTPDataSource(2622): connect to shoutcast2.omroep.nl:8104/ @0
    02-23 06:18:25.499: W/NuHTTPDataSource(2622): Server did not give us the content length!
    02-23 06:18:25.564: E/HTTPStream(2622): recv failed, server is gone, total received: 4723 bytes
    02-23 06:18:25.564: E/HTTPStream(2622): recv failed, errno = -1 (Operation not permitted)
    02-23 06:18:25.564: E/NuCachedSource2(2622): source returned error -1004
    02-23 06:18:25.704: E/MediaPlayer(9175): error (1, -2147483648)
    02-23 06:18:25.704: E/MediaPlayer(9175): Error (1,-2147483648)
    02-23 06:18:27.024: D/dalvikvm(7165): GC_EXPLICIT freed 5K, 49% free 2752K/5379K, external 0K/0K, paused 88ms
    02-23 06:18:32.064: D/dalvikvm(7443): GC_EXPLICIT freed 7K, 47% free 3266K/6151K, external 0K/0K, paused 121ms
    02-23 06:18:37.039: D/dalvikvm(2882): GC_EXPLICIT freed 309K, 50% free 3224K/6343K, external 0K/0K, paused 96ms
    02-23 06:18:59.999: I/AlarmManager(2711): wakelock acquire, uid:1000 at elapsed real time: 35625310
    02-23 06:19:00.054: I/AlarmManager(2711): wakelock release, uid:1000 at elapsed real time: 35625367
    02-23 06:19:49.729: I/AlarmManager(2711): wakelock acquire, uid:10013 at elapsed real time: 35675045
    02-23 06:19:49.749: I/AlarmManager(2711): wakelock release, uid:10013 at elapsed real time: 35675065

    please advice. thanks

    ReplyDelete
  25. hey its grate example and simple to understand.....

    ReplyDelete
  26. Hey, thanks for your very useful tutorial, it's a great help for beginners in android development like me. I tried your code, and it worked. BTW I'm making online radio app and I want the title of the playing song to be viewed. I have no idea about this, could you give me some hints? Thanks in advance.

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

    ReplyDelete
  28. nice tutor, hey dude how to make many station in app?

    ReplyDelete
  29. Hey i developed simple radio app using your guideline...but my application have service that actually allow me to run the radio as background process..but many times service not working properly for Stop and Start service for radio...so please tell me any solution to handle the service so that it work properly..

    Thanks,
    Pranav

    ReplyDelete
    Replies
    1. What exactly is the problem that you are facing?

      Delete
    2. while working with app..i need to stop and start the service for radio app and to run the next station...but many times the service remain start...and when i came back to application from outside to radio app...it suddenly stop whatever station running in....

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

    ReplyDelete
  31. while stopping and starting the service it not working properly..means it just stop itself when i came back to application from outside while radio is running as service...

    ReplyDelete
    Replies
    1. I can't help you with that. You have to fix it on your own. Check the logs and see if you can figure out the problem.

      Delete
    2. ohhh...that's ok...i checked out already but i think its service problem....that i cant manage but as suggested in android doc i prepared service for starting and stopping it..but sorry..working..
      If u have solution the please suggest me or if u have any one who expert in it or actually have developed such application nice to welcome u....please

      Delete
  32. Nice example, i have a question, does it work with a RTMP streaming protocol?

    Thank you in advance

    ReplyDelete
  33. Nice example, does it work with RTMP streaming protocol?

    Thank you in advance

    ReplyDelete
  34. Thanks for the code.It is working . Can you also share the code to get metadata like title, station name of the stream ?

    ReplyDelete
  35. Thanks for the code. Now I am able to play the station using southcast stream but I also want to get Metadata of the stream like title, station name. Can you please share the code to achieve this in Android?

    ReplyDelete
    Replies
    1. Will try to investigate that. I am not sure if you can do that with all the stations. But I will have a look.

      Delete
  36. I tried to stream the following url but it is not working
    http://bitgravity.live.cdn.bitgravity.com/hellofm/live/feed02

    ReplyDelete
  37. Kumar, it seems lime many people are complaining about not hearing sound on some devices. i wrote a custom streamer myself and have had the same problems. Have you been able to figure out why this happens? It's been driving my crazy and i have no clues. thanks!!

    ReplyDelete
  38. Kumar, it seems that many people have complained about not hearing sound on some devices. i have written my own streaming code and have the same problems. Any ideas why this happens? I've been trying to figure it out and have no clue. Thanks for the great article!

    ReplyDelete
  39. Good example. Thank you!
    Any ideas on how to make it work with ustream?

    ReplyDelete
  40. Get exception "prepareasync called in state 0". Any idea?

    ReplyDelete
  41. i got error (38,0)..
    please help to fix this .. :(

    ReplyDelete
  42. This little app is awesome. I am trying to figure out how I can make the URL editable from the app. Any suggestions guys?

    ReplyDelete
  43. very good job, works perfectly in the emulator, but I'm having trouble exporting:

    Error - keytool error invalid keystore format java.io.IOException

    ReplyDelete
  44. very good job, works perfectly in the emulator, but I'm having trouble exporting:

    Error - keytool error invalid keystore format java.io.IOException

    ReplyDelete