English 中文(简体)
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?

问题回答

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.

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;
}

I think you should listne for loss/gain of network. Have a look at: Detect 3G or Wifi Network restoration

When you seek or skip or the connection is lost and MediaPlayer keeps reconnecting to the proxy server, you must send this response with Status 206 after you get the request and range(int) from the client.

String headers += "HTTP/1.1 206 Partial Content
";
headers += "Content-Type: audio/mpeg
";
headers += "Accept-Ranges: bytes
";
headers += "Content-Length: " + (fileSize-range) + "
";
headers += "Content-Range: bytes "+range + "-" + fileSize + "/*
";
headers += "
";

And when you receive a request from MediaPlayer that does not contain Range in the HTTP header , then it is requesting a new stream file, in this case your response header should look like this:

String headers = "HTTP/1.1 200 OK
";
headers += "Content-Type: audio/mpeg
";
headers += "Accept-Ranges: bytes
";
headers += "Content-Length: " + fileSize + "
";
headers += "
";

Enjoy!





相关问题
Android - ListView fling gesture triggers context menu

I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

Android intent filter for a particular file extension?

I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...

Android & Web: What is the equivalent style for the web?

I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...

TiledLayer equivalent in Android [duplicate]

To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?

Using Repo with Msysgit

When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error: /c/Users/Andrew Rabon/bin/repo: line ...

Android "single top" launch mode and onNewIntent method

I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...

From Web Development to Android Development

I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ? Also what new languages would I ...

热门标签