I'm trying to implement the restart of MediaPlayer in Android, when errors happen (connection with server lost, network is unreachable and other). I've seen many code examples, but all are somewhat non-standard. I think there must be the standard way to restart corresponding to the developer.android.com, but it's not clear from here, how to set the listener which would restart player on such errors.
Here are the parts of my code:
public class PlayerService extends Service implements OnErrorListener {
....
////////////////////
this.mplayer = MediaPlayer.create(c, Uri.parse(url));
mplayer.setOnErrorListener(onErrorListener);
////////////////////
MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener()
{
@Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
Log.e(getPackageName(), String.format("Error(%s%s)", what, extra));
playlist="ERROR";
restart();
return true;
}
};
@Override
public boolean onError(MediaPlayer player, int what, int extra) {
restart();
return true;
};
public void restart()
{
try
{
playlist="RELOADING";
for (int u=1; u<=5; u++)
{
Thread.sleep(5000);
mplayer.stop();
mplayer.release();
mplayer=null;
playSong(getApplicationContext(),currenturl);
};
}
catch (Exception e)
{
playlist="RELOADING ERROR";
}
}
//////////////
....
}
Am I setting the listener right? I'm not sure where to put onError function so I have 2 of them. When I emulate the error by setting the phone to the flight mode, the listener fires "RELOADING" and "RELOADING ERROR" title. But after the network is on, no restart of the player happens. There is no sound.
What's wrong here? The player cannot restart.
Please help to make the code workable. Also can be connection skips and IO Exception.
Just use pause to stop, followed by seekTo(0) before restarting: mediaPlayer. seekTo(0); mediaPlayer.
android.media.MediaPlayer. MediaPlayer class can be used to control playback of audio/video files and streams.
The Media Player requires a SurfaceHolder object for displaying video content, assigned using the setDisplay() method. The Surface View is a wrapper around the Surface Holder object. Note that we must implement the SurfaceHoler. Callback interface.
I ran into a similar issue and based on the documentation it indicates that all you need to do is reset your media player:
In order to reuse a MediaPlayer object that is in the Error state and recover from the error, reset() can be called to restore the object to its Idle state.
What you are currently doing is stopping and releasing (mplayer.stop()
and mplayer.release()
) a media player that is in the Error state. This should be causing something like an IllegalStateException to be raised. If it's not throwing an error you would still be trying to start a song in a null object. Instead of calling stop and release then setting the variable to null you should be using the mplayer.reset()
function.
Another option would be to initiate a new media player but the documentation details the subtle difference between a newly instantiated MediaPlayer object and one that has had reset()
called on it.
Based on this information something like the following should fix your issue:
public boolean onError(MediaPlayer mp, int what, int extra)
{
Log.e(getPackageName(), String.format("Error(%s%s)", what, extra));
playlist="ERROR";
if(what == MediaPlayer.MEDIA_ERROR_SERVER_DIED)
mp.reset();
else if(what == MediaPlayer.MEDIA_ERROR_UNKNOWN)
mp.reset();
// Deal with any other errors you need to.
// I'm under the assumption you set the path to the song
// and handle onPrepare, start(), etc with this function
playSong(getApplicationContext(),currenturl);
mplayer.setOnErrorListener(this);
mplayer.setOnCompletionListener(this);
mplayer.setOnPreparedListener(this);
return true;
}
See media player constant documentation for a list of potential errors.
As for setting the error listener, here is how I've implemented it in the past:
public class MediaPlayerActivity extends Activity implements OnCompletionListener,
OnPreparedListener, AnimationListener, OnErrorListener{
private MediaPlayer mediaPlayer;
@Override
public boolean onError(final MediaPlayer arg0, final int arg1, final int arg2) {
// Error handling logic here
return true;
}
protected void onResume(){
super.onResume();
// do some onResume logic
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
// finish on resume and start up media player
}
}
I then handle loading up the media player in another function initiated by onResume().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With