I'm trying to use one MediaPlayer to play a number of songs in succession. The first song will play as needed, but afterwards, one particular song (the first song in alphabetic order) will play over and over again. I followed this: Android Mediaplayer play different songs after eachother
public void startPlayer(View view) {
game = new Game();
TextView textView = (TextView) findViewById(R.id.title);
// start first song
Music firstSong = game.getNextSong();
textView.setText(firstSong.getID());
mediaPlayer = MediaPlayer.create(view.getContext(), firstSong.getID());
// make sure rest of songs play
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
goToNextSong();
}
});
// actually start!
mediaPlayer.start();
}
public void goToNextSong() {
Music nextSong = game.getNextSong();
TextView textView = (TextView) findViewById(R.id.title);
// if we still have music to play
if (nextSong != null) {
try {
// set the new title
textView.setText(nextSong.getID());
mediaPlayer.stop();
mediaPlayer.reset();
// get the music file
FileDescriptor fd = getResources().openRawResourceFd(
nextSong.getID()).getFileDescriptor();
mediaPlayer.setDataSource(fd);
// play it!
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Even when I set fd to a particular song, it will still play the first song in alphabetical order. nextSong.getID() returns R.raw.somesong. The textview (which is set to the song ID) changes to the correct song. Help?
So I haven't found a way to keep the same MediaPlayer and play different songs, so I just made a new one each time. It works!
public void startPlayer() {
game = new Game();
goToNextSong();
}
public void goToNextSong() {
Music nextSong = game.getNextSong();
TextView textView = (TextView) findViewById(R.id.title);
// if we still have music to play
if (nextSong != null) {
try {
// set the new title
textView.setText(nextSong.getID());
// stop old music player
if (mediaPlayer != null) {
mediaPlayer.stop();
}
// create new music player
mediaPlayer = MediaPlayer.create(textView.getContext(),
nextSong.getID());
// make sure rest of songs play
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
goToNextSong();
}
});
// actually start!
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
} else {
// we're done!
mediaPlayer.release();
mediaPlayer = null;
}
}
Related
I have been able to play audio from my firebase storage and i want the song to stop and start when a user clicks on same button but i haven't been able to get get the right code for that.
this is what i have tried
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}else {
mediaPlayer.stop();
}
}
});
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
The above code is correct, now do one thing create button listener and write below code
button.setOnClickListener(view.onCLickListeners(){
#override
public void onClick(){
if (!mediaPlayer.isPlaying()) {
mediaPlayer.play();
}
else {
mediaPlayer.pause();
}
}});
And please define mediaplayer globally.
I am getting list of mp3 files(as a ArrayList(Path)) from local by choosing one by one but I could not able to make them to play one by one play if finished move to next and if finished all list loop again. any help?
I solved issue thansk to : http://www.helloandroid.com/tutorials/musicdroid-audio-player-part-i
ofcourse I did a little bit modification, like:
private void playSong() {
try {
mp.reset();
mp.setDataSource(playlist.get(currentPosition));
mp.prepare();
mp.start();
// Setup listener so next song starts automatically
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
nextSong();
}
});
} catch (IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
private void nextSong() {
if (++currentPosition >= playlist.size()) {
// Last song, just reset currentPosition
currentPosition = 0;
} else {
// Play next song
playSong(/*MEDIA_PATH + playlist.get(currentPosition)*/);
}
}
I have a application in which when i select any item then it will play that media file but when i select other item then the old media is playing continue and the current media file is overlay(current file is also playing) so i am listen both media files.
I have written below code:
ImageView songView;
Gallery songGallery;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song_test);
songView = (ImageView) findViewById(R.id.songView);
songGallery = (Gallery) findViewById(R.id.songGallery);
songGallery.setAdapter(new MyGalleryAdapter(getApplicationContext()));
songGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View arg1,
int arg2, long id) {
// TODO Auto-generated method stub
songView.setImageResource(symbolIds[arg2]);
String imageName = getResources().getResourceEntryName(
symbolIds[arg2]);
Uri audio = Uri.parse("android.resource://" + getPackageName()
+ "/raw/" + imageName + "");
mp = MediaPlayer.create(getApplicationContext(), audio);
try {
if (mp.isPlaying()) {
mp.reset();
}
mp.start();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Error", Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
}
....
....
}
}
So my question is - When i select the item the song is playing very well but when i select other item then the old song is also playing with the current.
so i want to stop the old song...
I want to play only current selected item song.
The issue is that MediaPlayer is being recreated instead of being reset. Rather than using the #create() factory call, you can use the constructor instead. In the following code, if the mp is already created it is reset and then a datasource is prepared and started.
if (mp != null) {
mp.reset();
} else {
mp = new MediaPlayer();
}
// Now set the datasource
mp.setDataSource(context, audio);
mp...
mp.prepare();
mp.start();
Ideally though you should call prepareAsync and have a callback onPrepare() call the actual mediaPlayer.start so that prepare does not block the main thread.
mp.setOnPreparedListener(this);
mp.setDataSource(..)
mp.prepareAsync();
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
Make the MediaPlayer mp global variable private static. Better yet use Singleton instead of global
You could review the state diagram here
then review an implementation of that logic for recycle media player in the
media sample you can find in your SDK installation:
$SDK/.../src/com/android/sample/apis/media/MediaPlayerDemo_Video.java
and follow how the sample resets the player state before using it again
I am building an app which plays several videos, and I have two different user scenarios :
Scenario 1. While video 'A' is playing, if user clicks next button, then it stops and play the next video 'B'.
Scenario 2. Play video 'A', and if it's done, user clicks next button and it plays video 'B'.
For the first scenario, I used mediaPlayer.isPlaying() method to detect if it is in Started state and it works fine. However, if I use the same code for the second scenario, isPlaying() throws IllegalStateException.
Here's my code for playing videos :
private void playVideos(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(holder);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + video_files[mCounter]);
mediaPlayer.setDataSource(this, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
} catch (IOException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalStateException e) {
}
}
Also, here's my button listener to play next video :
nextBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mediaPlayer != null) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
mCounter += 1;
if (mCounter <= 8) {
playVideos(holder);
}
}
});
One way that I tried to hack this issue was using a boolean variable instead of isPlaying() method. For example,
boolean mIsPlaying = false;
...
// in button listener
if(mIsPlaying) {
mediaPlayer.stop();
mediaPlayer.release();
}
...
// in playVideos() function
mediaPlayer.start();
mIsPlaying = true;
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
That works for my both of scenario, but I'm not sure if it's the correct way to do it. Isn't there any way to detect whether mediaPlayer is in Stopped state?
I took a look at Google's Documentation which you can find here. You can only know if the player isPlaying(); or isLooping(); ... So no, there is not an "easy" or "short" way to achieve what you want. Hope it helped.
I m making an app which is supposed to play a few sounds with the mediaPlayer.
This is the code i use :
String[] name = {"sonar_slow","sonar_medium","sonar_fast"};
String link = "/res/raw/" + name[state-1] + ".mp3";
try {
player.setDataSource(link);
player.prepare();
player.start();
} catch(Exception e) {
e.printStackTrace();
}
I also tried this :
if(state==1){
player.create(this, R.raw.sonar_slow);
}else if(state==2){
player.create(this, R.raw.sonar_medium);
}else if(state==3){
player.create(this, R.raw.sonar_fast);
}
player.start();
But none of the above is working. My app is not crashing but the sound is not playing.
Any ideas ?
There are two problems.
Problem 1
You cannot reference resources inside your projects /res/raw directory in this fashion. The file "/res/raw/sonar_slow.mp3" in your project directory is not stored in "/res/raw/sonar_slow.mp3" in your apk. Instead of the following:
MediaPlayer mp = MediaPlayer.create(this);
mp.setSource("sonar_slow");
You need to use
MediaPlayer mp = MediaPlayer.create(this, R.raw.sonar_slow);
Problem 2
The following is wrong: it calls a static method that does not modify the player.
player.create(this, R.raw.sonar_slow);
You should instead call
player = MediaPlayer.create(this, R.raw.sonar_slow);
Full solution
Below is a reusable AudioPlayer class that encapsulates MediaPlayer. This is slightly modified from "Android Programming: The Big Nerd Ranch Guide". It makes sure to remember to clean up resources
package com.example.hellomoon;
import android.content.Context;
import android.media.MediaPlayer;
public class AudioPlayer {
private MediaPlayer mMediaPlayer;
public void stop() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void play(Context c, int rid) {
stop();
mMediaPlayer = MediaPlayer.create(c, rid);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
stop();
}
});
mMediaPlayer.start();
}
}
How to play a file with MediaPlayer:
MediaPlayer mp = MediaPlayer.create(this, R.raw.mysound); // sound is inside res/raw/mysound
mp.start();
This is a simple example of how to play a sound with the Android MediaPlayer.
You have two buttons hat each play a different sound. The selecting of the sound and actually playing it is done in the manageSound() method. The sounds "hello", "goodbye" and "what" are in the res/raw directory:
MediaPlayer mp = null;
String hello = "Hello!";
String goodbye = "GoodBye!";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button buttonHello = (Button) findViewById(R.id.idHello);
buttonHello.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(hello);
} // END onClick()
}); // END buttonHello
final Button buttonGoodBye = (Button) findViewById(R.id.idGoodBye);
buttonGoodBye.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(goodbye);
} // END onClick()
}); // END buttonGoodBye
} // END onCreate()
protected void manageSound(String theText) {
if (mp != null) {
mp.reset();
mp.release();
}
if (theText.equals(hello))
mp = MediaPlayer.create(this, R.raw.hello);
else if (theText.equals(goodbye))
mp = MediaPlayer.create(this, R.raw.goodbye);
else
mp = MediaPlayer.create(this, R.raw.what);
mp.start();
}
Taken from here: http://www.badprog.com/android-mediaplayer-example-of-playing-sounds
Furthermore, I would strongly recommend using SoundPool instead of MediaPlayer, for better Performance and usability.
http://developer.android.com/reference/android/media/SoundPool.html
Please also check if your sound is muted - I know this sounds stupid, but it happens to the best of us ;)
You need to do it like this :
try{
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
Make sure your only playing when the file has finished preparing.