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 making a android simple media player for playing a audio files and facing a problem with it.
I want to stop Chronometer and media player
When the current Duration of playing file == total duration of file..?
Here is my demo code.
private void playAudio() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(outputFile);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.start();
mediaPlayer.start();
long totalDuration = mediaPlayer.getDuration();
Log.i("MediaPlayer", String.valueOf(totalDuration));
}
here is another code added from answer .
i add the listrner
mediaPlayer.setOnCompletionListener(CompletionListener);
MediaPlayer.OnCompletionListener CompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
long totalDuration = mp.getDuration();
}
};
Use onCompletionListener to check when media player has reached end of the media file.
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// do your task
}
});
For further reference see this link
Media Player
i have one TextureView.i can play video from assess folder in my TextureView.
now i want to check if video is finished.i wrote setOnCompletionListener but not working.this is a my source
private void playVideoAnimation()
{
textureView.setVisibility(View.VISIBLE);
mMediaPlayer = new MediaPlayer();
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
Surface surface = new Surface(surfaceTexture);
try {
Log.e("FILE_NAME",FILE_NAME);
AssetFileDescriptor afd = getAssets().openFd(FILE_NAME);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mMediaPlayer.setSurface(surface);
mMediaPlayer.setLooping(true);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.e("FILE_NAME", "Finished");
}
});
} catch (IllegalArgumentException e) {
Log.d(TAG, e.getMessage());
} catch (SecurityException e) {
Log.d(TAG, e.getMessage());
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
}
i also wrote setOnCompletionListener listener outside the setSurfaceTextureListener but also not working.
how i can solve my problem? if anyone knows solution please help me
Most likely, your OnCompletionListener is never called because of the following line:
mMediaPlayer.setLooping(true);
According to the MediaPlayer documentation:
When the playback reaches the end of stream, the playback completes.
If the looping mode was being set to true with setLooping(boolean), the MediaPlayer object shall remain in the Started state.
If the looping mode was set to false, the player engine calls a user supplied callback method, OnCompletion.onCompletion(), if a OnCompletionListener is registered beforehand via setOnCompletionListener(OnCompletionListener). The invoke of the callback signals that the object is now in the PlaybackCompleted state.
While in the PlaybackCompleted state, calling start() can restart the playback from the beginning of the audio/video source.
If you want to get a callback from the MediaPlayer when it completes playback and also loop playback, you could change your implementation to follow the suggestion given in the third bullet point: remove mMediaPlayer.setLooping(true) and in your OnCompletionListener call mp.start() to restart playback from the beginning.
I need to play multiple (correct :2 ) mp3 files loaded from my assets when a button is clicked. If the button is again clicked 2 new songs should be played and the old ones should be stopped immidiatelly.The process is on going...
At the moment I have achieved this by stupidly creating 2 mediaPlayer instances in 2 separate methods that basically have the same body .
The caller is an onTouch method and ,within it, first I call method 1 ,then sleep for 2 secs ,then call method 2. I m sure there must be a way for this to be more elegant code? For example I have implemented some listeners that are just sitting there (Actually tried to make this work but totally screwed up with Illegal States all over the place ). Ideally I would like to use 1 MediaPlayer and one method for playing every sound in my app.
int carouzelIndex = 0
#Override
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
...
if (e.getAction() == MotionEvent.ACTION_UP) {
carouzelIndex++;
Assets.playMusic1("music1.ogg",false);
Thread thread = new Thread(){
public void run(){
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assets.playMusic2("music2.ogg",false);
}
}
}
}
Now my player methods 1 and 2 (playMusic1() and playMusic2() )are the same. Both are instansiating different MediaPlayers and for the shake of simplicity I write just one copy in the post
Public class Assets
MediaPlayer mediaPlayer;
public static void playMusic(String filename, boolean looping) {
AssetFileDescriptor afd = null;
Log.d("Assets", "playing music");
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
}
try {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
}
afd = GameMainActivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (!mp.isPlaying())
mp.start();
}
});
mediaPlayer.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
}
});
mediaPlayer.setOnInfoListener(new OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
For immediate playback you need two MediaPlayer set up and chained together via OnCompletionListener
You can do it like this:
Note that I also deleted some unnecessary overrides, you might add them again if you need them.
Public class Assets{
MediaPlayer mediaPlayer;
MediaPlayer mediaPlayer2;
boolean mediaplayer2prepared = false;
boolean mediaplayer1finished = false;
public static void playMusic(String filename, boolean looping, String filename2, boolean looping2) {
AssetFileDescriptor afd = null;
Log.d("Assets", "playing music");
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
mediaplayer1finished = false;
}
if (mediaPlayer2 == null) {
mediaPlayer2 = new MediaPlayer();
mediaPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer2.setLooping(looping);
mediaplayer2prepared = false;
}
try {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
mediaplayer1finished = false;
}
if (mediaPlayer2 != null) {
mediaPlayer2.stop();
mediaPlayer2.release();
mediaPlayer2 = new MediaPlayer();
mediaplayer2prepared = false;
mediaPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer2.setLooping(looping);
}
afd = GameMainActivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (!mp.isPlaying())
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
if(mediaplayer2prepared)
mediaplayer2.start();
mediaplayer1finished = true;
}
});
mediaPlayer.prepareAsync();
afd2 = GameMainActivity.assets.openFd(filename2);
mediaPlayer2.setDataSource(afd2.getFileDescriptor(),
afd2.getStartOffset(), afd2.getLength());
afd2.close();
mediaPlayer2.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
mediaplayer2prepared = true;
if(mediaplayer1finished && !mp.isPlaying()){
mp.start();
}
}
});
mediaPlayer2.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayerIsFinished = true;
mp.reset();
}
});
mediaPlayer2.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
}
To start both mediaplayers in succession simply do Assets.playMusic("music1.ogg",false, "music2.ogg",false);
You can try something like this. Use a single mediaplayer in a single thread. It is an asynchronous operation so it will go on also if the thread is paused. I think it would work.
private Thread t = null;
private MediaPlayer mediaPlayer;
...
Button b=findViewById(R.id.yourButtonId);
b.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//if button had previously clicked stop audio reproduction
if(mediaPlayer.isPlaying()) mediaPlayer.stop();
if(t.isAlive()) t.stop();
String[] files;
//Here you have to set your filenames in the array
...
...
//Now play that audio
playMusic(files, false);
}
});
...
protected static void playMusic(String[] files, boolean looping){
AssetFileDescriptor afd = null;
Log.e("Assets", "Playing music");
t=new Thread(){
#Override
public void run(){
//Initialize mediaPlayer
for(String filename:files){
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(looping);
afd = GameMainAcivity.assets.openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),afd.getLength());
afd.close();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp){
if(!mp.isPlaying()) mp.start();
}
});
//while audio is playing wait in this position
while(mediaPlayer.isPlaying()){
this.wait(100);
}
//now loop can restart with the other filename that has
//to be reproduced
}
}
};
t.start();
}
I am currently trying to design a simple app that streams an internet radio station. I have the URL for the station and am setting up the Media Player like
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(URL);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
The program isn't crashing when emulated, but nothing is playing and I am get the following error:
start called in state 0
and right below it is
Error (-38,0)
Does anyone know what this means?
I've read a little about these state errors, but couldn't find anything that applies to my project.
You need to call mediaPlayer.start() in the onPrepared method by using a listener.
You are getting this error because you are calling mediaPlayer.start() before it has reached the prepared state.
Here is how you can do it :
mp.setDataSource(url);
mp.setOnPreparedListener(this);
mp.prepareAsync();
public void onPrepared(MediaPlayer player) {
player.start();
}
It seems like Error -38 means a state-exception (as the error-message indicates). For example if you call start(), before the song was ready, or when you call pause(), even if the song isn't playing at all.
To fix this issue check the state of the mediaPlayer before calling the methods. For example:
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
Additionally, the MediaPlayer is sending event-messages. Even if you do not need the prepared-event (although it would be a good idea to not start the playback before this event was fired) you must set a callback-listener. This also holds true for the OnErrorListener, OnCompletionListener, OnPreparedListener and OnSeekCompletedListener (if you call the seek method).
Listeners can be attached simply by
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Do something. For example: playButton.setEnabled(true);
}
});
I got this error when I was trying to get the current position (MediaPlayer.getCurrentPosition()) of media player when it wasn't in the prepared stated. I got around this by Keeping track of its state and only calling the getCurrentPosition() method after onPreparedListener is called.
This is my code,tested and working fine:
package com.example.com.mak.mediaplayer;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder
Button btnplay = (Button) findViewById(R.id.btnplay); //Play
btnplay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View vone) {
mpp.start();
}
});
Button btnpause = (Button) findViewById(R.id.btnpause); //Pause
btnpause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View vtwo) {
if (mpp.isPlaying()) {
mpp.pause();
mpp.seekTo(0);
}
}
});
}
}
I encountered the same issue few days ago. My audio MediaPlayer works fine on devices with high processing power, but for slow devices, the media player just did not play some time and from LogCat it had many complain about called in wrong state. So I resolved it by calling putting the call to start(), pause(),... in onPrepared() method of OnPreparedListener() as below:
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
........
mediaPlayer.start();
....
songControlBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
............
}
});
}
});
Also try to release any media player that you do not need any more. For example, if you do not want to play the audio or video on background then you should call mediaPlayer.release() in onPause().
i tested below code. working fine
public class test extends Activity implements OnErrorListener, OnPreparedListener {
private MediaPlayer player;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
player.setOnErrorListener(this);
player.setOnPreparedListener(this);
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
player.release();
player = null;
}
#Override
public void onPrepared(MediaPlayer play) {
play.start();
}
#Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
return false;
}
}
Some times file are encoded in a way that Android can't decode. Even some mp4 files can not be played. Please try a different file format (.3gp are played most of the time) and see..
You get this message in the logs, because you do something that is not allowed in the current state of your MediaPlayer instance.
Therefore you should always register an error handler to catch those things (as #tidbeck suggested).
At first, I advice you to take a look at the documentation for the MediaPlayer class and get an understanding of what that with states means. See: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram
Your mistake here could well be one of the common ones, the others wrote here, but in general, I would take a look at the documentation of what methods are valid to call in what state: http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States
In my example it was the method mediaPlayer.CurrentPosition, that I called while the media player was in a state, where it was not allowed to call this property.
above the picture,you can get the right way.
I solved both the errors (-19,0) and (-38,0) , by creating a new object of MediaPlayer every time before playing and releasing it after that.
Before :
void play(int resourceID) {
if (getActivity() != null) {
//Using the same object - Problem persists
player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
After:
void play(int resourceID) {
if (getActivity() != null) {
//Problem Solved
//Creating new MediaPlayer object every time and releasing it after completion
final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
if(length>0)
{
mediaPlayer = new MediaPlayer();
Log.d("length",""+length);
try {
mediaPlayer.setDataSource(getApplication(),Uri.parse(uri));
} catch(IOException e) {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(length);
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
It was every much frustrated. So, I got solution which works for me.
try {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(file.getAbsolutePath());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
});
}
});
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
For me this worked
mp.seekTo(0);
mp.start();
I also got this error i tried with onPreparedListener but still got this error. Finally i got the solution that error is my fault because i forgot the internet permission in Android Manifest xml. :)
<uses-permission android:name="android.permission.INTERNET" />
I used sample coding for mediaplayer. I used in StreamService.java
onCreate method
String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mp = new MediaPlayer();
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName);
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.prepareAsync();
I have change setAudioStreamType to setAudioAttributes;
mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.setLegacyStreamType(AudioManager.STREAM_ALARM)
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build());
I am new in android programming and i had same error as this one. so i simply redefined the mp.createmediaPlayer = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI). It may not the true way to do it but it worked fined for me:
try {
mp = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
} catch (Exception e) {
e.printStackTrace();
}
mp.start();