131

I am currently trying to design a simple app that streams an internet radio station. I have the URL for the station and am setting up the Media Player like

    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setDataSource(URL);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        mediaPlayer.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mediaPlayer.start();

The program isn't crashing when emulated, but nothing is playing and I am get the following error:

start called in state 0

and right below it is

Error (-38,0)

Does anyone know what this means?

I've read a little about these state errors, but couldn't find anything that applies to my project.

jahroy
  • 22,322
  • 9
  • 59
  • 108
SmashCode
  • 4,227
  • 8
  • 38
  • 56
  • 1
    http://stackoverflow.com/questions/8681550/android-2-2-mediaplayer-is-working-fine-with-one-shoutcast-url-but-not-with-the http://stackoverflow.com/questions/8671479/android-mediaplayer-works-fine-in-our-custom-audio-streaming-application-up-to-a – Yaqub Ahmad Jan 28 '12 at 07:23
  • possible duplicate of [Android MediaPlayer Problems :"Error (-38 , 0) " and "stop called in state 1"](http://stackoverflow.com/questions/11913108/android-mediaplayer-problems-error-38-0-and-stop-called-in-state-1) – rds Jun 22 '15 at 08:55
  • @SmashCode please mark another answer as the accepted as my answer is totaly useless. – tidbeck Aug 07 '15 at 12:36

17 Answers17

141

You need to call mediaPlayer.start() in the onPrepared method by using a listener. You are getting this error because you are calling mediaPlayer.start() before it has reached the prepared state.

Here is how you can do it :

mp.setDataSource(url); 
mp.setOnPreparedListener(this);
mp.prepareAsync();

public void onPrepared(MediaPlayer player) {
    player.start();
}
Christian
  • 25,249
  • 40
  • 134
  • 225
user1492955
  • 1,728
  • 2
  • 12
  • 13
  • 1
    What if we don't want it to start right away? Even if I initialize my player and wait a minute or so, the first time i try to play it, it has this error unless I call .start() in onPrepared – Elliptica Nov 15 '17 at 19:52
  • 2
    You prepare it before and remember you prepared it. In parallel, you try to remember if you want to run it. When it is both prepared and you want to run it, you start it. – Victor Paléologue Jul 19 '18 at 10:27
41

It seems like Error -38 means a state-exception (as the error-message indicates). For example if you call start(), before the song was ready, or when you call pause(), even if the song isn't playing at all.

To fix this issue check the state of the mediaPlayer before calling the methods. For example:

if(mediaPlayer.isPlaying()) {
    mediaPlayer.pause();
}

Additionally, the MediaPlayer is sending event-messages. Even if you do not need the prepared-event (although it would be a good idea to not start the playback before this event was fired) you must set a callback-listener. This also holds true for the OnErrorListener, OnCompletionListener, OnPreparedListener and OnSeekCompletedListener (if you call the seek method).

Listeners can be attached simply by

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});
Alexander Pacha
  • 9,187
  • 3
  • 68
  • 108
15

I got this error when I was trying to get the current position (MediaPlayer.getCurrentPosition()) of media player when it wasn't in the prepared stated. I got around this by Keeping track of its state and only calling the getCurrentPosition() method after onPreparedListener is called.

fire in the hole
  • 1,171
  • 15
  • 34
13

This is my code,tested and working fine:

package com.example.com.mak.mediaplayer;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder

    Button btnplay = (Button) findViewById(R.id.btnplay); //Play
    btnplay.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View vone) {
        mpp.start();
      }
    });

    Button btnpause = (Button) findViewById(R.id.btnpause); //Pause
    btnpause.setOnClickListener(new View.OnClickListener() {

      @Override
      public void onClick(View vtwo) {
        if (mpp.isPlaying()) {
          mpp.pause();
          mpp.seekTo(0);
        }
      }
    });
  }
}
Michel Jung
  • 2,966
  • 6
  • 31
  • 51
MAK
  • 379
  • 3
  • 7
6

I encountered the same issue few days ago. My audio MediaPlayer works fine on devices with high processing power, but for slow devices, the media player just did not play some time and from LogCat it had many complain about called in wrong state. So I resolved it by calling putting the call to start(), pause(),... in onPrepared() method of OnPreparedListener() as below:

mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    ........
                    mediaPlayer.start();
                    ....
                    songControlBtn.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mediaPlayer.isPlaying()) {
                                mediaPlayer.pause();

                            } else {
                                mediaPlayer.start();

                            }
                        }
                    });

                    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            ............

                        }
                    });
                }
            });

Also try to release any media player that you do not need any more. For example, if you do not want to play the audio or video on background then you should call mediaPlayer.release() in onPause().

Tony Vu
  • 4,251
  • 3
  • 31
  • 38
5

i tested below code. working fine

public class test extends Activity implements OnErrorListener, OnPreparedListener {

private MediaPlayer player;

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


