I am trying to find out how to use the android's MediaPlayer method setNextMediaPlayer which should smoothly transition from one player (song) to another. But do not know how to use the method since there is a lack of documentation.
This is what i do and it does not work:
final MediaPlayer mp1 = new MediaPlayer();
final MediaPlayer mp2 = new MediaPlayer();
try {
mp1.setDataSource("http://song1.MP3");
mp2.setDataSource("http://song2.mp3");
mp1.prepareAsync();
mp1.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp1.start();
}
});
mp1.setNextMediaPlayer(mp2);
mp1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp2.prepareAsync();
mp2.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp2.start();
}
});
}
});
} catch (IllegalArgumentException e) {}
So the first song plays. But after it finishes the second does not start.
Got it to work.
mp1.setDataSource(song1);
mp1.prepareAsync();
mp1.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp1.start();
}
});
//mp1.start();
//mp1.seekTo(1000*100);
mp2.setDataSource(song2);
mp2.prepare();
mp1.setNextMediaPlayer(mp2);
The only problem is that the second mediaplayer cannot be called as async (i.e. mp2.prepareAsync()). I do not know why, but if you try it like that it does not start, which is a bad thing :/.
MediaPlayer setNextMediaPlayer gives a lot of problem what i do is this:
in the onCompletion() reset() the mediaplayer, setDataSource() and prepareAsync().
Something like this
mp1.setDataSource("http://song1.MP3");
mp1.prepareAsync();
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp1.start();
}
});
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp1.reset();
//ADD FLAG FOR STOP
try {
mp1.setDataSource("http://song2.mp3");
} catch (IOException e) {
e.printStackTrace();
}
mp1.prepareAsync();
}
});
Then in the onCompletion you need some flag to check if the last song was played to stop, because the code as i posted will loop in the last song.
Related
i am making a phone dialer app that play the sound when you press on button the app is working great but after a while i get a random crash because on prepared listener i do not know what is happening and this is the error
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.setOnPreparedListener(android.media.MediaPlayer$OnPreparedListener)' on a null object reference
at com.alper.pola.andoid.phonedailer.MainActivity$1.onTouch(MainActivity.java:258)
and this is how i cast the media player
if (mLastButton == one) {
MediaPlayer mediaPlayer ;
mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.one);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp1.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp1.release();
}
});
}
if (mLastButton == two) {
MediaPlayer mediaPlayer ;
mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.two);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp2.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp2.release();
}
});
}
if (mLastButton == three) {
MediaPlayer mediaPlayer ;
mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.three);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp3.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp3.release();
}
});
}
if (mLastButton == four) {
MediaPlayer mediaPlayer ;
mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.four);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp4.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp4.release();
}
});
}
the app is working fine and the same button when i click on it is working but after while the button stop working and i get this crash with every button it start with working fine but after i type a few numbers the app crash
You are using a very inefficient way while dealing with MediaPlayer. Still I'll help you a workaround with this code. Use mediaPlayer.prepare() to initiate the call. Checkout this code:
if (mLastButton == one) {
mp1 = MediaPlayer.create(MainActivity.this,R.raw.one);
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp1.start();
});
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp1.release();
}
});
mp1.prepare();
}
Do similarly for others. There are much better way to do this but as with your code, this is shortest.
I am having a listview in my app. Each listview item has button which will play an audio from a url received from web service. But my problem is that if I click play button from the next item then both start playing together. I am having problem in this. I want only one to play at a time. Right now I am creating new Media player object everytime button is clicked, but I also tried creating a single global object but in this case it only plays first time and not after it. What is the possible solution of it.
finalHolder.iv_sound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(birdsUrlList.get(position).getUrl_audio());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
//startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(birdsUrlList.get(position).getUrl_video())));
} catch (Exception e) {
e.printStackTrace();
}
}
});
Make the mp variable global and remove this:
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
because if you take a look at this reference http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram it says:
Once the MediaPlayer object is in the End state, it can no longer be
used and there is no way to bring it back to any other state.
And when you call mp.release(); the media player WILL go to that state.
Then make your onClickListener look something like this:
#Override
public void onClick(View v) {
try {
if (mp.isPlaying()) {
mp.stop();
mp.reset();
}
mp.setDataSource(birdsUrlList.get(position).getUrl_audio());
//... and so on
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.reset();
}
});
The trick there is to make it back to Idle state so you can set the new data source and start playing again. It's all about the states...
I'm testing Android sound implementation. I have an "imagenButton" and when I push it, a method "musica()" is called. Is really simple:
public void musica(View v) {
img = (ImageView) findViewById(R.id.Migrunido);
if(m.isPlaying()) {
m.stop();
}
else {
m.start();
}
}
It works, but want when I press the button, the sound repeats. I was reading a lot about threads and I have to prepare it before "stop()" but can't fix it.
I have to prepare my method? Or what is the problem?
Thanks
try
public static void playAudio(int id) {
mediaPlayer = MediaPlayer.create(context,id);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.release();
}
});
}else{
mediaPlayer.stop();
mediaPlayer.release();
}
}
if this doesn't work try mediaPlayer.prepare(); before you start.
For example, I want to play 3 songs. When the 1st song ends, the 2nd song begins, and when the 2nd song ends, the 3rd song begins, and when the 3rd song ends, the 1st song begins again and so on. Is the mp.setOnCompletionListener used here?
You are right. You can do something simple like this:
public class MainActivity extends Activity {
MediaPlayer mp1, mp2, mp3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mp1 = MediaPlayer.create(this, R.raw.music_1);
mp2 = MediaPlayer.create(this, R.raw.music_2);
mp3 = MediaPlayer.create(this, R.raw.music_3);
mp1.start();
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp2.start();
}
});
mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp3.start();
}
});
mp3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp1.start();
}
});
}
}
This will play mp1 and onCompletion of it, it will play mp2, and onCompletion of mp2, it will play mp3, and onCompletion of mp3, it will play mp1 again and so on...
First declare the 3 MediaPlayer files:
MediaPlayer song1;
MediaPlayer song2;
MediaPlayer song3;
Then initialize the MediaPlayer objects:
song1 = MediaPlayer.create(this, R.raw.exampleSong1);
song2 = MediaPlayer.create(this, R.raw.exampleSong2);
song3 = MediaPlayer.create(this, R.raw.exampleSong3);
Now start the first Media file with
song1.start();
Now with every instance created you should add to every MediaPlayer object a setOnCompletionListener like this:
song1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
song2.start();
}
});
Do the same for the Second and Third MediaPlayer files:
song2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
song3.start();
}
});
song3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
song1.start();
}
});
I've implemented a MediaPlayer using the following code but it's never calling onCompletion. I'm streaming mp3 from my LAN. Any idea what's wrong?
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
mMediaPlayer.start();
}
});
mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
// Nothing here gets executed
mMediaPlayer.start();
}
});
mMediaPlayer.reset();
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepareAsync();