I was using SoundPoolto play sound effects but now I need to switch to MediaPlayer as I need to listen to the onCompletion event to trigger a GUI change.
My questions are:
The sound files are very small, less than 30kB, Can I use
MediaPlayer in the main thread?
Can I just call mediaPlayer.stop() after the play is done like so,
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
//Do some GUI changes
mediaPlayer.stop();
mediaPlayer.release();
}
});
Then to play another effect will do this:
mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start();
So, is it ok to create and release every time I play an effect?
Initialize your MediaPlayer
MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
Look at the MediaPlayer lifecycle:
When the track is complete the MediaPlayer is in Stopped state and you wan't to change the track, so:
call reset()' to get toIdlethensetDataSourcethenprepareand finallystart()`.
The sound files are very small, less than 30kB, Can I use MediaPlayer in the main thread?
Irrespective of the size of your audio file, you should run MediaPlayer on its own thread, especially if you are playing a file from network. Not doing so may cause ANR (In your case I don't think much to worry about)
Can I just call mediaPlayer.stop() after the play is done
There is no need to release the MediaPlayer after every audio file. Release it once you are no longer going to use it.
how can I load a new sound
AssetFileDescriptor audio = context.getResources().openRawResourceFd(R.raw.next_audio);
mediaPlayer.setDataSource(audio);
Related
I have an array of audio files and I want to play 3 audio files one after the other, so as the gap in between them is not noticeable.
I am trying it using onCompletion listener but unable to do.
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
// TODO Auto-generated method stub
if ((image100==1)&&(image10==0)&&(image1==1))
{
mediaplayer = MediaPlayer.create(getApplicationContext(), sounds[0]);
mediaplayer.start();
mediaplayer = MediaPlayer.create(getApplicationContext(), sounds[12]);
mediaplayer.start();
mediaplayer = MediaPlayer.create(getApplicationContext(), sounds[3]);
mediaplayer.start();
}
}
You may want to try using the AudioTrack class to play your sounds. With it, you can get very close and even overlapping sounds. To use it, you create separate threads for each sound.
Here's the AudioTrack reference page and here's an easy to follow blog entry where the author implements a piano with arbitrary length and simultaneous sounds. In it, he loops very short duration sounds, but you could easily adapt that to longer, single-play sounds.
If these 3 audio files are short sounds, like game sound effects or piano tones, you can use SoundPool for playing them.
Here is a link to the sample code:
Game Sound effects in Android
In my android application I only play a looping sound with MediaPlayer. I'm trying to loop fluid, eliminating the time between the end of the track and the beginning of the next reading.
I tried with the function setLooping but there is a time between sounds.
I tried with setOnCompletionListener function like this:
MP.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
MP.start();
}
});
However, there are still a few seconds between sounds.
Apparently it is not possible with MediaPlayer; there's an open bug asking for gapless playback that has been open since 2009.
Android: MediaPlayer gapless or seamless Video Playing also has several non-answers on the topic.
In iPhone, we can use AVQueuePlayer, AVAsset, and AVPlayerItem if we want to play a list of movies sequentially. It is very convenient over MPMediaPlayer and MPMediaPlayerController in iPhone. From, apple documentation:
AVQueuePlayer is a subclass of AVPlayer you use to play a number
of items in sequence.
So, my question is, is there anything like that in android which we can use instead of MediaPlayer and VideoView.
In Android, there is no automatic way of playing sounds in sequence (at least not a "built-in" one). If you need to start playback of the second sound when the first one finishes, you can use method
public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener)
of the MediaPlayer to start the second playback when the first one is finished. Something like this:
MediaPlayer player = MediaPlayer.create(context, uriOfFirstSound);
player.setOnCompletionListener(new OnCompletionListener(
public void onCompletion(MediaPlayer mp) {
mp.setDataSource(context, uriOfNextSound);
mp.prepare();
mp.start();
}
));
player.prepare();
player.start();
Naturally, if you have more than two sounds, you can do this in a loop.
I have to play sounds on GUI events, like clicking buttons etc. For this purpose, I call the following native code from WebView:
MediaPlayer _SoundPlayer = new MediaPlayer();
private void playSound(String sound)
{
_SoundPlayer.reset();
try
{
AssetFileDescriptor afd = getAssets().openFd("sound/" + sound + ".mp3");
_SoundPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
_SoundPlayer.prepare();
_SoundPlayer.start();
}
catch (Exception e) { }
}
The problem is there is a delay ~500ms between an event and its sound. Can I optimize playing sound somehow, maybe, creating a dedicated MediaPlayer instances for every kind of sound?
Regards,
Use SoundPool for low-latency media playback, instead of MediaPlayer.
I see that this already has an accepted answer, but I would add that there is no complete solution at this time: Android currently has very large audio latency. Devs are still waiting for a good solution.
This issue refers to the NDK, but the issue is general:
http://code.google.com/p/android/issues/detail?id=3434
I am working on video player in android.when i created surface holder in on create method ,it did not create.but when i created the surface holder in button onclick method,its created
My coding is,
preview=(VideoView)findViewById(R.id.surface);
preview.setEnabled(true);
preview.bringToFront();
holder=preview.getHolder();
holder.setFixedSize(400, 400);
mp=new MediaPlayer();
mp.setDataSource("path");
mp.setDisplay(holder);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnBufferingUpdateListener(playerActivity.this);
mp.setOnPreparedListener(playerActivity.this);
mp.prepare();
mp.start();
mp.prepare();
mp.start();
prepare() is asynchronous, which means, it might not be finished when you already call the mp.start. What do you mean by 'surface not created'? Do you just mean the video doesn't play?
Anyway, you should use an MediaPlayer.OnPreparedListener and start the media in onPrepared().