    player = new MediaPlayer();
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
        player.setOnErrorListener(this);
        player.setOnPreparedListener(this);
        player.prepareAsync();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }       
}
@Override
public void onDestroy() {
    super.onDestroy();
    player.release();
    player = null;
}
@Override
public void onPrepared(MediaPlayer play) {
    play.start();
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
    return false;
}
}
Emran Hamza
  • 3,829
  • 1
  • 24
  • 20
3

You get this message in the logs, because you do something that is not allowed in the current state of your MediaPlayer instance.

Therefore you should always register an error handler to catch those things (as @tidbeck suggested).

At first, I advice you to take a look at the documentation for the MediaPlayer class and get an understanding of what that with states means. See: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Your mistake here could well be one of the common ones, the others wrote here, but in general, I would take a look at the documentation of what methods are valid to call in what state: http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States

In my example it was the method mediaPlayer.CurrentPosition, that I called while the media player was in a state, where it was not allowed to call this property.

SimonSimCity
  • 6,415
  • 3
  • 39
  • 52
3

enter image description here

above the picture,you can get the right way.

Longalei
  • 453
  • 3
  • 8
3

Some times file are encoded in a way that Android can't decode. Even some mp4 files can not be played. Please try a different file format (.3gp are played most of the time) and see..

Rukmal Dias
  • 3,242
  • 1
  • 34
  • 28
  • 47
    I can't ask an internet radio station to change their file format. – SmashCode May 24 '12 at 23:51
  • Do you get the "Can't play this video" popup? How do you deal with it? I catch the error but get this modal regardless and I have no control over the source of media as it comes from a public API. If anyone knows how to prevent the "Can't play this video" modal I would be grateful. – Krafty Apr 26 '14 at 15:07
  • Did you try setting an error listener. MediaPlayer mp = new MediaPlayer() { @Override public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener listener) { // Do stuff here.. } }; mp.setDataSource(.. – Rukmal Dias May 13 '14 at 17:56
2

I solved both the errors (-19,0) and (-38,0) , by creating a new object of MediaPlayer every time before playing and releasing it after that.

Before :

void play(int resourceID) {
if (getActivity() != null) {

     //Using the same object - Problem persists
    player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}

After:

void play(int resourceID) {

if (getActivity() != null) {

    //Problem Solved
    //Creating new MediaPlayer object every time and releasing it after completion
    final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}

Saurabh Padwekar
  • 3,888
  • 1
  • 31
  • 37
1

I also got this error i tried with onPreparedListener but still got this error. Finally i got the solution that error is my fault because i forgot the internet permission in Android Manifest xml. :)

<uses-permission android:name="android.permission.INTERNET" />

I used sample coding for mediaplayer. I used in StreamService.java
onCreate method

String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();            
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
adiga
  • 34,372
  • 9
  • 61
  • 83
B M
  • 1,863
  • 1
  • 25
  • 40
1
  if(length>0)
        {
            mediaPlayer = new MediaPlayer();
            Log.d("length",""+length);
            try {
                mediaPlayer.setDataSource(getApplication(),Uri.parse(uri));
            } catch(IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.seekTo(length);
                    mediaPlayer.start();

                }
            });
            mediaPlayer.prepareAsync();
kamakshi
  • 11
  • 2
1

It was every much frustrated. So, I got solution which works for me.

try {
                        if (mediaPlayer != null) {
                            mediaPlayer.release();
                            mediaPlayer = null;

                        }
                        mediaPlayer = new MediaPlayer();
                        mediaPlayer.setDataSource(file.getAbsolutePath());
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mediaPlayer) {
                                mediaPlayer.start();
                                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                                    @Override
                                    public void onCompletion(MediaPlayer mediaPlayer) {
                                        mediaPlayer.stop();
                                        mediaPlayer.release();
                                        mediaPlayer = null;
                                    }
                                });
                            }
                        });
                        mediaPlayer.prepare();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
Aman Srivastava
  • 1,007
  • 1
  • 13
  • 25
1

For me this worked

mp.seekTo(0);
mp.start();
Piyush Jajoo
  • 1,095
  • 2
  • 18
  • 27
-1
mp = new MediaPlayer();
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName);
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  public void onPrepared(MediaPlayer mp) {
    mp.start();
  }
});

mp.prepareAsync();
adiga
  • 34,372
  • 9
  • 61
  • 83
HuynhHan
  • 365
  • 1
  • 4
  • 11
-1

I have change setAudioStreamType to setAudioAttributes;

mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .setLegacyStreamType(AudioManager.STREAM_ALARM)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build());
shubomb
  • 672
  • 7
  • 20
-2

I am new in android programming and i had same error as this one. so i simply redefined the mp.createmediaPlayer = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI). It may not the true way to do it but it worked fined for me:

try {
  mp = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
} catch (Exception e) {
  e.printStackTrace();
}

mp.start();
adiga
  • 34,372
  • 9
  • 61
  • 83