2

I have a list of songs that I'm streaming using the MediaPlayer. Some of the songs consistently work and others consistently do not work. I can't see a difference between these files, and they seem to play fine in itunes and such.

When the songs fail it is throwing an IllegalStateException on the mediaPlayer.prepare() line. The IllegalStateException that is thrown has no useful info in it, (detailMessage is null, stackState is null)

Here is my code

try {
    mediaPlayer.setDataSource(media.url);
    setPlayerState(PlayerState.PREPARING);
    mediaPlayer.prepare();
} catch (Exception e) {
    e.printStackTrace();
    Log.e(TAG, "bad stream");
}

Here is a url to the file that does NOT work: skdy.bryceb.dev.mediarain.com/song.m4a

Here is one that DOES work: skdy.bryceb.dev.mediarain.com/song2.m4a

Any ideas why this works on some songs and fails on others?

Brais Gabin
  • 5,827
  • 6
  • 57
  • 92
b-ryce
  • 5,752
  • 7
  • 49
  • 79
  • That url is for one of the files that cause the exception right??? If so, post a url to one which doesn't cause a problem and I'll try to compare. – Squonk Dec 15 '10 at 00:45
  • Here is one that works: skdy.bryceb.dev.mediarain.com/song2.m4a – b-ryce Dec 15 '10 at 00:53
  • Hmmm, nothing I can tell you so far. I can stream both files from url using Winamp and also directly in Chrome on my PC. I downloaded both and rendered them in GraphEdit and they both produce identical graphs and play glitch-free. I'm between projects at the moment so will play around some more - if I find an answer I'll get back to you. – Squonk Dec 15 '10 at 01:16
  • @MisterSquonk, it looks like it might be a separate issue. Both files are actually getting to the exception. But the first file is also triggering the mediaplayer error listener with an error code of -38 looking into that now. – b-ryce Dec 15 '10 at 01:33

2 Answers2

3

Thanks MisterSquonk I'm sure that way would work.

In my particular case after beating my head against the wall for a while I realized that on some songs, I was getting to the buffered amount before the player state was getting set to prepared. So I added a check to make sure that the MediaPlayer was in the "PREPARED" state and then it worked great:

// Media prepared listener
    mediaPlayer.setOnPreparedListener(
            new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    setPlayerState(PlayerState.PREPARED);
                }
            });

    // Media buffer listener
    mediaPlayer.setOnBufferingUpdateListener(
            new MediaPlayer.OnBufferingUpdateListener() {
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                    // Sometimes the song will finish playing before the 100% loaded in has been
                    // dispatched, which result in the song playing again, so check to see if the 
                    // song has completed first
                    if(getPlayerState() == PlayerState.COMPLETED)
                        return;

                    if(getPlayerState() == PlayerState.PAUSED)
                        return;

                    // If the music isn't already playing, and the buffer has been reached
                    if(!mediaPlayer.isPlaying() && percent > PERCENT_BUFFER) {
                        if(getPlayerState() == PlayerState.PREPARED)
                        {
                            mediaPlayer.start();
                            setPlayerState(PlayerState.PLAYING);
                        }
                        //if it isn't prepared, then we'll wait till the next buffering
                        //update
                        return;
                    }
                }
            });
b-ryce
  • 5,752
  • 7
  • 49
  • 79
0

OK, I hacked together a minimal Mediaplayer implementation in a 'sandbox' app/activity I always keep spare for testing.

I might be wrong but if you're streaming these songs over the net, you'll need to prefix the url with http://.

I tried the urls with Winamp and Chrome verbatim (no protocol prefix string) and they worked fine although it's likely both of those applications will use some form of intelligence to work out how to connect/stream.

If I tried that in my mediaPlayer code, I get the same exception as you but if I prefix the urls with http:// the songs play fine.

Example...

// Activity scope
Button button;
CheckBox checkBox;
String url = "";

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //button declared in my activity
    button = (Button)findViewById(R.id.button);
    button.setOnClickListener(this);

    if (!checkBox.isChecked())
        url = getString(R.string.url_song1);
    else
        url = getString(R.string.url_song2);

    mediaPlayer = new MediaPlayer();
}

@Override
public void onClick(View arg0) {
    try {
        Log.i(TAG, "onClick() entered...");
        mediaPlayer.setDataSource(url);
        Log.i(TAG, "Preparing mediaplayer...");
        mediaPlayer.prepare();
        Log.i(TAG, "Starting mediaplayer...");
        mediaPlayer.start();
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "bad stream");
    }       
}

If I copy the songs to my SD card both play fine and as long as the internet url strings have an 'http://' prefix then they also work.

Squonk
  • 48,735
  • 19
  • 103
  • 135