Android Streaming MediaPlayer Tutorial – Updated to v1.5 (Cupcake)

After spending the last year game programming on the iPhone, I’ve finally returned to Android.  My six prior tutorials were outdated (Android v1.0) so I took the time to update them to v1.5 (Cupcake).  The most popular of those tutorials was the Streaming MediaPlayer tutorial so that’s the primary focus of this post. 

Tutorial #3 results screenshots

At the time of initially writing the streaming tutorial, Android’s media streaming function didn’t work well so I wrote my own.  As of v1.5 however, Android’s MediaPlayer streams very well.  That said, it’s still useful to know how to retrieve a media file from a server and store it on the device.  This would be useful to immediate replay of the file at a later date or for caching files for later playback ‘off the grid’.

Download the source files to get started immediately and then view the rest of the tutorial after the jump.

You may want to look at my old Android v1.0 streaming tutorial for additional details. I don’t want to rewrite that post completely so I’ll mostly focus here on the changes required for Android v1.5. That said, there is very little difference between my old tutorial and this new one.

The most important change is that MediaPlayer.setDataSource() now takes a FileDescriptor instead of a String path to the media File. It seems the reason to use FileDescriptors is for security/permission reasons. In either case though, passing a String path to our media File resulted in errors such as “PVMFErrNotSupported” and “Prepare failed.: status=0×1″. So until I learn otherwise, I recommend using FileDescriptor for the MediaPlayer.


FileInputStream fis = new FileInputStream(mediaFile);
mPlayer.setDataSource(fis.getFD());

The only other change is I can no longer find any File move functionality it Android so I wrote my own. It does exactly what it says, it moves data in one File to a new File location. This is used while streaming the media file so we can double buffer it. The double buffering allows us to simulaneously download to one File while playing from another File. We sync the downloaded data between the Files as more data is downloaded:

public void moveFile(File oldLocation, File newLocation) throws IOException

Download the source files for all the tutorials. The streaming media tutorial available by clicking button #3. Don’t forget to look at my old Android v1.0 streaming tutorial for additional details.

