There are 3 MediaPlayers and I want to set that these 3 sounds play seamlessly using setNextMediaPlayer(). The code is simple (repeated code is omitted)
mediaPlayer1 = new MediaPlayer();
try {
AssetFileDescriptor afd = getAssets().openFd("sound1.ogg");
mediaPlayer1.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mediaPlayer1.prepare();
afd.close();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer1.start();
mediaPlayer2 = new MediaPlayer();
//Prepare 2nd player with sound2 without calling start()
mediaPlayer3 = new MediaPlayer();
//Prepare 3rd player with sound3 without calling start()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mediaPlayer1.setNextMediaPlayer(mediaPlayer2);
mediaPlayer2.setNextMediaPlayer(mediaPlayer3); //ERROR RUNTIME!!!
And here I get an error
E/MediaPlayer﹕ next player is not prepared
D/AndroidRuntime﹕ Shutting down VM
W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x4175fda0)
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.testgaplesssound.app, PID: 28960
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: java.lang.IllegalStateException at...
The error say MediaPlayer﹕ next player is not prepared so I tried setting onPrepared listener
mediaPlayer2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mediaPlayer2.setNextMediaPlayer(mediaPlayer3);
}
}
});
but onPrepared is never initiated!
So, how can I sent the 3rd player to play seamlessly as the first two?
I just tested the following setup with no errors, thinking your problem was with initialization. But then I noticed that you're starting your first player before initializing and chaining the other two. Reordering your code might solve your problem, but I'll post this as well, as it seems a simpler solution, to me, at least.
Move your audio files to the /res/raw folder, and initialize and start your players like so:
MediaPlayer mediaPlayer1, mediaPlayer2, mediaPlayer3;
mediaPlayer1 = MediaPlayer.create(this, R.raw.sound1);
mediaPlayer2 = MediaPlayer.create(this, R.raw.sound2);
mediaPlayer3 = MediaPlayer.create(this, R.raw.sound3);
mediaPlayer1.setNextMediaPlayer(mediaPlayer2);
mediaPlayer2.setNextMediaPlayer(mediaPlayer3);
mediaPlayer1.start();
NB: I tested under API 19, so you'll still need your version checks, if you're back-supporting.
Related
im trying to play a MP3 from raw folder .i have different buttons which playing different MP3's so i must change the mediaplayer input every time here is my code on button click:
public void onClick(View v) {
t=R.raw.virtualbarber
playsound(t);
}
and here is my mediaplayer code which im taking error in .create ! :
private void playSound(string t ){
mp = MediaPlayer.create(getActivity(), t);
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.setLooping(true);
mp.start();
}}
im also declared my string and mediaplayer on top of my project like this :
MediaPlayer mp;
int t;
nothing works ! my other program worked correctly but this doesn't !
logcat
01-17 22:01:35.016: E/AndroidRuntime(30521): FATAL EXCEPTION: main
01-17 22:01:35.016: E/AndroidRuntime(30521): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.safshari.board3d/com.safshari.board3d.MainActivity}: java.lang.NullPointerException
01-17 22:01:35.016: E/AndroidRuntime(30521): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2247)
01-17 22:01:35.016: E/AndroidRuntime(30521): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2297)
Use
mp = MediaPlayer.create(getActivity(), R.raw.virtualbarber);
If it is fragment instead of this use getActivity().
mediaplayer fixed tnx to you but now im getting nullpointer exception on start of program ?
If its still crashing post the updated relevant code along with stacktrace for further help
Use the uri something like:
Uri myUri = Uri.parse("android.resource://com.package.sample/raw/filename");
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(getApplicationContext(), myUri);
mp.prepare();
I am writing an Android alarm application that uses a Service in order to play the alarm tone. Currently, I am able to get the audio to play, but it plays in a form that can be muted by turning down the device's volume. Thus, I am trying to add a call to setAudioStreamType(AudioManager.STREAM_ALARM); to prevent this.
I have the following for my onStartCommand() function for the service:
MediaPlayer mMP;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
try
{
mMP = MediaPlayer.create(this, R.raw.alarm);
mMP.setAudioStreamType(AudioManager.STREAM_ALARM);
mMP.setLooping(true);
//mMP.prepare(); commented out since prepare() is called in create
}
catch (Exception e)
{
e.printStackTrace();
}
if (mMP != null) mMP.start();
return START_STICKY;
}
My problem is that with the call to setAudioStreamType(), the MediaPlayer never plays the audio. If I comment that line out, the audio plays.
With the line in, I get the following runtime error(s):
04-10 19:32:03.115: E/MediaPlayer(3411): setAudioStream called in state 8
04-10 19:32:03.115: E/MediaPlayer(3411): error (-38, 0)
04-10 19:32:03.115: E/MediaPlayer(3411): start called in state 0
04-10 19:32:03.115: E/MediaPlayer(3411): error (-38, 0)
04-10 19:32:03.115: E/MediaPlayer(3411): Error (-38,0)
04-10 19:32:03.115: E/MediaPlayer(3411): Error (-38,0)
Some research (I can't find the link now) told me that setAudioStreamType() can't be called after prepare() has been called, and that create() implicitly calls prepare().
In any regard, how am I supposed to setAudioStreamType() without such an error?
You can either call mp.reset() and then set the stream type, data source, and then prepare. Alternately just use the default constructor and handle the initialization yourself.
EDIT:
Resources res = getResources();
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.alarm);
mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.setLooping(true);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.start();
Accepted answer was throwing an IllegalStateException. This is working
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(
this,
getCustomToneUri()
);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
I have a game in which a sound plays when a level is completed. Everything works fine to start with but after repeating a level 10 or 20 times the logcat suddenly reports:
"MediaPlayer error (-19,0)" and/or "MediaPlayer start called in state 0" and the sounds are no longer made.
I originally had the all sounds in mp3 format but, after reading that ogg may be more reliable, I converted them all to ogg, but the errors appeared just the same.
Any idea how I can fix this problem?
I was getting the same problem, I solved it by adding the following code to release the player:
mp1 = MediaPlayer.create(sound.this, R.raw.pan1);
mp1.start();
mp1.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
};
});
I think you are not releasing the mediaplayers you are using to play the sound..
You need to release() the media players otherwise the resources are not released , and you soon get out of memory (since you allocate them again next time). so,I think you can play twice or even thrice... but not many times without releasing the resources
MediaPlayer is not a good option when you are playing small sound effects as the user can click on multiple buttons very soon and you will have to create a MP object for all of them which doesnt happen synchronously. That is why you are not hearing sounds for every click. Go for the SoundPool Class which allows you to keep smaller sounds loaded in memory and you can play them any time you want without any lag which you would feel in a mediaplayer. http://developer.android.com/reference/android/media/SoundPool.html Here is a nice tutorial : http://www.anddev.org/using_soundpool_instead_of_mediaplayer-t3115.html
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();
}
});
}
}
This is a very old question, But this came up first in my search results So other people with the same issue will probably come upon this page eventually.
Unlike what some others have said, you can in fact use MediaPlayer for small sounds without using a lot of memory. I'll put in a little modified snippit from my soundboard app to show you what I'm getting at.
private MediaPlayer mp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
mp = new MediaPlayer();
}
private void playSound(int soundID){
mp.reset();
AssetFileDescriptor sound = getResources().openRawResourceFd(soundID);
try {
mp.setDataSource(sound.getFileDescriptor(),sound.getStartOffset(),sound.getLength());
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
with the way I set it up, you create on MediaPlayer object that you reuse everytime you play a sound so that you don't use up too much space.
You call .reset() instead of .release() because .release() is only used if you are disposing of an object, however you want to keep your MediaPlayer Object.
You use an assetfiledescriptor to set a new soundfile for your mediaplayer to play instead of setting a new object to your mediaplayer address because that way you are creating new objects within the method that aren't being handled properly and you will eventually run into the same error as you described.
This is only one of many ways to use MediaPlayer but I personally think it is the most efficient if you are only using it for small sound applications. The only issue with it is that it is relatively restrictive in what you can accomplish, but that shouldn't be much of an issue if you are indeed using it for small sound applications.
i try delete emulator and new create emulator for remove error of (-19,0) media player.
I need to play sound from sd card. I have method that must do this but it's doesn't work.
When I use this method:
public class AudioPlayService extends Service
{
MediaPlayer mMediaPlayer;
..............
public void soundplay(String adr)
{
mMediaPlayer = new MediaPlayer();
try
{
if (mMediaPlayer.isPlaying())
{
mMediaPlayer.reset();
}
mMediaPlayer.setDataSource(adr);
mMediaPlayer.prepare();
} catch (IOException e)
{
}
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mp.release();
mp = null;
}
});
}
Where String adr - it's absolute path to file on sd.
Then I call it:
AudioPlayService s = new AudioPlayService();
s.soundplay(iA.getSdDir() + "Files/Numbers/0.mp3");
and I get an err's:
12-09 13:04:13.829: E/MediaPlayer(16997): error (1, -2147483648)
12-09 13:04:13.829: E/MediaPlayer(16997): start called in state 0
12-09 13:04:13.829: E/MediaPlayer(16997): error (-38, 0)
12-09 13:04:13.839: E/MediaPlayer(16997): Error (-38,0)
I myself tried your code:
Mine worked fine when i put just "sdcard/1.mp3"
You ensure that the path is right or not
s.soundplay(iA.getSdDir() + "Files/Numbers/0.mp3");
Note:
If you are trying to make your method soundplay so as to stop previous audio and play the new audio file, then better would be not to perfom this inside that method
mMediaPlayer = new MediaPlayer();
Place this in constructor.
Otherwise each time you invoke s.soundplay(path) you will hear previous audio plus the new audio. ie,Previous one will not be stopped
player.start() put within try,catch block. Because if player not prepare your song ,still you are calling start method.start method is only called after playback is ready,
means prepare is success.Another thing is that you have to release the media player when your player is no longer.Otherwise there is so many player objects are running in back ground.
For some reason, your setDataSource() or Prepare() is failing. So after the exception, start()is giving the error, since the player is not in Prepared state. Add print statements in the catch block to know what is the exception. And move start() into the try catch block.
mMediaPlayer = new MediaPlayer();
try
{
if (mMediaPlayer.isPlaying())
{
mMediaPlayer.reset();
}
mMediaPlayer.setDataSource(adr);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e)
{
e.printStackTrace();
}
I have followed the steps to create my media player object but I cant understand why it is not playing the music track. I used the following code:
mp = new MediaPlayer();
mp.create(this, R.raw.testmed);
mp.setVolume(100, 100);
mp.start();
but no sound is playing through the emulator, and furthermore when i check the method mp.isPlaying() it returns false. What have I missed?!
Many thanks
You have to call all methods necessary to actually start the player. Take a look at Android Media Player state diagram
I think you need to prepare the player before starting. When the player is prepared, it can be started. This is done through a onPreparedListener:
mp = new MediaPlayer();
mp.create(this, R.raw.testmed);
mp.setVolume(100, 100);
mp.setOnPreparedListener(this);
mp.prepare();
Then you will need to define this and it should work:
public void onPrepared(MediaPlayer player) {
mp.start();
}