Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Streaming with Android MediaPlayer - catching errors and buffering

I'm having trouble getting MediaPlayer to be resilient when streaming from a HTTP URL.

If I start playing the file, but then drop the connection (e.g. airplane mode), MediaPlayer#OnErrorListener generates what=1, extra=-17 and then shortly afterwards what=-38, extra=0.

There's no documentation I can see in the APIs of what this denotes, except extra is "Typically implementation dependant". I'm using a HTC Hero (well, it's T-Mobile UK's G2 Touch).

Do other people get the same values and is it safe to catch these values as meaning the connection's gone?

How can I best resume when the connection reappears? (save the current seek to preferences, and retry every 5 seconds?)

How do I know when the device has decided to start playing what it's been buffering - is there a callback (other than polling isPlaying())?

Additionally, I'm not entirely sure what onBufferingUpdate provides. I'm using a 40 minute podcast MP3 (64kbps bitrate) - buffering goes 1%, 2%, 3%. When I seek to about 30 mins in, it shows 75%, then when I seek back to the start back to 5% - what is the point of this callback other than showing approximately what is cached?

Finally - is there any way to pipe what's streamed to an MP3?

like image 430
Chris Avatar asked Jan 09 '10 17:01

Chris


2 Answers

Taken from This similar stack Overflow Question

I too am disappointed about the MEDIA_INFO_BUFFERING_START and MEDIA_INFO_BUFFERING_END hooks... bummer.

I checked out the Pandora app and it doesn't display a buffering indicator. When music is interrupted for buffering, it just sits there as if nothing happened and the UI looks like it's still playing. So I've come to the conclusion that if you're using MediaPlayer, it's just not possible to determine if the track is temporarily paused for buffering.

However, I did notice that there are a couple MediaPlayer constants that could be of use: MEDIA_INFO_BUFFERING_START and MEDIA_INFO_BUFFERING_END. But they're only available in API level 9+, and the docs don't say anything about them. I'm assuming they can be used with an OnInfoListener.

I'm disappointed, but at least I can stop spinning my wheels now and move on to something else.

like image 143
Lysogen Avatar answered Sep 30 '22 13:09

Lysogen


It is possible to do this

MediaPlayer has methods to register a OnPreparedListener and a OnBufferingUpdateListener

onPrepared will be called once the player has buffered enough to start playing.

http://developer.android.com/reference/android/media/MediaPlayer.OnPreparedListener.html

onBufferingUpdate will be called to update you on buffering information.

http://developer.android.com/reference/android/media/MediaPlayer.OnBufferingUpdateListener.html

You should also use the Connectivity service to listen for network connectivity

public boolean hasConnectivity()
{
    ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = connectivityManager.getActiveNetworkInfo();

    int netType = info.getType();
    int netSubtype = info.getSubtype();

    if (netType == ConnectivityManager.TYPE_WIFI)
    {
        return info.isConnected();
    }
    else if (netType == ConnectivityManager.TYPE_MOBILE && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS)
    {
        return info.isConnected();
    }

    return false;
}
like image 23
JeffG Avatar answered Sep 30 '22 12:09

JeffG