65 Responses to “Android Streaming MediaPlayer Tutorial – Updated to v1.5 (Cupcake)”


  1. 1 Hapoo January 3, 2010 at 9:55 pm

    I implemented your new revision and it works fine for the first file I play albeit with a stutter at data swaps. I can’t seem to get it to load any subsequent files though. I’ve gone so far as trying to load a new instance of it, but it merely crashes the program. Any ideas or hints you can give me?
    Thanks

    • 2 Biosopher January 3, 2010 at 9:59 pm

      The tutorial app was only designed to load & play a single file. You would need to add MediaPlayer shutdown and cleanup at the end of the file playing for it to download and play another file (exercise for the reader).

      With a restart though, I was able to load and reload files without problems. What error message are you getting?

    • 3 Tim April 7, 2010 at 7:03 am

      I try to use this to play a shoutcast but there are always gaps between the files.
      Any ideas how to improve this?
      I tried different buffer sizes, but there is no solution.
      I’m using the code from the 1.5 tutorial.

      I’m getting the “PVMFErrNotSupported”-failure, too

  2. 6 Hapoo January 3, 2010 at 10:07 pm

    Thanks for the rapid response!!

    I’m not getting any errors… none that I can detect anyway. I tried reseting the mediaplayer before calling startstreaming(…) again, but that didn’t work either, it didn’t do anything. If I had an idea as to where it was locking up it would make it much easier to fix.

    At this point with the new sdks, is this still a beneficial route to go for streaming? Doesn’t the standard mediaplayer buffer the data? The only real reason I’m going through all this is because I want the entire mp3 file loaded on to the device so if someone rewinds/fastforwards the file doesn’t reload from the server and I’m not sure if mediaplayer does this automatically.

    • 7 Biosopher January 4, 2010 at 6:52 am

      I’m unsure how Android handles the buffering upon fast forward/rewind. My tutorial was written before Android’s streaming was working well. I’m fairly happy with the built-in streaming of v1.5 so I don’t use my own code anymore.

      Anthony

  3. 8 Nenad January 4, 2010 at 1:15 pm

    I have modify code little bit so it can work on my HTC Tattoo (1.6). Then I tried it and it’s not working. when I press button play it start downloading file without playing anything.

    I’m begginer in Android programming.

    Help please … thanks.

  4. 11 DinDin January 6, 2010 at 11:12 am

    I am trying to do some live video delivery to the android platform. I have done this for the iPhone and given Apple’s HTTP adaptive streaming, this is made very easy. But not so on Android. What path would you recommend?

    I am writing along the lines of what you have done (thanks for the examples) but I don’t want to have glitches when switching between files. Would be made simpler if there was a way for Android to implement something like M3U8 or another video playlist playback mechanism.

    • 12 Biosopher January 6, 2010 at 6:51 pm

      Hi Din Din,

      I didn’t include this in the tutorial as I wasn’t sure it would work at the time. However as the MediaPlayer is currently written, you don’t need to double buffer the streamed media as in the current tutorial. You can actually just write directly the file as it’s playing.

      You would need to add logic to pause playback if the playback exceeds the amount of downloaded file though.

      Anthony

      • 13 Hapoo January 6, 2010 at 6:53 pm

        I discovered this today. The only catch (in my case anyway) is that you have to allocate space for the entire file first.

  5. 14 Biosopher January 6, 2010 at 7:00 pm

    Hi Hapoo,

    You can always allocate a given amount of file space and stream to it until it’s full. At that point, allocate a new File for streaming then create a new MediaPlayer to point to the new File.

  6. 15 Biosopher January 8, 2010 at 9:04 pm

    Hi Nenad,

    It would be easiest if you could quickly tell me how you altered the code to work on your Tattoo. Also explain why you had to alter it to work on your Tattoo.

    Thanks,
    Anthony

    • 16 Nenad January 9, 2010 at 2:37 am

      It’s working :)
      I was thinking that I need to change version to 1.6.
      Thanks. :)

      Is it posible to stop mp immediately when I press back button?
      Now it’s playing whole (downloaded part) of mp3 file.

      Your Tutorials are fantastic!
      Thank you very much for helping us to learn programming in Android!

      • 17 Biosopher January 9, 2010 at 12:39 pm

        You can setup the MediaPlayer to stop and restart. Just listen to the buttons, test for the MedaPlayers current state (playing, paused), and take the appropriate action.

  7. 18 Tiger January 11, 2010 at 5:52 am

    Just out of curiousity, will this work on a real stream ? Not by streaming a (size definite) MP3 file from a server… And if so what kind of modifications does the code need ?

    • 19 Biosopher January 11, 2010 at 8:06 am

      First that would depend on the format of the stream and whether Android’s MediaPlayer supports that media format. Android’s media support is fairly minimal.

      If it was a supported stream though, I would recommend simply using Android’s MediaPlayer as there would seem to be little reason to download and cache the stream yourself.

      However if the stream was supported, then I don’t know why this approach would not work.

      • 20 Tiger January 14, 2010 at 3:20 am

        well basically because in your code I see that you are supplying a size to the startStreaming() method of the StreamingMediaPlayer class

        public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds)

        so what should be supplied for a real stream ?

        Also the formats would be (ideally) AAC(+)/MP3/AMR-WB throught rtsp or http…

        My tests confirm a working MP3 through rtsp with the inbuilt mediaplayer but for example I am not able to play a .3gp rtsp stream using AAC+…
        Any idea’s or experiences on how to get that to work ?

  8. 21 Biosopher January 14, 2010 at 9:02 am

    Hi Tiger,

    I just looked at the supported media types for Android:

    http://developer.android.com/intl/zh-CN/guide/appendix/media-formats.html

    That list doesn’t say anything about support for streaming formats. File-based media typically have a header with information about the file. Streams provide that information in other ways. That would seem to preclude saving the stream to a file for replay as a file-based format.

    In short unless Android supports streamed audio, I doubt this tutorial would be much help.

  9. 22 Tiger January 18, 2010 at 2:13 am

    hhmmm ok, sounds plausible :D
    Not very happy to hear that even with a new and modern platform we still aren’t able to actually stream AAC(+) content… Seems like they looked a lot at J2ME and decided that a 6 year old platform still is a good way to go :(
    I did try your project, and it works, but I did notice that on my device (Android dev Phone 2, which is a HTC Magic running 1.6) the “holes” inbetween the played pieces have a tendency to grow through time… So if the first couple of switches between chunks souns decent after 6-7 switches it will start to have holes of several seconds… Is this normal ?

    • 23 Biosopher January 18, 2010 at 10:15 am

      There shouldn’t be any gaps in the downloaded audio files. Are you saying that once you’ve downloaded the audio files, the final file residing on the device has gaps in the audio?

      What audio file are you streaming? Could you confirm this by streaming this file:

      http://www.pocketjourney.com/downloads/pj/video/famous.3gp

      • 24 Tiger March 3, 2010 at 1:00 am

        Hi,
        first of all sorry for the old reply but here it is :

        [quote]Are you saying that once you’ve downloaded the audio files, the final file residing on the device has gaps in the audio? [/quote]
        Nope the files themselves were ok, but there is a gap which keeps getting bigger inbetween the stopping of a file and the starting up of the next one… So inbetween “chunks” (files in this case)…
        I heard though that ogg would be faster thus completely removing those gaps, only my source is mp3 so is there some way, to your knwoledge, to encode mp3 to ogg in Android itself ?

  10. 25 Tanmay January 19, 2010 at 1:46 pm

    Hey.. thanks for the excellent tutorials and the time you have put in to help everyone developing android apps.

    I am working on something which is close to the streaming media player but a little different. I want to be listening on a port on my phone for some raw audio data, that will be sent from a location on my network using netcat. I pretty much want to perform a netcat listen function on my android and pipe out the data to the audio hardware. You must have worked or heard about the AudioRecord and AudioTrack classes which give access to raw media.

    I was wondering if you could refine the following algorithm for me and point me to the implementation, as I know a bit of java but not too confident with using Sockets, Pipes and Android stuff.

    The procedure i am planning to use is:

    1) Use a new ServerSocket(port) to listen on particular port.
    2) The other side connects to this port using netcat :
    3) Make a new Pipe which takes the outputstream from the socket, and feeds it into the input of the audio hardware.
    4) Use methods from AudioTrack to play the raw audio in real time

    Any help in this area would be very much appreciated, as I have been struggling to find anything in this area.

    Cheers..
    Tanmay

    • 26 Biosopher January 19, 2010 at 9:13 pm

      Hi Tanmay,

      That’s quite the challenge you’ve set for yourself. Seems like mostly a networking challenge at this point to get the audio onto the phone. (1) should be easy as I’m sure there’s documentation on the web about it.

      For (2), I don’t know anything about netcat. Why are you using it? I assume there’s a reason you’re connecting from the server to the phone rather than vice versa? I would guess you want to push the data to the phone but don’t want the phone wasting battery power by constantly polling the server for data.
      How is your server going to discover the IP address of your phone though? My worry is that the IP address changes as the phone roams.

      (3) should be documented on the web. For (4), look here:
      http://hashspeaks.wordpress.com/2009/06/18/audiorecord-part-4/

      • 27 Tanmay January 20, 2010 at 11:59 am

        Hey, Thanks for the prompt reply.
        Yup, its a challenging one, but quite fun to do ! I will probably elaborate on my project a bit more to give u a slight picture of what we I am doing.
        My first step, which is complete now, was to look at MightyOhms Wifi Radio Project and transform it into a full duplex audio comms system between two routers (with USB sound cards) by installing OpenWRT on it. Its just a linux flavour to unleash your router. I set up one of the routers as an Access point and the other as a client, and by using netcat as I said above and a recorder/player program on the routers I was able to achieve this setup.
        So all that is good. Now, I was looking at replacing the client side router, with another wifi client..ie. the Android phone.
        The comms has to be real time, thats why I am not going for polling. IP address on roaming is not an issue, as being my own lan, I can use static IP addressing.
        So yeah, this will help me establish a 2 way audio path.

        For step (4), i already looked at the code from http://hashspeaks.wordpress.com/2009/06/18/audiorecord-part-4/ and made it into an android project, however, when I heard what I recorded, It seemed like something is overdriving the microphone. And I seem to be having no control on that via the API. Whatever I record closet to the phone turns into clipped garbage, but sounds from far away are clear.

        It would be a huge help if you could test that code on hashirs blog on an android G1 phone running 1.6(which I tested it on) , so that I can confirm its not something I am doing wrong or something to do with my phone.

        Many thanks
        Tanmay

  11. 28 Biosopher January 20, 2010 at 10:07 pm

    Hi Tanmay,

    I’m using Hashir’s code to record from both a G1 & HTC Ion’s microphone. The only problem I’ve found is that 8 bit audio has a problem. If I use 16 bit, everything works fine.

    • 29 Tanmay January 21, 2010 at 12:02 pm

      Hey .. Just found the solution to my problem !
      It was just endianness ! I shud hv been careful while playing the file on an intel PC, and specify Big endian format for audio. My problem was that it was recording correctly, but listening in the wrong format introduces noise in the recording (but still records ..which is why i never thought it cud be the parameters) ! I heard the right one in audacity, as it let me choose between endianness.

      All sorted now, thank you for the help.

      Now onto the networking stuff !

      Cheers.
      Tanmay

  12. 30 Draffodx January 21, 2010 at 1:58 am

    Hi Biosopher,

    Thanks for the excellent tutorial.

    I currently record sound from the mic and save it to a 3gp file on the sdcard.

    What I want to do is be able to record straight from the mic and play what I’m recording back out with only a 1 second delay.

    Is this possible do you know? Would the code from your StreamingMediaPlayer be usable with changes to do this and a good place to start?

  13. 32 mitu January 21, 2010 at 6:00 am

    Hi, I tried to run your streaming program but I got these errors in logCat :

    01-21 20:41:23.995: ERROR/Player(1839): 122880
    01-21 20:41:23.995: ERROR/Player(1839): /data/data/com.pocketjourney.tutorials/cache/playingMedia1.dat
    01-21 20:41:24.165: ERROR/PlayerDriver(51): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
    01-21 20:41:24.175: ERROR/MediaPlayer(1839): error (1, -4)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): Error initializing the MediaPlaer.
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): java.io.IOException: Prepare failed.: status=0×1
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at android.media.MediaPlayer.prepare(Native Method)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at com.pocketjourney.media.StreamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:185)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at com.pocketjourney.media.StreamingMediaPlayer.access$2(StreamingMediaPlayer.java:173)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at com.pocketjourney.media.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:153)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at android.os.Handler.handleCallback(Handler.java:587)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at android.os.Handler.dispatchMessage(Handler.java:92)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at android.os.Looper.loop(Looper.java:123)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at android.app.ActivityThread.main(ActivityThread.java:4203)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at java.lang.reflect.Method.invokeNative(Native Method)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at java.lang.reflect.Method.invoke(Method.java:521)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
    01-21 20:41:24.185: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1839): at dalvik.system.NativeStart.main(Native Method)
    01-21 20:41:24.185: WARN/PlayerDriver(51): PVMFInfoErrorHandlingComplete
    01-21 20:41:24.195: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.195: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.195: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.205: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.205: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.205: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.215: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.225: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.225: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.225: ERROR/MediaPlayer(1839): Attempt to call getDuration without a valid mediaplayer
    01-21 20:41:24.225: ERROR/MediaPlayer(1839): error (-38, 0)
    01-21 20:41:24.235: ERROR/MediaPlayer(1839): Error (-38,0)
    01-21 20:41:24.235: ERROR/MediaPlayer(1839): Error (-38,0)

    and continuing….

    So what is it causing for I can’t understand. I’m trying to run it on real device and my SDK is 1.6

    I’m waiting for the reply.

    thanks,
    mitu

    • 33 Biosopher January 21, 2010 at 8:33 am

      Hi mitu,

      Seems like you’re using a file format that isn’t supported by Android. Only these formats are supported:

      http://developer.android.com/intl/zh-CN/guide/appendix/media-formats.html

      You can try using this file for testing as .3gp is supported by Android: http://www.pocketjourney.com/downloads/pj/video/famous.3gp

      • 34 Mitu January 21, 2010 at 11:28 pm

        hi Biosopher, I tried it with mp3 format and I found it is supported media format. In fact I tried to run it with your codebase url without changing it and got previuos errors that I posted to you. Now I tried with wma format uploading to my own site and got the following error in logCat:

        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): Error updating to newly loaded content.
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): java.lang.NullPointerException
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at com.pocketjourney.media.StreamingMediaPlayer.transferBufferToMediaPlayer(StreamingMediaPlayer.java:205)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at com.pocketjourney.media.StreamingMediaPlayer.access$3(StreamingMediaPlayer.java:201)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at com.pocketjourney.media.StreamingMediaPlayer$5.run(StreamingMediaPlayer.java:265)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at android.os.Handler.handleCallback(Handler.java:587)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at android.os.Handler.dispatchMessage(Handler.java:92)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at android.os.Looper.loop(Looper.java:123)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at android.app.ActivityThread.main(ActivityThread.java:4203)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at java.lang.reflect.Method.invokeNative(Native Method)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at java.lang.reflect.Method.invoke(Method.java:521)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
        01-22 14:10:15.965: ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): at dalvik.system.NativeStart.main(Native Method)

        So please show me the way what I should do or if anything I’m doing wrong.

        Thanks,
        mitu

  14. 35 Mitu January 21, 2010 at 11:31 pm

    Sorry to mention that My device is T-Mobile running Android 1.6

    thanks,
    mitu

    • 36 Biosopher January 22, 2010 at 3:29 pm

      Hi Mitu,

      I just download the tutorial and installed it onto my HTC Ion running Android v1.6. It played two different .mp3 without a problem.

      ERROR/com.pocketjourney.media.StreamingMediaPlayer(628): java.lang.NullPointerException

      Judging from this part of your error message though, you’re getting a NullPointerException for some reason. Run debug and let me know what’s causing it.

      • 37 Mitu Kumar Debnath February 9, 2010 at 3:40 am

        Hello Biosopher, It’s been a long time I didn’t get here. I was busy with my other works and missed to come here. Still no hope but persist these error logs:

        02-09 18:19:49.754: ERROR/Player(3639): 121544
        02-09 18:19:49.754: ERROR/Player(3639): /data/data/com.pocketjourney.tutorials/cache/playingMedia1.dat
        02-09 18:19:49.944: ERROR/PlayerDriver(51): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
        02-09 18:19:49.944: ERROR/MediaPlayer(3639): error (1, -4)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): Error initializing the MediaPlaer.
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): java.io.IOException: Prepare failed.: status=0×1
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at android.media.MediaPlayer.prepare(Native Method)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at com.pocketjourney.media.StreamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:170)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at com.pocketjourney.media.StreamingMediaPlayer.access$2(StreamingMediaPlayer.java:159)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at com.pocketjourney.media.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:143)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at android.os.Handler.handleCallback(Handler.java:587)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at android.os.Handler.dispatchMessage(Handler.java:92)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at android.os.Looper.loop(Looper.java:123)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at android.app.ActivityThread.main(ActivityThread.java:4203)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at java.lang.reflect.Method.invokeNative(Native Method)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at java.lang.reflect.Method.invoke(Method.java:521)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
        02-09 18:19:49.954: ERROR/com.pocketjourney.media.StreamingMediaPlayer(3639): at dalvik.system.NativeStart.main(Native Method)
        02-09 18:19:49.964: WARN/PlayerDriver(51): PVMFInfoErrorHandlingComplete
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.974: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.984: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.984: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.984: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.984: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.994: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.994: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:49.994: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:49.994: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:50.004: ERROR/MediaPlayer(3639): Attempt to call getDuration without a valid mediaplayer
        02-09 18:19:50.004: ERROR/MediaPlayer(3639): error (-38, 0)
        02-09 18:19:50.014: ERROR/MediaPlayer(3639): Error (-38,0)
        02-09 18:19:50.014: ERROR/MediaPlayer(3639): Error (-38,0)

        I tried it with your Tutorials.apk which is provided with your source code. But the same error showing after a 20-30 KB buffering. May be when it is trying to start the media player to play the file.

        Thanks,
        mitu

  15. 38 Mitu February 9, 2010 at 3:47 am

    hello Biosopher,
    is there any need of changing in your code for proper media file or need to change the url of media file? here I found that you are changing the extension as *.dat for the media file if I’m correct abt it.

    Please help me from getting out of it.

    Thanks,
    mitu

  16. 39 Biosopher February 9, 2010 at 8:21 am

    Hi Mitu,

    Check out roughly the 5th paragraph in this tutorial. It talks about the “PVMFErrNotSupported” error you’re getting.

    As for the .dat extension, it doesn’t matter what you use.

    Anthony

  17. 40 Mitu February 10, 2010 at 12:27 am

    Hi Biosopher,

    you were right. This “PVMFErrNotSupported” error is due to FileDescriptor Class. I used file descriptor instead of absolute file path for media player setDataSource() method and it plays for a couple of seconds and then shows these errors: Here it says it doesn’t get the desired file.

    02-10 14:43:14.636: ERROR/Player(848): 122880
    02-10 14:43:14.636: ERROR/Player(848): /data/data/com.pocketjourney.tutorials/cache/playingMedia1.dat
    02-10 14:43:14.816: DEBUG/WifiService(79): ACTION_BATTERY_CHANGED pluggedType: 2
    02-10 14:43:15.847: WARN/AudioFlinger(50): write blocked for 96 msecs
    02-10 14:43:20.046: DEBUG/dalvikvm(501): GC freed 512 objects / 25088 bytes in 201ms
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): Error updating to newly loaded content.
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): java.io.FileNotFoundException: /data/data/com.pocketjourney.tutorials/cache/playingMedia2.dat
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:231)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at java.io.FileInputStream.(FileInputStream.java:80)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at com.pocketjourney.media.StreamingMediaPlayer.transferBufferToMediaPlayer(StreamingMediaPlayer.java:213)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at com.pocketjourney.media.StreamingMediaPlayer.access$3(StreamingMediaPlayer.java:202)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at com.pocketjourney.media.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:166)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at android.os.Handler.handleCallback(Handler.java:587)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at android.os.Handler.dispatchMessage(Handler.java:92)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at android.os.Looper.loop(Looper.java:123)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at android.app.ActivityThread.main(ActivityThread.java:4203)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at java.lang.reflect.Method.invokeNative(Native Method)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at java.lang.reflect.Method.invoke(Method.java:521)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
    02-10 14:43:31.266: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at dalvik.system.NativeStart.main(Native Method)
    02-10 14:43:31.286: ERROR/MediaPlayer(848): pause called in state 128
    02-10 14:43:31.296: ERROR/MediaPlayer(848): error (-38, 0)
    02-10 14:43:31.306: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): Error updating to newly loaded content.
    02-10 14:43:31.306: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): java.io.FileNotFoundException: /data/data/com.pocketjourney.tutorials/cache/playingMedia3.dat
    02-10 14:43:31.306: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:231)
    02-10 14:43:31.306: ERROR/com.pocketjourney.media.StreamingMediaPlayer(848): at java.io.FileInputStream.(FileInputStream.java:80)

    But if I don’t use file descriptor for setDataSource() method which is inside the transferBufferToMediaPlayer() method then I get these errors:

    02-10 14:57:55.826: ERROR/Player(1003): 122880
    02-10 14:57:55.826: ERROR/Player(1003): /data/data/com.pocketjourney.tutorials/cache/playingMedia1.dat
    02-10 14:57:56.456: WARN/AudioFlinger(50): write blocked for 99 msecs
    02-10 14:58:00.036: WARN/AudioTrack(50): obtainBuffer timed out (is the CPU pegged?) 0x22b78 user=00015ae8, server=00015341
    02-10 14:58:00.036: WARN/AudioTrack(50): *** SERIOUS WARNING *** obtainBuffer() timed out but didn’t need to be locked. We recovered, but this shouldn’t happen (user=00015ae8, server=00015341)
    02-10 14:58:03.766: WARN/AudioTrack(50): obtainBuffer timed out (is the CPU pegged?) 0x22b78 user=0002bd77, server=0002b5d0
    02-10 14:58:03.766: WARN/AudioTrack(50): *** SERIOUS WARNING *** obtainBuffer() timed out but didn’t need to be locked. We recovered, but this shouldn’t happen (user=0002bd77, server=0002b5d0)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): Error updating to newly loaded content.
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): java.io.FileNotFoundException: /data/data/com.pocketjourney.tutorials/cache/playingMedia2.dat
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:231)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at java.io.FileInputStream.(FileInputStream.java:80)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at com.pocketjourney.media.StreamingMediaPlayer.transferBufferToMediaPlayer(StreamingMediaPlayer.java:213)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at com.pocketjourney.media.StreamingMediaPlayer.access$3(StreamingMediaPlayer.java:202)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at com.pocketjourney.media.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:166)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at android.os.Handler.handleCallback(Handler.java:587)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at android.os.Handler.dispatchMessage(Handler.java:92)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at android.os.Looper.loop(Looper.java:123)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at android.app.ActivityThread.main(ActivityThread.java:4203)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at java.lang.reflect.Method.invokeNative(Native Method)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at java.lang.reflect.Method.invoke(Method.java:521)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
    02-10 14:58:10.906: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at dalvik.system.NativeStart.main(Native Method)
    02-10 14:58:10.956: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): Error updating to newly loaded content.
    02-10 14:58:10.956: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): java.io.FileNotFoundException: /data/data/com.pocketjourney.tutorials/cache/playingMedia3.dat
    02-10 14:58:10.956: ERROR/com.pocketjourney.media.StreamingMediaPlayer(1003): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:231)

    Here I can see that there is a buffer problem. So what should I do for solve this prob. What do I need to change in codebase.

    Thanks,
    mitu

  18. 41 Biosopher February 10, 2010 at 9:29 am

    For some reason you’re getting this error:

    FileNotFoundException: /data/data/com.pocketjourney.tutorials/cache/playingMedia2.dat

    That means the newly downloaded content isn’t being written to the new file. Run the app is debug mode with breakpoints during the file writing process to see what’s happening.

    As for not using FileDescriptor during setDataSource(), I can’t tell you what to do. I wasn’t able to get any other option to work properly except FileDescriptor.

  19. 42 Mitu February 10, 2010 at 11:25 pm

    Hello Biosopher,

    Thank you for helping me. It’s now working.

    Thanks once again :)

    Regards,
    mitu

    • 43 chinmay July 9, 2010 at 5:49 am

      Hi Mitu,

      Can you please let me know what did you do in order to remove that error ? I am having the same problem.

      Thanks,
      Chinmay

  20. 44 Biosopher March 3, 2010 at 8:37 am

    Hi Tiger,

    This tutorial only supports single files downloads so you must have updated it to support multiple files. Look at how you’re handling the handoff between files. Seems like you are still writing to a file even though no data is being recieved.

    You should only be writing to file what you read from the stream.

    int numread = stream.read(buf);

    out.write(buf, 0, numread);

    Cheers,
    Anthony

  21. 45 Winston March 21, 2010 at 1:31 pm

    Nice stuff, is it possible to stream live media via real time streaming protocol (rtsp) on android?

    • 46 Biosopher March 21, 2010 at 4:07 pm

      There appears to be lots of discussion on the web about using RTSP on Android. You could possibly use what’s written here to roll your own rtsp client.

  22. 47 zerayaqob March 24, 2010 at 12:44 pm

    Thank you so much man, this works like a charm! I’ve been trying to get streaming working for weeks!

  23. 48 simran April 25, 2010 at 8:15 pm

    Hi Biosopher,
    We tried playing another audio file as well as a video file with the code you have provided.. It played for 5 sec and then stops playing, but continues to buffer and download the complete file. We guess the problem would be with the number of bytes you assign for two buffers –
    1) the buffer into which the data is copied from the URL. – it is 16384
    2) the buffer used to move the file – it is 8192
    Does these numbers have any significance with the file size or the data rate at which the file is downloaded?

    Do u have an idea if Android emulator 1.5/2.0 supports real-time video streaming?

    • 49 Biosopher April 26, 2010 at 8:12 am

      Hi Simran,

      This code was initialy written for Android pre-v1.0. As of Cupcake (v1.5), Android’s MediaPlayer supports streaming video/audio very well.

      • 50 simran April 26, 2010 at 10:41 am

        Thanks for the reply.
        We are doing a project where we need to develop the RTP/RTSP stack on Android for real time streaming.

        We are basically receiving the rtp packets for audio/video files over the socket. But we are not able to play them back real-time.

        You mentioned Android’s MediaPlayer supports streaming of video/audio, does this mean real-time support?

        We are referring to the code you have provided for (Cupcake(v1.5)).

        For understanding of the code we tried playing other audio files changing the parameters 16384 and 8192 according to the file size. We couldn’t play the entire file.
        So it would be great if you could just explain the significance of those byte array lengths.

        Thanks in advance.

  24. 51 Biosopher April 26, 2010 at 10:52 am

    Hi Simran,

    Android’s MediaPlayer supports very few media types. My code was tested only for .3gp which is a file-based non-real-time audio format.

    My guess is you’re using a file format that isn’t supported by Android. Only these formats are supported:

    http://developer.android.com/intl/zh-CN/guide/appendix/media-formats.html

  25. 52 Jeremy Coker April 29, 2010 at 1:57 am

    Hi Biosopher,

    A related ‘live’ streaming question:

    In my setup I have a live stream source connected which an Axis
    encoder (250S) receives and encodes to MPEG2 which I then receive into
    VLC (re-encodes as h264 – mpeg4) and re-stream out as an RTSP stream, using a .sdp definition.

    I’m attempting to display this LIVE video source using the Media Video
    demo that comes with the Android SDK, i’ve also attempted to use a
    http link in the Android emulator browser.

    But to no avail, I don’t ever see a video playing.

    Can anyone confirm if the android emulator is able to play this type
    of video source and if the
    real android device say an HTC Hero could play this using RTSP.

    OR

    Is there some fundamential thing i’m missing here ?

  26. 54 Jeremy Coker April 30, 2010 at 12:30 am

    Mmm… i’m definitely converting this in VLC to h.264 and also tried h.263 format and re-streaming out to android. A second VLC confirms that the live stream plays.

    Only question is can Android really handle a live stream i.e. there is NO file with this except the streaming description file (.sdp)

    The VLC sout configuration for restreaming out to android is:

    :sout=#transcode{vcodec=h264,vb=124,fps=10,scale=1,width=480,height=320,acodec=none}:rtp{dst=10.19.99.129,port=5004,mux=ts,sdp=rtsp://10.19.99.129:8080/stream.sdp}

    ????????

    • 55 Biosopher April 30, 2010 at 5:51 am

      Hi Jeremy,

      Unfortunately I’m not experienced enough with live streaming to conclude yea/nay on whether Android can stream live. Given the numerous questions on this tutorial though, it seems Android doesn’t readily support live streaming out of the box.

      Anthony

  27. 56 venkat May 13, 2010 at 3:45 am

    Hi Biosopher

    i am using absolute path to play a file which resides in sd card

    mp.reset();
    mp.setDataSource(“/sdcard/playsong.wma”);
    mp.prepare();
    mp.start();

    the following errors are coming up.
    i think its throwing error at mp.prepare();
    could pls help me out??????

    05-13 17:11:15.911: WARN/MediaPlayer(5567): info/warning (1, 26)
    05-13 17:11:15.911: INFO/MediaPlayer(5567): Info (1,26)
    05-13 17:11:15.920: ERROR/PlayerDriver(31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
    05-13 17:11:15.930: ERROR/MediaPlayer(5567): error (1, -4)
    05-13 17:11:15.930: WARN/System.err(5567): java.io.IOException: Prepare failed.: status=0×1
    05-13 17:11:15.959: WARN/PlayerDriver(31): PVMFInfoErrorHandlingComplete
    05-13 17:11:15.969: WARN/System.err(5567): at android.media.MediaPlayer.prepare(Native Method)
    05-13 17:11:15.969: WARN/System.err(5567): at com.androplayer1.PlayerService.Playsong(PlayerService.java:92)
    05-13 17:11:15.980: WARN/System.err(5567): at com.androplayer1.PlayerService$1.playFile(PlayerService.java:53)
    05-13 17:11:15.990: WARN/System.err(5567): at com.androplayer1.InterFac$Stub.onTransact(InterFac.java:57)
    05-13 17:11:15.990: WARN/System.err(5567): at android.os.Binder.execTransact(Binder.java:287)
    05-13 17:11:16.000: WARN/System.err(5567): at dalvik.system.NativeStart.run(Native Method)

    • 57 tiger May 25, 2010 at 6:45 am

      I’m not Biosopher, but I can see the following in your errors :
      05-13 17:11:15.920: ERROR/PlayerDriver(31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported

      And I have a very very advanced feature on my mouse : a scrollwheel it’s called.. with that I actually (yes yes) can scroll up and down in a page, that in combination with another very special feature I have (called eyes) I can see this :
      http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/#comment-608

      also you actually might want to read the tutorial itself, and you will notice something about your
      mp.setDataSource(“/sdcard/playsong.wma”);
      code…

      • 58 Biosopher May 25, 2010 at 11:13 am

        Thanks Tiger,

        I get rather tired of answering questions for people that are simply too lazy to even read the tutorial.

        Cheers,
        Anthony

  28. 59 hema June 21, 2010 at 6:06 am

    can anyone send me code for playing a list of audio mp3 files dat are present in sdcard ………

  29. 60 hema June 21, 2010 at 6:08 am

    and also android code to display pdf files pdf files on the emulator……..

  30. 61 arlen June 30, 2010 at 9:43 am

    Hi, Thank you for the source code it was gr8
    I have a question,
    How can I stream a radio station via android insted of streaming mp3 files .
    something like this one :

    http://mfile.akamai.com/2110/live/reflector:20637.asx?bkup=21011
    .asx file types.

  31. 63 arlen July 2, 2010 at 7:11 pm

    hi ,
    Is there any direct link that I can download all the MyNPR or npr files like a zip file ?


  1. 1 Android Tutorial 3: Custom Audio Streaming with MediaPlayer « Pocket Journey Trackback on December 27, 2009 at 9:38 am
  2. 2 Android Audio Streaming « Ballard Hack Trackback on April 25, 2010 at 9:18 am

Leave a Reply




a