Android: Playing two sounds one after the other - android

I am trying to play two sound items, one after the other
MediaPlayer mp = null;
protected void produceErrorSound(int index) {
if (mp != null) {
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, index);
mp.start();
}
public void correctAnswerAndNext(){
produceErrorSound(R.raw.right1) ;
produceErrorSound(R.raw.right1) ;
}
but only second sound is produced.
is there any alternative approach?

I can't see any wait mechanism in your code.
You can use an onCompletionListener to receive a callback when your first MediaPlayer has finished playback. At that point you can start the second MediaPlayer.
An alternative way in Jellybean (and later versions) is to use the audio chaining functionality (i.e. setNextMediaPlayer) to automatically start another MediaPlayer as soon as the current one has finished playing. Something like this (I've omitted the calls to setDataSource etc for brevity):
mediaPlayer1.prepare();
mediaPlayer2.prepare();
mediaPlayer1.start();
mediaPlayer1.setNextMediaPlayer(mediaPlayer2);

Related

Which is the best player to use for playing 1 audio sound in a loop?

Currently I am using a mediaplayer to play one single audio file in a loop when a button is clicked( stops playing when a certain event is triggered or onstop). However, I am not sure if mediaplayer is ideal for playing 1 audio sound worth 8-10 seconds set to loop to a max of 30seconds. Is there a better and resource efficient alternative I can use? Any examples would help.
Here's my code so far:
MediaPlayer mp;
onCreate(savedinstance){
....
mp = MediaPlayer.create(getBaseContext(), R.raw.ringbacktone);
mp.setLooping(true);
mp.setVolume(100, 100);
...
}
public void somefunction {
...
case someeventhappens:
mp.start();
break;
...}
#Override
public void onStop() {
super.onStop();
mp.stop();
}
#Override
protected void onDestroy() {
super.onDestroy();
if(mp != null) {
mp.stop();
}
Any idea how I can improve this or use a better resource efficient alternative to best suit my needs of just playing a .wav file ?
Thanks in advance!

Android Media Player Release won't stop playing

Here's my scenario:
I have a timer that counts down from 20 seconds. At 13 seconds, a sound starts playing. At 0 seconds, I stop the current sound, load up a new sound and play that new sound. Once that sounds finishes, I load up the previous sound, set it to loop, and start it.
This is the logic for hitting 0 seconds:
mp.stop();
mp = MediaPlayer.create(mActivity, R.raw.second_sound);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp = MediaPlayer.create(mActivity, R.raw.first_sound);
mp.setLooping(true);
mp.start();
}
});
Once the last sound starts playing, calling mp.release() doesn't stop the player. Any ideas as to how to stop the player?
Note: mp.release() works during the first time I start playing and during the second sound but not during the looping sound.
Solution: My global MediaPlayer is also named "mp". Oops.
You're getting the mp MediaPlayer objects mixed up a little. If mp.release() is being called outside of the onCompletion() method, it is not referring to the looping instance created there. Change the identifiers in onCompletion() to refer to the "outer" mp. For example, if your code is in MainActivity:
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
MainActivity.this.mp = MediaPlayer.create(MainActivity.this, R.raw.chirp);
MainActivity.this.mp.setLooping(true);
MainActivity.this.mp.start();
}
}
);
Why are you creating new media player every time and not releasing old one onCompltion? did you try setDataSource?

MediaPlayer stops working after 30 uses?

I'm trying to write a function to play a short sound (in /res/raw) in my program, called at effectively random times throughout the program. So far I have this function:
public void playSound() {
MediaPlayer mp = new MediaPlayer();
mp = MediaPlayer.create(this, R.raw.ShortBeep);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(false);
mp.start();
}
It works fine for awhile, but after exactly 30 plays of the sound, it stops making sound.
According to the Docs
... failure to call release() may cause subsequent instances of MediaPlayer objects to fallback to software implementations or fail altogether.
When you are done with it call mp.release() so that it can release the resources. I don't know what the limit is and I'm sure it depends on many factors. Either way you should be calling this function on your MediaPlayer object, especially if it will be used more than once.
I've just solved the exact same problem, but I'm using Xamarin. I ended up changing from holding on to a MediaPlayer instance for the lifetime of the activity to creating an instance each time I want to play a sound. I also implemented the IOnPreparedListener and IOnCompletionListener.
Hopefully you can get the idea despite it being C# code
public class ScanBarcodeView :
MvxActivity,
MediaPlayer.IOnPreparedListener,
MediaPlayer.IOnCompletionListener
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.ScanBarcodeView);
((ScanBarcodeViewModel) ViewModel).BarcodeScanFailed += (sender, args) => PlaySound(Resource.Raw.fail);
((ScanBarcodeViewModel) ViewModel).DuplicateScan += (sender, args) => PlaySound(Resource.Raw.tryagain);
}
private void PlaySound(int resource)
{
var mp = new MediaPlayer();
mp.SetDataSource(ApplicationContext, Android.Net.Uri.Parse($"android.resource://com.company.appname/{resource}"));
mp.SetOnPreparedListener(this);
mp.SetOnCompletionListener(this);
mp.PrepareAsync();
}
public void OnPrepared(MediaPlayer mp)
{
mp.Start();
}
public void OnCompletion(MediaPlayer mp)
{
mp.Release();
}
}
So, each time I want a sound to be played I create a MediaPlayer instance, so the data source, tell it that my Activity is the listener to Prepared and Completion events and prepare it. Since I'm using PrepareAsync I don't block the UI thread. When the media player is prepared the Start method on the MediaPlayer is called, and when the sound has finished playing the MediaPlayer object is released.
Before I made these changes I would get to 30 sounds played and it would all stop working. Now I've gone way past 30, also multiple sounds can be played simultaneously.
Hope that helps.

How to play a Sound Effect in Android

I'm looking to do a very simple piece of code that plays a sound effect. So far I have this code:
SoundManager snd;
int combo;
private void soundSetup() {
// Create an instance of the sound manger
snd = new SoundManager(getApplicationContext());
// Set volume rocker mode to media volume
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the samples from res/raw
combo = snd.load(R.raw.combo);
}
private void playSound() {
soundSetup();
snd.play(combo);
}
However, for some reason when I use the playSound() method, nothing happens. The audio file is in the correct location.
Is there a specific reason you are using SoundManager? I would use MediaPlayer instead, here is a link to the Android Docs
http://developer.android.com/reference/android/media/MediaPlayer.html
then it's as simple as
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.combo);
mp.start();
Make a directory called "raw/" under the "res/" directory. Drag wav or mp3 files into the raw/ directory. Play them from anywhere as above.
i have also attempted using the top answer, yet it resulted in NullPointerExceptions from the MediaPlayer when i tried playing a sound many times in a row, so I extended the code a bit.
FXPlayer is my global MediaPlayer.
public void playSound(int _id)
{
if(FXPlayer != null)
{
FXPlayer.stop();
FXPlayer.release();
}
FXPlayer = MediaPlayer.create(this, _id);
if(FXPlayer != null)
FXPlayer.start();
}

Mediaplayer error (-19,0) after repeated plays

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.

Categories

Resources