Loading core/java/android/widget/VideoView.java +91 −68 Original line number Diff line number Diff line Loading @@ -51,11 +51,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private Uri mUri; private int mDuration; // all possible internal states private static final int STATE_ERROR = -1; private static final int STATE_IDLE = 0; private static final int STATE_PREPARING = 1; private static final int STATE_PREPARED = 2; private static final int STATE_PLAYING = 3; private static final int STATE_PAUSED = 4; private static final int STATE_PLAYBACK_COMPLETED = 5; // mCurrentState is a VideoView object's current state. // mTargetState is the state that a method caller intends to reach. // For instance, regardless the VideoView object's current state, // calling pause() intends to bring the object to a target state // of STATE_PAUSED. private int mCurrentState = STATE_IDLE; private int mTargetState = STATE_IDLE; // All the stuff we need for playing and showing a video private SurfaceHolder mSurfaceHolder = null; private MediaPlayer mMediaPlayer = null; private boolean mIsPrepared; private boolean mIsPlaybackCompleted; private int mVideoWidth; private int mVideoHeight; private int mSurfaceWidth; Loading @@ -65,8 +80,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private MediaPlayer.OnPreparedListener mOnPreparedListener; private int mCurrentBufferPercentage; private OnErrorListener mOnErrorListener; private boolean mStartWhenPrepared; private int mSeekWhenPrepared; private int mSeekWhenPrepared; // recording the seek position while preparing public VideoView(Context context) { super(context); Loading @@ -80,7 +94,6 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { public VideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initVideoView(); } Loading Loading @@ -143,6 +156,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { setFocusable(true); setFocusableInTouchMode(true); requestFocus(); mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } public void setVideoPath(String path) { Loading @@ -151,7 +166,6 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { public void setVideoURI(Uri uri) { mUri = uri; mStartWhenPrepared = false; mSeekWhenPrepared = 0; openVideo(); requestLayout(); Loading @@ -163,6 +177,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } } Loading @@ -177,17 +193,11 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { i.putExtra("command", "pause"); mContext.sendBroadcast(i); if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; } release(); try { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnPreparedListener(mPreparedListener); mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); mIsPrepared = false; Log.v(TAG, "reset duration to -1 in openVideo"); mDuration = -1; mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.setOnErrorListener(mErrorListener); Loading @@ -198,12 +208,18 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setScreenOnWhilePlaying(true); mMediaPlayer.prepareAsync(); mCurrentState = STATE_PREPARING; mTargetState = STATE_PREPARED; attachMediaController(); } catch (IOException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; return; } catch (IllegalArgumentException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; return; } } Loading @@ -222,7 +238,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { View anchorView = this.getParent() instanceof View ? (View)this.getParent() : this; mMediaController.setAnchorView(anchorView); mMediaController.setEnabled(mIsPrepared); mMediaController.setEnabled(isInPlaybackState()); } } Loading @@ -239,8 +255,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { // briefly show the mediacontroller mIsPrepared = true; mCurrentState = STATE_PREPARED; if (mOnPreparedListener != null) { mOnPreparedListener.onPrepared(mMediaPlayer); } Loading @@ -249,6 +264,10 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be changed after seekTo() call if (seekToPosition != 0) { seekTo(seekToPosition); } if (mVideoWidth != 0 && mVideoHeight != 0) { //Log.i("@@@@", "video size: " + mVideoWidth +"/"+ mVideoHeight); getHolder().setFixedSize(mVideoWidth, mVideoHeight); Loading @@ -256,18 +275,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { // We didn't actually change the size (it was already at the size // we need), so we won't get a "surface changed" callback, so // start the video here instead of in the callback. if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; } if (mStartWhenPrepared) { if (mTargetState == STATE_PLAYING) { start(); mStartWhenPrepared = false; if (mMediaController != null) { mMediaController.show(); } } else if (!isPlaying() && (mSeekWhenPrepared != 0 || getCurrentPosition() > 0)) { (seekToPosition != 0 || getCurrentPosition() > 0)) { if (mMediaController != null) { // Show the media controls when we're paused into a video and make 'em stick. mMediaController.show(0); Loading @@ -277,13 +291,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } else { // We don't know the video size yet, but should start anyway. // The video size might be reported to us later. if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; } if (mStartWhenPrepared) { if (mTargetState == STATE_PLAYING) { start(); mStartWhenPrepared = false; } } } Loading @@ -292,7 +301,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { mIsPlaybackCompleted = true; mCurrentState = STATE_PLAYBACK_COMPLETED; mTargetState = STATE_PLAYBACK_COMPLETED; if (mMediaController != null) { mMediaController.hide(); } Loading @@ -306,6 +316,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer mp, int framework_err, int impl_err) { Log.d(TAG, "Error: " + framework_err + "," + impl_err); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; if (mMediaController != null) { mMediaController.hide(); } Loading Loading @@ -402,14 +414,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { { mSurfaceWidth = w; mSurfaceHeight = h; if (mMediaPlayer != null && mIsPrepared && mVideoWidth == w && mVideoHeight == h) { boolean isValidState = (mTargetState == STATE_PLAYING); boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h); if (mMediaPlayer != null && isValidState && hasValidSize) { if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; seekTo(mSeekWhenPrepared); } if (!mIsPlaybackCompleted) { start(); } if (mMediaController != null) { mMediaController.show(); } Loading @@ -427,17 +438,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { // after we return from this we can't use the surface any more mSurfaceHolder = null; if (mMediaController != null) mMediaController.hide(); release(); } }; /* * release the media player in any state */ private void release() { if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } } }; @Override public boolean onTouchEvent(MotionEvent ev) { if (mIsPrepared && mMediaPlayer != null && mMediaController != null) { if (isInPlaybackState() && mMediaController != null) { toggleMediaControlsVisiblity(); } return false; Loading @@ -445,7 +465,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { @Override public boolean onTrackballEvent(MotionEvent ev) { if (mIsPrepared && mMediaPlayer != null && mMediaController != null) { if (isInPlaybackState() && mMediaController != null) { toggleMediaControlsVisiblity(); } return false; Loading @@ -454,15 +474,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mIsPrepared && keyCode != KeyEvent.KEYCODE_BACK && boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_MENU && keyCode != KeyEvent.KEYCODE_CALL && keyCode != KeyEvent.KEYCODE_ENDCALL && mMediaPlayer != null && mMediaController != null) { keyCode != KeyEvent.KEYCODE_ENDCALL; if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) { if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) { if (mMediaPlayer.isPlaying()) { Loading Loading @@ -494,26 +512,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } public void start() { mIsPlaybackCompleted = false; if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { mMediaPlayer.start(); mStartWhenPrepared = false; } else { mStartWhenPrepared = true; mCurrentState = STATE_PLAYING; } mTargetState = STATE_PLAYING; } public void pause() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mCurrentState = STATE_PAUSED; } } mStartWhenPrepared = false; mTargetState = STATE_PAUSED; } // cache duration as mDuration for faster access public int getDuration() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { if (mDuration > 0) { return mDuration; } Loading @@ -525,25 +543,23 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } public int getCurrentPosition() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { return mMediaPlayer.getCurrentPosition(); } return 0; } public void seekTo(int msec) { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { mMediaPlayer.seekTo(msec); mSeekWhenPrepared = 0; } else { mSeekWhenPrepared = msec; } } public boolean isPlaying() { if (mMediaPlayer != null && mIsPrepared) { return mMediaPlayer.isPlaying(); } return false; return isInPlaybackState() && mMediaPlayer.isPlaying(); } public int getBufferPercentage() { Loading @@ -552,4 +568,11 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } return 0; } private boolean isInPlaybackState() { return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING); } } Loading
core/java/android/widget/VideoView.java +91 −68 Original line number Diff line number Diff line Loading @@ -51,11 +51,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private Uri mUri; private int mDuration; // all possible internal states private static final int STATE_ERROR = -1; private static final int STATE_IDLE = 0; private static final int STATE_PREPARING = 1; private static final int STATE_PREPARED = 2; private static final int STATE_PLAYING = 3; private static final int STATE_PAUSED = 4; private static final int STATE_PLAYBACK_COMPLETED = 5; // mCurrentState is a VideoView object's current state. // mTargetState is the state that a method caller intends to reach. // For instance, regardless the VideoView object's current state, // calling pause() intends to bring the object to a target state // of STATE_PAUSED. private int mCurrentState = STATE_IDLE; private int mTargetState = STATE_IDLE; // All the stuff we need for playing and showing a video private SurfaceHolder mSurfaceHolder = null; private MediaPlayer mMediaPlayer = null; private boolean mIsPrepared; private boolean mIsPlaybackCompleted; private int mVideoWidth; private int mVideoHeight; private int mSurfaceWidth; Loading @@ -65,8 +80,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private MediaPlayer.OnPreparedListener mOnPreparedListener; private int mCurrentBufferPercentage; private OnErrorListener mOnErrorListener; private boolean mStartWhenPrepared; private int mSeekWhenPrepared; private int mSeekWhenPrepared; // recording the seek position while preparing public VideoView(Context context) { super(context); Loading @@ -80,7 +94,6 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { public VideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initVideoView(); } Loading Loading @@ -143,6 +156,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { setFocusable(true); setFocusableInTouchMode(true); requestFocus(); mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } public void setVideoPath(String path) { Loading @@ -151,7 +166,6 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { public void setVideoURI(Uri uri) { mUri = uri; mStartWhenPrepared = false; mSeekWhenPrepared = 0; openVideo(); requestLayout(); Loading @@ -163,6 +177,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } } Loading @@ -177,17 +193,11 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { i.putExtra("command", "pause"); mContext.sendBroadcast(i); if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; } release(); try { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnPreparedListener(mPreparedListener); mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); mIsPrepared = false; Log.v(TAG, "reset duration to -1 in openVideo"); mDuration = -1; mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.setOnErrorListener(mErrorListener); Loading @@ -198,12 +208,18 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setScreenOnWhilePlaying(true); mMediaPlayer.prepareAsync(); mCurrentState = STATE_PREPARING; mTargetState = STATE_PREPARED; attachMediaController(); } catch (IOException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; return; } catch (IllegalArgumentException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; return; } } Loading @@ -222,7 +238,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { View anchorView = this.getParent() instanceof View ? (View)this.getParent() : this; mMediaController.setAnchorView(anchorView); mMediaController.setEnabled(mIsPrepared); mMediaController.setEnabled(isInPlaybackState()); } } Loading @@ -239,8 +255,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { // briefly show the mediacontroller mIsPrepared = true; mCurrentState = STATE_PREPARED; if (mOnPreparedListener != null) { mOnPreparedListener.onPrepared(mMediaPlayer); } Loading @@ -249,6 +264,10 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be changed after seekTo() call if (seekToPosition != 0) { seekTo(seekToPosition); } if (mVideoWidth != 0 && mVideoHeight != 0) { //Log.i("@@@@", "video size: " + mVideoWidth +"/"+ mVideoHeight); getHolder().setFixedSize(mVideoWidth, mVideoHeight); Loading @@ -256,18 +275,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { // We didn't actually change the size (it was already at the size // we need), so we won't get a "surface changed" callback, so // start the video here instead of in the callback. if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; } if (mStartWhenPrepared) { if (mTargetState == STATE_PLAYING) { start(); mStartWhenPrepared = false; if (mMediaController != null) { mMediaController.show(); } } else if (!isPlaying() && (mSeekWhenPrepared != 0 || getCurrentPosition() > 0)) { (seekToPosition != 0 || getCurrentPosition() > 0)) { if (mMediaController != null) { // Show the media controls when we're paused into a video and make 'em stick. mMediaController.show(0); Loading @@ -277,13 +291,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } else { // We don't know the video size yet, but should start anyway. // The video size might be reported to us later. if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; } if (mStartWhenPrepared) { if (mTargetState == STATE_PLAYING) { start(); mStartWhenPrepared = false; } } } Loading @@ -292,7 +301,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { mIsPlaybackCompleted = true; mCurrentState = STATE_PLAYBACK_COMPLETED; mTargetState = STATE_PLAYBACK_COMPLETED; if (mMediaController != null) { mMediaController.hide(); } Loading @@ -306,6 +316,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer mp, int framework_err, int impl_err) { Log.d(TAG, "Error: " + framework_err + "," + impl_err); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; if (mMediaController != null) { mMediaController.hide(); } Loading Loading @@ -402,14 +414,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { { mSurfaceWidth = w; mSurfaceHeight = h; if (mMediaPlayer != null && mIsPrepared && mVideoWidth == w && mVideoHeight == h) { boolean isValidState = (mTargetState == STATE_PLAYING); boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h); if (mMediaPlayer != null && isValidState && hasValidSize) { if (mSeekWhenPrepared != 0) { mMediaPlayer.seekTo(mSeekWhenPrepared); mSeekWhenPrepared = 0; seekTo(mSeekWhenPrepared); } if (!mIsPlaybackCompleted) { start(); } if (mMediaController != null) { mMediaController.show(); } Loading @@ -427,17 +438,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { // after we return from this we can't use the surface any more mSurfaceHolder = null; if (mMediaController != null) mMediaController.hide(); release(); } }; /* * release the media player in any state */ private void release() { if (mMediaPlayer != null) { mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; mCurrentState = STATE_IDLE; mTargetState = STATE_IDLE; } } }; @Override public boolean onTouchEvent(MotionEvent ev) { if (mIsPrepared && mMediaPlayer != null && mMediaController != null) { if (isInPlaybackState() && mMediaController != null) { toggleMediaControlsVisiblity(); } return false; Loading @@ -445,7 +465,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { @Override public boolean onTrackballEvent(MotionEvent ev) { if (mIsPrepared && mMediaPlayer != null && mMediaController != null) { if (isInPlaybackState() && mMediaController != null) { toggleMediaControlsVisiblity(); } return false; Loading @@ -454,15 +474,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mIsPrepared && keyCode != KeyEvent.KEYCODE_BACK && boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_MENU && keyCode != KeyEvent.KEYCODE_CALL && keyCode != KeyEvent.KEYCODE_ENDCALL && mMediaPlayer != null && mMediaController != null) { keyCode != KeyEvent.KEYCODE_ENDCALL; if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) { if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) { if (mMediaPlayer.isPlaying()) { Loading Loading @@ -494,26 +512,26 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } public void start() { mIsPlaybackCompleted = false; if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { mMediaPlayer.start(); mStartWhenPrepared = false; } else { mStartWhenPrepared = true; mCurrentState = STATE_PLAYING; } mTargetState = STATE_PLAYING; } public void pause() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mCurrentState = STATE_PAUSED; } } mStartWhenPrepared = false; mTargetState = STATE_PAUSED; } // cache duration as mDuration for faster access public int getDuration() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { if (mDuration > 0) { return mDuration; } Loading @@ -525,25 +543,23 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } public int getCurrentPosition() { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { return mMediaPlayer.getCurrentPosition(); } return 0; } public void seekTo(int msec) { if (mMediaPlayer != null && mIsPrepared) { if (isInPlaybackState()) { mMediaPlayer.seekTo(msec); mSeekWhenPrepared = 0; } else { mSeekWhenPrepared = msec; } } public boolean isPlaying() { if (mMediaPlayer != null && mIsPrepared) { return mMediaPlayer.isPlaying(); } return false; return isInPlaybackState() && mMediaPlayer.isPlaying(); } public int getBufferPercentage() { Loading @@ -552,4 +568,11 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } return 0; } private boolean isInPlaybackState() { return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING); } }