5

Hey, I'm using MediaPlayer to play a regular ShoutCast stream. The code is straightforward with prepareAsync() and a handler to start the playback. While it works flawlessly with some streams like DI.FM or ETN.FM (http://u10.di.fm:80/di_progressive), with others (http://mp3.wpsu.org:8000/) it won't go past the prepare state. No other listeners are called either.

//Uri streamUri = Uri.parse("http://u10.di.fm:80/di_progressive"); /* works */
Uri streamUri = Uri.parse("http://mp3.wpsu.org:8000/"); /* stuck on prepare state */
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(this.getBaseContext(), streamUri);
mediaPlayer.prepareAsync();

Any feedback is appreciated!

Community
  • 1
  • 1
Sergei
  • 63
  • 1
  • 4
  • 1
    Izvorean: Use `adb logcat`, DDMS, or the DDMS perspective in Eclipse to examine LogCat and look for any warnings that might be raised. – CommonsWare Nov 15 '10 at 01:50
  • I'm using Eclipse debug, but the MediaPlayer posts no log messages :( – Sergei Nov 16 '10 at 14:38
  • I do not know if this is still valid, but my 2 cents: 1. 1. You can print messages to logcat by using Log. Check http://developer.android.com/reference/android/util/Log.html 2. create() is a better method for instantiating an object of MediaPlayer class. Additional details here: http://developer.android.com/reference/android/media/MediaPlayer.html#create(android.content.Context,%20android.net.Uri,%20android.view.SurfaceHolder) – Sriram Jan 12 '11 at 11:05
  • I don't have a real answer for this but this will help your app to be less frustrating for the user (http://stackoverflow.com/questions/6582908/why-does-it-take-so-long-for-androids-mediaplayer-to-prepare-some-live-streams/42042218#42042218) – LiTTle Feb 04 '17 at 15:43

2 Answers2

2

I think that there are some compatibility problems with the server end. This is rather strange since the emulator handles it ok in my case - just not on my Froyo Galaxy S, even though it is the same API version.

It could be a codec issue, http streaming issue, I do not know. But all the servers that fail tend to be old ones, with "Copyright 1998 - 2004" at the bottom... Not exactly recent or up to date you would think.

One potential workaround (which I have not tried yet) would be to use the StreamProxy, which would also make your code compatible with 2.1 and possibly earlier versions too. At the cost of extra work, extra code, and without doubt extra bugs...

In case you are not aware of it, there is another player bug report for 2.2 which may be relevant too: Basic streaming audio works in 2.1 but not in 2.2

Community
  • 1
  • 1
totaam
  • 1,306
  • 14
  • 25
2

I'm facing an issue when MP "hangs" at preparing state too long (stream) and i'm trying to stop it using reset(). This causes MP to hang and thus my whole app freezes. Seems like there is no way to stop MP at preparing state. Im thinking on use prepare() wrapped in thread instead of prepareAsync(). Then i'll be able to kill that thread. As for now i did it in following way:

private void actionCancel(){
            try {
                mp.setDataSource(new String());
            } catch (Exception e) {
                e.printStackTrace();
                android.util.Log.d(TAG,"actionCancel(): mp.setDataSource() exception");
                mp.reset();
            }
}

and it works 4me.
Additionally i have a following counter:

    @Override
    public void onBufferingUpdate(final MediaPlayer mp, final int percent) {

        if (!mp.isPlaying()){
//          android.util.Log.d(TAG,"onBufferingUpdate(): onBufferingUpdateCount = "+onBufferingUpdateCount);
            if (onBufferingUpdateCount>MAX_BUFFERING_UPDATES_AT_PREPARING_STATE)
                restartMP();
            onBufferingUpdateCount++;
            return;
        }
      }

i'd discover this listener always triggers at preparing state. So if it triggers more than 10 times and MP is still not playing i'm just restarting it:

private void restartMP(){
        if (mp!=null)
            if (mpState==MediaPlayerState.Preparing)
                actionCancel();
            else
                mp.reset();
    else
        mp = new MediaPlayer();
        mpState = MediaPlayerState.Idle;
        onBufferingUpdateCount=0;
        //isRequestCancelled=false;
        requestTrackInfoStartedAt=0;
        requestPlay();
}

note MediaPlayerState is my custom enum which has "Preparing" value. Also mpState is a class property/field which holds current MediaPlayerState state. Before starting prepareAsync() im setting mpState to MediaPlayerState.Preparing after it completes im setting it to MediaPlayerState.Started or other corresponding value.

Stan
  • 6,511
  • 8
  • 55
  • 87
  • does this method take less time to `mediaPlayer.prepareAsync()` and to `mediaPlayer.start()` – Naz141 Mar 30 '16 at 08:57
  • Actually this method is about "how to stop MP without ANR" only. Its up to you how long app will wait for MP to pass prepare state. And you can kill MP instance using my method after, lets say, 5s passed and MP still is preparing. – Stan Mar 30 '16 at 09:40