|
|
@@ -0,0 +1,212 @@ |
|
|
import java.io.IOException; |
|
|
import java.lang.reflect.Method; |
|
|
import java.util.AbstractCollection; |
|
|
import java.util.ArrayList; |
|
|
import java.util.EnumSet; |
|
|
import java.util.HashMap; |
|
|
import java.util.Iterator; |
|
|
import java.util.Map; |
|
|
import android.media.AudioManager; |
|
|
import android.media.MediaPlayer; |
|
|
import android.media.MediaPlayer.OnBufferingUpdateListener; |
|
|
import android.media.MediaPlayer.OnCompletionListener; |
|
|
import android.media.MediaPlayer.OnErrorListener; |
|
|
import android.media.MediaPlayer.OnInfoListener; |
|
|
import android.media.MediaPlayer.OnPreparedListener; |
|
|
import android.util.Log; |
|
|
|
|
|
/** |
|
|
* A wrapper class for {@link android.media.MediaPlayer}. |
|
|
* <p> |
|
|
* Encapsulates an instance of MediaPlayer, and makes a record of its internal state accessible via a |
|
|
* {@link MediaPlayerWrapper#getState()} accessor. Most of the frequently used methods are available, but some still |
|
|
* need adding. |
|
|
* </p> |
|
|
*/ |
|
|
public class MediaPlayerStateWrapper { |
|
|
|
|
|
private static String tag = "MediaPlayerWrapper"; |
|
|
private MediaPlayer mPlayer; |
|
|
private State currentState; |
|
|
private MediaPlayerStateWrapper mWrapper; |
|
|
|
|
|
MediaPlayerStateWrapper() { |
|
|
mWrapper = this; |
|
|
mPlayer = new MediaPlayer(); |
|
|
currentState = State.IDLE; |
|
|
mPlayer.setOnPreparedListener(mOnPreparedListener); |
|
|
mPlayer.setOnCompletionListener(mOnCompletionListener); |
|
|
mPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener); |
|
|
mPlayer.setOnErrorListener(mOnErrorListener); |
|
|
mPlayer.setOnInfoListener(mOnInfoListener); |
|
|
} |
|
|
|
|
|
/* METHOD WRAPPING FOR STATE CHANGES */ |
|
|
public static enum State { |
|
|
IDLE, ERROR, INITIALIZED, PREPARING, PREPARED, STARTED, STOPPED, PLAYBACK_COMPLETE, PAUSED; |
|
|
} |
|
|
|
|
|
public void setDataSource(String path) { |
|
|
if (currentState == State.IDLE) { |
|
|
try { |
|
|
mPlayer.setDataSource(path); |
|
|
currentState = State.INITIALIZED; |
|
|
} catch (IllegalArgumentException e) { |
|
|
e.printStackTrace(); |
|
|
} catch (IllegalStateException e) { |
|
|
e.printStackTrace(); |
|
|
} catch (IOException e) { |
|
|
e.printStackTrace(); |
|
|
} |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void prepareAsync() { |
|
|
Log.d(tag, "prepareAsync()"); |
|
|
if (EnumSet.of(State.INITIALIZED, State.STOPPED).contains(currentState)) { |
|
|
mPlayer.prepareAsync(); |
|
|
currentState = State.PREPARING; |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public boolean isPlaying() { |
|
|
Log.d(tag, "isPlaying()"); |
|
|
if (currentState != State.ERROR) { |
|
|
return mPlayer.isPlaying(); |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void seekTo(int msec) { |
|
|
Log.d(tag, "seekTo()"); |
|
|
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, State.PLAYBACK_COMPLETE).contains(currentState)) { |
|
|
mPlayer.seekTo(msec); |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void pause() { |
|
|
Log.d(tag, "pause()"); |
|
|
if (EnumSet.of(State.STARTED, State.PAUSED).contains(currentState)) { |
|
|
mPlayer.pause(); |
|
|
currentState = State.PAUSED; |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void start() { |
|
|
Log.d(tag, "start()"); |
|
|
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, State.PLAYBACK_COMPLETE).contains(currentState)) { |
|
|
mPlayer.start(); |
|
|
currentState = State.STARTED; |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void stop() { |
|
|
Log.d(tag, "stop()"); |
|
|
if (EnumSet.of(State.PREPARED, State.STARTED, State.STOPPED, State.PAUSED, State.PLAYBACK_COMPLETE).contains( |
|
|
currentState)) { |
|
|
mPlayer.stop(); |
|
|
currentState = State.STOPPED; |
|
|
} else throw new RuntimeException(); |
|
|
} |
|
|
|
|
|
public void reset() { |
|
|
Log.d(tag, "reset()"); |
|
|
mPlayer.reset(); |
|
|
currentState = State.IDLE; |
|
|
} |
|
|
|
|
|
/** |
|
|
* @return The current state of the mediaplayer state machine. |
|
|
*/ |
|
|
public State getState() { |
|
|
Log.d(tag, "getState()"); |
|
|
return currentState; |
|
|
} |
|
|
|
|
|
public void release() { |
|
|
Log.d(tag, "release()"); |
|
|
mPlayer.release(); |
|
|
} |
|
|
|
|
|
/* INTERNAL LISTENERS */ |
|
|
private OnPreparedListener mOnPreparedListener = new OnPreparedListener() { |
|
|
|
|
|
@Override |
|
|
public void onPrepared(MediaPlayer mp) { |
|
|
Log.d(tag, "on prepared"); |
|
|
currentState = State.PREPARED; |
|
|
mWrapper.onPrepared(mp); |
|
|
mPlayer.start(); |
|
|
currentState = State.STARTED; |
|
|
} |
|
|
}; |
|
|
private OnCompletionListener mOnCompletionListener = new OnCompletionListener() { |
|
|
|
|
|
@Override |
|
|
public void onCompletion(MediaPlayer mp) { |
|
|
Log.d(tag, "on completion"); |
|
|
currentState = State.PLAYBACK_COMPLETE; |
|
|
mWrapper.onCompletion(mp); |
|
|
} |
|
|
}; |
|
|
private OnBufferingUpdateListener mOnBufferingUpdateListener = new OnBufferingUpdateListener() { |
|
|
|
|
|
@Override |
|
|
public void onBufferingUpdate(MediaPlayer mp, int percent) { |
|
|
Log.d(tag, "on buffering update"); |
|
|
mWrapper.onBufferingUpdate(mp, percent); |
|
|
} |
|
|
}; |
|
|
private OnErrorListener mOnErrorListener = new OnErrorListener() { |
|
|
|
|
|
@Override |
|
|
public boolean onError(MediaPlayer mp, int what, int extra) { |
|
|
Log.d(tag, "on error"); |
|
|
currentState = State.ERROR; |
|
|
mWrapper.onError(mp, what, extra); |
|
|
return false; |
|
|
} |
|
|
}; |
|
|
private OnInfoListener mOnInfoListener = new OnInfoListener() { |
|
|
|
|
|
@Override |
|
|
public boolean onInfo(MediaPlayer mp, int what, int extra) { |
|
|
Log.d(tag, "on info"); |
|
|
mWrapper.onInfo(mp, what, extra); |
|
|
return false; |
|
|
} |
|
|
}; |
|
|
|
|
|
/* EXTERNAL STUBS TO OVERRIDE */ |
|
|
public void onPrepared(MediaPlayer mp) {} |
|
|
|
|
|
public void onCompletion(MediaPlayer mp) {} |
|
|
|
|
|
public void onBufferingUpdate(MediaPlayer mp, int percent) {} |
|
|
|
|
|
boolean onError(MediaPlayer mp, int what, int extra) { |
|
|
return false; |
|
|
} |
|
|
|
|
|
public boolean onInfo(MediaPlayer mp, int what, int extra) { |
|
|
return false; |
|
|
} |
|
|
|
|
|
/* OTHER STUFF */ |
|
|
public int getCurrentPosition() { |
|
|
if (currentState != State.ERROR) { |
|
|
return mPlayer.getCurrentPosition(); |
|
|
} else { |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
public int getDuration() { |
|
|
// Prepared, Started, Paused, Stopped, PlaybackCompleted |
|
|
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, State.STOPPED, State.PLAYBACK_COMPLETE).contains( |
|
|
currentState)) { |
|
|
return mPlayer.getDuration(); |
|
|
} else { |
|
|
return 100; |
|
|
} |
|
|
} |
|
|
} |