Playing .wav file using MediaPlayer class. As I need to loop the Audio I've set .setLooping(true); . So obviously, the doubt is how do I add a delay each time the audio plays, say I want a delay of 5000 .
The answers to similar questions here doesn't work in my case. Any help would be appreciated. Here is my code:
Button Sample = (Button)findViewById(R.id.samplex);
Sample.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String filePath = Environment.getExternalStorageDirectory()+"/myAppCache/wakeUp.wav";
try {
mp.setDataSource(filePath);
mp.prepare();
mp.setLooping(true);
}
catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
});
You need to register 2 listeners (on completion and on error) and then you would need to delay next play in on completion callback. Reason for the error listener is to return true to avoid calling on completion event whenever there is an error - explanation here
private final Runnable loopingRunnable = new Runnable() {
#Override
public void run() {
if (mp != null) {
if (mp.isPlaying() {
mp.stop();
}
mp.start();
}
}
}
mp.setDataSource(filePath);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
button.postDelayed(loopingRunnable, 5000);
}
});
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
...
return true;
});
mp.prepare();
// no need to loop it since on completion event takes care of this
// mp.setLooping(true);
Whenever your destruction method is (Activity.onDestroyed(), Fragment.onDestroy(), View.onDetachedFromWindow()), ensure you are removing the runnable callbacks, e.g.
#Override
protected void onDestroy() {
super.onDestroy();
...
button.removeCallbacks(loopingRunnable);
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
mp = null;
}
}
Related
in my simple player i have play, and stop buttons and play and pause media player work fine, now after click on stop and play again, media player don't work and i'm not sure whats problem to resolve that
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
playMonthLesson();
...
}
#SuppressLint("DefaultLocale")
public void playMonthLesson() {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(CoreApplication.MEDIAFOLDER + "/" + lesson.getFilename());
mediaPlayer.prepare();
mediaPlayer.start();
lesson_play.setImageResource(R.drawable.ic_pause);
int totalDuration = mediaPlayer.getDuration();
// set Progress bar values
lesson_progress_bar.setProgress(curretLessonProgress);
lesson_progress_bar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#OnClick(R.id.lesson_play)
public void lesson_play(View view) {
if (mediaPlayer == null) {
playMonthLesson();
} else if (mediaPlayer.isPlaying()) {
if (mediaPlayer != null) {
mediaPlayer.pause();
// Changing button image to play button
lesson_play.setImageResource(R.drawable.ic_play);
}
} else {
// Resume song
if (mediaPlayer != null) {
mediaPlayer.start();
// Changing button image to pause button
lesson_play.setImageResource(R.drawable.ic_pause);
}
}
}
#OnClick(R.id.lesson_stop)
public void setLesson_stop(View view) {
if (mediaPlayer != null) {
mediaPlayer.stop();
lesson_play.setImageResource(R.drawable.ic_play);
lesson_progress_bar.setProgress(0);
}
}
According to the MediaPlayer life cycle, which you can view in the Android API guide, I think that you have to call reset() instead of stop(), and after that prepare again the media player (use only one) to play the sound from the beginning. Take also into account that the sound may have finished. So I would also recommend to implement setOnCompletionListener() to make sure that if you try to play again the sound it doesn't fail.
The problem is that when you stop mediaplayer and click on play again your call will go to mediaplayer.play() as mediaplayer is not null.
You will have to null the mediaPlayer on stop method. Now, once you stop mediaplayer and again click on play it will call playMonthLesson();
#OnClick(R.id.lesson_stop)
public void setLesson_stop(View view) {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer = null;
lesson_play.setImageResource(R.drawable.ic_play);
lesson_progress_bar.setProgress(0);
}
}
change this code too,
#SuppressLint("DefaultLocale")
public void playMonthLesson() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(CoreApplication.MEDIAFOLDER + "/" + lesson.getFilename());
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
lesson_play.setImageResource(R.drawable.ic_pause);
int totalDuration = mediaPlayer.getDuration();
}
});
mediaPlayer.prepareAsync();
// set Progress bar values
lesson_progress_bar.setProgress(curretLessonProgress);
lesson_progress_bar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
i've created a playlist based on Media Player class. The thing is that it succeed in reading some mp3 url and it doesn't for another ones.
For example here is a directory of mp3 i've uploaded but no one is working:
http://rajaapp12.0fees.us/gbv3/
in the other hands an mp3 which work:
http://mp3.mp3zik.com/music/Music-Rap/Casa%20Verde%202009/track%20(14).mp3
I don't think there is a problem with the code since it works already witch some url, but here is the most iportant part of it :
public void beginLrcPlay(){
killMediaPlayer();
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(songEnCours.getSource_128());
mPlayer.setLooping(true);
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
if (mTimer == null) {
mTimer = new Timer();
mTask = new LrcTask();
mTimer.scheduleAtFixedRate(mTask, 0, mPalyTimerDuration);
}
}
});
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
//fin musique ajouter action !
stopLrcPlay();
chantSuivant();
btnPlay.setImageResource(R.drawable.bg_selector_btn_play);
}
});
mPlayer.setOnBufferingUpdateListener(onBufferingUpdateListener);
mPlayer.prepare();
mPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Making an app and streaming audio from site. I've got a menu and when I click the button to open the radio activity it can take from 8-20 seconds to load and sometimes force closes. Any help would be awesome thanks.
Code:
public class Radio extends Activity {
private MediaPlayer mp;
private ImageButton pauseicon;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_1);
pauseicon = (ImageButton) findViewById(R.id.pauseicon);
getActionBar().setDisplayHomeAsUpEnabled(true);
/**
* Play button click event plays a song and changes button to pause
* image pauses a song and changes button to play image
* */
String res = "http://216.235.91.36/play?s=magic24point7&d=LIVE365&r=0&membername=&session=magic24point7:0&AuthType=NORMAL&app_id=live365%3ABROWSER&SaneID=24.79.96.172-13316781890137014897763&tag=live365";
mp = new MediaPlayer();
try {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(res);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
}
pauseicon.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// No need to check if it is pauseicon
if (mp.isPlaying()) {
mp.pause();
((ImageButton) v).setImageResource(R.drawable.playicon);
} else {
mp.start();
((ImageButton) v).setImageResource(R.drawable.pauseicon);
}
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
if (mp != null)
if (mp.isPlaying())
mp.stop();
mp.release();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
if (mp != null) {
if (mp.isPlaying())
mp.stop();
mp.release();
}
// there is no reason to call super.finish(); here
// call super.onBackPressed(); and it will finish that activity for you
super.onBackPressed();
}
}
Use prepareAsync() and setOnPreparedListener() instead of prepare(). prepare() blocks the UI thread until it returns and is not recommended for a stream. This may be the cause your crash.
mp = new MediaPlayer();
try {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(res);
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
mp.start();
}
});
mp.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
}
http://developer.android.com/reference/android/media/MediaPlayer.html#prepare()
Prepares the player for playback, synchronously. After setting the datasource and the display surface, you need to either call prepare() or prepareAsync(). For files, it is OK to call prepare(), which blocks until MediaPlayer is ready for playback.
Otherwise I think the network is your bottleneck. The fastest way to speed things up is to ensure your server/client communication is quick. There doesn't seem to be anything inherently slow about your code.
My media player for some reason completes while it is paused. Now i have seen another post that said about it being async and 300ms difference and that I understand. But my main problem is that i have 20 seconds left on the video and while paused it finishes after the 20 seconds run out.
here is the relevant code that I might have messed up on:
private void initPlayer()
{
try {
if(videoFile != null)
{
afd = getAssets().openFd(videoFile);
instructionVideoPlayer = new MediaPlayer();
instructionVideoPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
instructionVideoPlayer.setDisplay(holder);
instructionVideoPlayer.prepare();
Log.i("Instruction Video", "videoPrepared");
instructionVideoPlayer.setOnCompletionListener(instructionVideoComplete);
instructionVideoPlayer.setOnPreparedListener(this);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
Log.i(this.toString(), "IOEXception");
e.printStackTrace();
//initPlayer();
} catch (Exception e)
{
Log.i("InitPlayer", e.getClass().toString());
e.printStackTrace();
}
restoreOverlayState();
}
The listeners:
MediaPlayer.OnCompletionListener instructionVideoComplete = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
Log.i("onCompletion", "called");
if(!videoFile.contentEquals(LangSelect.INSTRUCTION_05))
{
Intent returnIntent = new Intent();
returnIntent.putExtra(LangSelect.ACTION, LangSelect.GO_VIDEO_NEXT);
setResult(RESULT_OK, returnIntent);
continuePlaying = true;
toFinish();
}
else
toFinish();
}
};
public void onPrepared(MediaPlayer mediaPlayer)
{
playVideo();
}
the play and pause functions
private void playVideo()
{
instructionVideoPlayer.seekTo(pausedAt);
instructionVideoPlayer.start();
restoreOverlayState();
}
private void pauseVideo()
{
pausedAt = instructionVideoPlayer.getCurrentPosition();
instructionVideoPlayer.pause();
}
private void restoreOverlayState()
{
prefs = getSharedPreferences(SAVE_PREFS, Context.MODE_PRIVATE);
if(prefs.getBoolean(IS_PAUSED, false))
{
pauseOverlay.setVisibility(View.VISIBLE);
pauseVideo();
}
else
{
pauseOverlay.setVisibility(View.GONE);
}
}
Edit: this only happens on the Nexus S (2.3.3) one of the phones I am testing on. The other Galaxy S(Froyo) does not have this error.
I figured out what I was doing Wrong. the OnCompletionListener was being called. The problem was I was running 2 media players and setting the same onCompletionlistener to them accidentally as I was calling initPlayer twice. Once in surfaceCreated and again at the end of onResume(). Either the Galaxy S is messed up or it has weird error checking becasue this problem didnt show up there.
In the application I am currently writing, a user is able to select an entry from the database and play the contents of that entry: an entry is made up of a number of sound files (without a limit). In my application, I return the URI locations of the sound files of an entry (which have been stored in my database) in a List. The code is as follows:
public void audioPlayer() {
// set up MediaPlayer
MediaPlayer mp = new MediaPlayer();
DatabaseHandler db = new DatabaseHandler(this);
Entry retrieveEntry = new Entry();
retrieveEntry = db.getEntry();
List<String> path = retrieveEntry.getAudioUri();
path.size();
System.out.println("PATH SIZE: " +path.size());
System.out.println("FILEZ: " + path);
Iterator<String> i = path.iterator();
String myAudio;
int count = 0;
while (i.hasNext()) {
System.out.println(count);
myAudio = i.next();
System.out.println("MY AUDIO: " + myAudio);
MediaPlayer player = MediaPlayer.create(this, Uri.parse(myAudio));
player.start();
player.stop();
player = MediaPlayer.create(this, Uri.parse(myAudio));
player.start();
count++;
}
}
My users require that there be user input for playing a file - is there a way to play the first file, then wait for the user to press the button, then play the second file, then wait for the user to press the button, etc.? At the moment, when the play button is pressed, all of the sound files that have been returned get played at the same time, rather than one after the other.
Thanks in advance for any help provided!
You can use this class to play a playlist. This will start one audio, when that audio finishes, it will start playing next audio till the end of the list. If you want to play the playlist in looping i.e start first audio after reaching end, then pass isLooping=true in startPlayingPlaylist(list,looping)
AudioPlayer player = new AudioPlayer();
player.startPlayingPlaylist(list, false);
Class
public class AudioPlayer{
MediaPlayer player = null;
ArrayList<String> playlist = null;
int position = 0;
public AudioPlayer() {
super();
// TODO Auto-generated constructor stub
}
public void startPlayingPlaylist(ArrayList<String> list, boolean looping){
playlist = list;
if(player!=null){
player.release();
}
if(playlist!=null && playlist.size()>0){
player = MediaPlayer.create(LMApplicaton.getInstance(),Uri.parse(playlist.get(position)));
player.setWakeMode(LMApplicaton.getInstance(), PowerManager.PARTIAL_WAKE_LOCK);
player.setLooping(looping);
player.start();
// Set onCompletion listener
player.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
position = position+1;
if(position<playlist.size()){
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else if(player.isLooping()==true){
position = position%playlist.size();
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
else if(player.isLooping()==false){
player.release();
player = null;
}
}
});
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
}
}
public void pause(){
if(player!=null && player.isPlaying()){
player.pause();
}
}
public void play(){
if(player!=null && player.isPlaying()==false){
player.start();
}
}
public boolean isPlaying(){
return player.isPlaying();
}
public void release(){
if(player!=null){
player.release();
}
}
}
Edit:
The class below receives a list of audios, then plays first Audio. It plays next audio when user calls startNextAudio() You can use any one of these according to your requirements
public class AudioPlayer{
MediaPlayer player = null;
ArrayList playlist = null;
int position = 0;
public AudioPlayer() {
super();
// TODO Auto-generated constructor stub
}
public void startPlayingPlaylist(ArrayList<String> list){
playlist = list;
if(player!=null){
player.release();
}
if(playlist!=null && playlist.size()>0){
player = MediaPlayer.create(LMApplicaton.getInstance(),Uri.parse(playlist.get(position)));
player.setWakeMode(LMApplicaton.getInstance(), PowerManager.PARTIAL_WAKE_LOCK);
player.start();
// Set onCompletion listener
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
}
}
public void startNextAudio(){
position = position+1;
if(position<playlist.size()){
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else if(player.isLooping()==true){
position = position%playlist.size();
try {
player.reset();
player.setDataSource(playlist.get(position));
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
Log.i("AudioPlayer","Playlist reached at the end");
}
}
public void pause(){
if(player!=null && player.isPlaying()){
player.pause();
}
}
public void play(){
if(player!=null && player.isPlaying()==false){
player.start();
}
}
public boolean isPlaying(){
return player.isPlaying();
}
public void release(){
if(player!=null){
player.release();
}
}
}
One approach would be to implement the MediaPlayer.OnCompletionListener interface. This gives you the MediaPlayer.onCompletion() callback method which you could use like so:
#Override
public void onCompletion(MediaPlayer mp) {
if (i.hasNext) {
// ...hand mp the next file
// ...show the user the 'play next' button
}
}
Note you also will need to call the MediaPlayer.setOnCompletionListener() method in your setup.