How to implement a MediaPlayer restart on errors i

2019-02-16 20:46发布

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.

1条回答
劫难
2楼-- · 2019-02-16 21:18

Overview

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.


Reset after Error

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.


Setting Error Listener

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().

查看更多
登录 后发表回答