I want to play mp3 file from res/raw folder when user click on button
my code is below:
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
MediaPlayer mp = MediaPlayer.create(MainActivity.this,
R.raw.click);
mp.start();
}
});
Work well but take some time to play after button click. please, anyone, give me a solution.
Thanks
Loading time depends on the buffer size of the MediaPlayer (which is hardcoded in the firmware) and that there is nothing that can be done to change it. Read more here.
Option 1:
Instead of creating the media player and then calling start() method in the onClick of the button, you can initialize the mediaPlayer in onCreate() of activity.
As for the button click implementation, you need to call mediaPlayer.start() only.
Option 2:
You can use SoundPool API provided by Android. This has lower latency compared to MediaPlayer API. SoundPool are recommended mainly for playing short clips.
This is as a result of the buffer size of media player.
Try using SoundPool for a more responsive playback. You can see an implementation of it here.
SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100);
HashMap<Integer, Integer> soundPoolMap soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(soundID, soundPool.load(this, R.raw.click, 1));
Start the sound with soundPool.play(soundId, 1, 1, 1, 0, 0);
Related
I have several GridView items that play a small .ogg file when they are selected. They are played using the SoundPool class, however this class seems very intermittent - sometimes the sound plays, sometimes it doesn't; there is no pattern to this so I am having trouble figuring out why it's doing it.
Here is my code:
public void playSelectionSound(){
SoundPool sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
int soundId = sp.load(this, R.raw.char_select, 1);
sp.play(soundId, 1, 1, 0, 0, 1);
}
I eventually resorted to switching to MediaPlayer instead of SoundPool:
MediaPlayer mp = MediaPlayer.create(this, R.raw.char_select); //open media player
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.start(); //play the sound
Works everytime.
You shouldn't try to play it immediately after the load since the load can take time. Instead, you should use SoundPool.OnLoadCompleteListener() and play it in that callback. Here you can be sure that soundpool has loaded successfully.
I've started messing about with Android recently. I'm trying to kick something off once a sound has finished and return to the previous activity.
spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
int soundID = spool.load(this, card.getSound(), 1);
spool.play(soundID, 500, 500, 1, 0, 1f);
I can't see anything about getting the sound duration or any sort of sound end event. I know SoundPool can be a pain so I'm willing to ditch it.
How can I do something after a sound has ended? Can I do this with SoundPool or am I barking up the wrong tree?
Thanks. I'm pretty new to Android and Java so open to all suggestions.
If the multi-stream handling functionality of SoundPool isn't necessary, you can use MediaPlayer, which does have the callbacks you're asking about.
A rough example:
MediaPlayer mp = MediaPlayer.create(Activity.this, soundId);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// do something
}
});
mp.start();
Just make sure that you hang onto the MediaPlayer reference somewhere so that it doesn't get GC'd before your OnCompletionListener fires :)
I am having a bit of difficulty with my SoundPool. I have an ArrayList<Integer> of my soundIDs located in my res/raw folder. I'm creating the SoundPool like so in my ViewHolder class for my RecyclerView:
//create the SoundPool
sp = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
//create the AudioManager for managing volume
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
//store the streamVolume in an int
streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
//set the load listener for my soundfiles
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
loaded = true;
}
});
I am playing the sound on the click of an ImageView like so:
#Override
public void onClick(View v) {
if (v.equals(cardImg)) {
sp.load(context, cardData.getSoundId(), 1);
if (loaded) {
sp.play(cardData.getSoundId(), streamVolume, streamVolume, 1, 0, 1f);
}
}
}
And every time I click on the cardImg it gives me this error:
W/SoundPool﹕ sample 2130968609 not READY
Where the sample int changes depending on which card I click, like it should.
So I know that it's GETTING the proper soundID from my ArrayList (stored in CardData class), and it definitely sees that it's loaded, because it wouldn't try to play otherwise because loaded would never be true. My question is: Why are my sounds never ready?
My sounds are .m4a format which Android says is supported in the documentation. I've tried on an Android 5.0 device and an Android 4.4 device but nothing changes.
I have tried using a MediaPlayer but I am running into memory errors as I have many short clips that need to be able to be spammed and I read that a SoundPool was a much better way to manage this (?).
Any help would be appreciated! I am super vexxed here.
You're using the wrong id. SoundPool.load returns an id that is suppose to be passed in to SoundPool.play.
I have a class that extends Service, where i have a MediaPlayer that manages the background music of my app.
MediaPlayer player = MediaPlayer.create(this, R.raw.background_music);
player.setLooping(true);
The problem is that it doens't "loop" well: I mean, when the mp3 file ends, there's a second of silence before it starts again.
But, in the mp3 file, actually, there's not any second of silence.
How can i solve this problem?
You can't. This bug has been there for ages now, but they still didn't fix it and it does not look like they are going to do it in the close future!
http://code.google.com/p/android/issues/detail?id=18756
You can try to use SoundPool to play your audio file (it loops very well and without delay, however might be inappropriate for some audio resources).
Here is some kind of implementation (deprecation removal and appropriate closing of resource is left as a homework :))
SoundPool pool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
afd = getResources().openRawResourceFd(audioResource);
pool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (0 == status) {
soundPool.play(sampleId, 1f, 1f, 10, -1 /* looping parameter */, 1f);
}
}
});
pool.load(afd, 10);
afd.close();
From other side if MediaPlayer is a must have you might look into method setNextMediaPlayer. So the idea is to initialize several MediaPlayers for the same file (what a mess) and set them in a smart way.
I need to have the same short wav file (1 second) play each time the user presses a single button. I have the following code that works for about 30 clicks and then the app "Force closes" on the device. I think what is going on is that new instances of media player are being created and then the instances build up (approx 30 clicks) and the app crashes. So I then added the "release" instance in the hope that on button-click the wav would play and then the mediaplayer would be released. However, it doesnt work that way. With the mp.release() no sound is played possibly becaue the medaiplayer gets released too soon for the user to hear the sound?
Anyone have a good tip to help me getting this to work? Thank you all so much.
Button button2 = (Button) findViewById(R.id.button10);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
mp.release();
Its simple just create the MediaPlayer once, and play it over time.
private MediaPlayer mp;
public void onClick(View v) {
// Perform action on click
if (mp == null){
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
}
mp.start();
}
Why use MediaPlayer, when SoundPool is better suited for small audio files? As a base you could use this:
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 70);
final HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>();
final int soundID = 4;
soundPoolMap.put(soundID, soundPool.load(this, R.raw.wav_sound, 4));
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener()
{
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
{
if (sampleId == 4)
{
soundPool.play(4, 50, 50, 1, 0, 1f);
}
}
});
Here is the simple solution that will work
MediaPlayer mp;
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
public void onClick(View v) {
// Perform action on click
if(mp.isPlaying())
{
mp.stop();
mp.reset();
mp.release();
}
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
This is will check if mediaplayer is already playing..If it already playing it will stop and release it and then initialize that mediaplayer(mp) object and start the mediaplayer.
If it is not playing it will execute the code after the if statement and the start the media player after initialzing the mediaplayer object(mp in this case)
To learn more about MediaPlayer study this http://developer.android.com/reference/android/media/MediaPlayer.html. Study the Mediaplayer life cycle