Last active
August 29, 2015 14:27
-
-
Save mavencode01/6d8d2a668795c6c567cf to your computer and use it in GitHub Desktop.
VideoView extends TextureView with rotation support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mavencode.modules.chatwindow.widget; | |
import android.app.Activity; | |
import android.app.AlertDialog; | |
import android.content.Context; | |
import android.content.DialogInterface; | |
import android.content.Intent; | |
import android.content.res.Configuration; | |
import android.graphics.SurfaceTexture; | |
import android.media.AudioManager; | |
import android.net.Uri; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.util.Pair; | |
import android.view.*; | |
import android.view.ViewGroup.LayoutParams; | |
import com.mavencode.R; | |
import tv.danmaku.ijk.media.player.IMediaPlayer; | |
import tv.danmaku.ijk.media.player.IMediaPlayer.*; | |
import tv.danmaku.ijk.media.player.IMediaPlayer.OnSeekCompleteListener; | |
import tv.danmaku.ijk.media.player.IjkMediaPlayer; | |
import java.io.IOException; | |
import java.util.List; | |
public class VideoView extends TextureView implements | |
MediaController.MediaPlayerControl { | |
private static final String LOG_TAG = "VideoView"; | |
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; | |
private int mCurrentState = STATE_IDLE; | |
private int mTargetState = STATE_IDLE; | |
public int number; | |
private int mVideoLayout = VIDEO_LAYOUT_SCALE; | |
public static final int VIDEO_LAYOUT_ORIGIN = 0; | |
public static final int VIDEO_LAYOUT_SCALE = 1; | |
public static final int VIDEO_LAYOUT_STRETCH = 2; | |
public static final int VIDEO_LAYOUT_ZOOM = 3; | |
private IMediaPlayer mMediaPlayer = null; | |
private int videoWidth; | |
private int videoHeight; | |
private int surfaceWidth; | |
private int surfaceHeight; | |
private int mVideoSarNum; | |
private int mVideoSarDen; | |
private Surface mSurface; | |
private MediaController mMediaController; | |
private long mDuration; | |
private int mCurrentBufferPercentage; | |
private String mUserAgent; | |
private Uri uri; | |
private View mMediaBufferingIndicator; | |
private long mSeekWhenPrepared; | |
private boolean mCanPause = true; | |
private boolean mCanSeekBack = true; | |
private boolean mCanSeekForward = true; | |
private OnCompletionListener mOnCompletionListener; | |
private OnPreparedListener mOnPreparedListener; | |
private OnErrorListener mOnErrorListener; | |
private OnSeekCompleteListener mOnSeekCompleteListener; | |
private OnInfoListener mOnInfoListener; | |
private OnBufferingUpdateListener mOnBufferingUpdateListener; | |
private Context mContext; | |
private static final String TAG = VideoView.class.getName(); | |
public VideoView(final Context context) { | |
super(context); | |
mContext = context; | |
initVideoView(context); | |
setVideoLayout(mVideoLayout); | |
} | |
public VideoView(final Context context, final AttributeSet attrs) { | |
super(context, attrs); | |
mContext = context; | |
initVideoView(context); | |
} | |
public VideoView(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
mContext = context; | |
initVideoView(context); | |
} | |
public void initVideoView(Context context) { | |
Log.d(LOG_TAG, "Initializing video view."); | |
mContext = context; | |
videoHeight = 0; | |
videoWidth = 0; | |
mVideoSarNum = 0; | |
mVideoSarDen = 0; | |
setFocusable(true); | |
setFocusableInTouchMode(true); | |
setSurfaceTextureListener(mSurfaceTextureListener); | |
requestFocus(); | |
mCurrentState = STATE_IDLE; | |
mTargetState = STATE_IDLE; | |
if (context instanceof Activity) | |
((Activity) context).setVolumeControlStream(AudioManager.STREAM_MUSIC); | |
} | |
public void setVideoURI(Uri _videoURI) { | |
uri = _videoURI; | |
mSeekWhenPrepared = 0; | |
openVideo(); | |
requestLayout(); | |
invalidate(); | |
} | |
public Uri getUri() { | |
return uri; | |
} | |
public void setUserAgent(String ua) { | |
mUserAgent = ua; | |
} | |
public void stopPlayback() { | |
if (mMediaPlayer != null) { | |
mMediaPlayer.stop(); | |
mMediaPlayer.release(); | |
mMediaPlayer = null; | |
mMediaPlayer = null; | |
mCurrentState = STATE_IDLE; | |
mTargetState = STATE_IDLE; | |
} | |
} | |
public void openVideo() { | |
if ((uri == null) || (mSurface == null)) { | |
Log.d(LOG_TAG, "Cannot open video, uri or mSurface is null number " + number); | |
return; | |
} | |
Intent i = new Intent("com.android.music.musicservicecommand"); | |
i.putExtra("command", "pause"); | |
mContext.sendBroadcast(i); | |
Log.d(LOG_TAG, "Opening video."); | |
release(false); | |
try { | |
mDuration = -1; | |
mCurrentBufferPercentage = 0; | |
IjkMediaPlayer ijkMediaPlayer = null; | |
if (uri != null) { | |
ijkMediaPlayer = new IjkMediaPlayer(); | |
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32); | |
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 12); | |
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0); | |
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "user_agent", mUserAgent); | |
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48); | |
} | |
mMediaPlayer = ijkMediaPlayer; | |
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); | |
Log.d(LOG_TAG, "Preparing media player."); | |
mMediaPlayer.setOnPreparedListener(mPreparedListener); | |
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); | |
mMediaPlayer.setOnCompletionListener(mCompletionListener); | |
mMediaPlayer.setOnErrorListener(mErrorListener); | |
mMediaPlayer.setOnInfoListener(mInfoListener); | |
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); | |
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener); | |
if (uri != null) | |
mMediaPlayer.setDataSource(uri.toString()); | |
mMediaPlayer.setSurface(mSurface); | |
mMediaPlayer.setScreenOnWhilePlaying(true); | |
mMediaPlayer.prepareAsync(); | |
mCurrentState = STATE_PREPARING; | |
attachMediaController(); | |
} catch (IOException ex) { | |
DebugLog.e(TAG, "Unable to open content: " + uri, ex); | |
mCurrentState = STATE_ERROR; | |
mTargetState = STATE_ERROR; | |
mErrorListener.onError(mMediaPlayer, IMediaPlayer.MEDIA_ERROR_UNKNOWN, 0); | |
return; | |
} catch (IllegalArgumentException ex) { | |
DebugLog.e(TAG, "Unable to open content: " + uri, ex); | |
mCurrentState = STATE_ERROR; | |
mTargetState = STATE_ERROR; | |
mErrorListener.onError(mMediaPlayer, IMediaPlayer.MEDIA_ERROR_UNKNOWN, 0); | |
return; | |
} | |
} | |
public void setMediaController(MediaController controller) { | |
if (mMediaController != null) | |
mMediaController.hide(); | |
mMediaController = controller; | |
attachMediaController(); | |
} | |
public void setMediaBufferingIndicator(View mediaBufferingIndicator) { | |
if (mMediaBufferingIndicator != null) | |
mMediaBufferingIndicator.setVisibility(View.GONE); | |
mMediaBufferingIndicator = mediaBufferingIndicator; | |
} | |
private void attachMediaController() { | |
if (mMediaPlayer != null && mMediaController != null) { | |
mMediaController.setMediaPlayer(this); | |
View anchorView = this.getParent() instanceof View ? (View) this.getParent() : this; | |
mMediaController.setAnchorView(anchorView); | |
mMediaController.setEnabled(isInPlaybackState()); | |
if (uri != null) { | |
List<String> paths = uri.getPathSegments(); | |
String name = paths == null || paths.isEmpty() ? "null" : paths.get(paths.size() - 1); | |
mMediaController.setFileName(name); | |
} | |
} | |
} | |
private void release(boolean cleartargetstate) { | |
Log.d(LOG_TAG, "Releasing media player."); | |
if (mMediaPlayer != null) { | |
mMediaPlayer.reset(); | |
mMediaPlayer.release(); | |
mMediaPlayer = null; | |
mCurrentState = STATE_IDLE; | |
if (cleartargetstate) { | |
mTargetState = STATE_IDLE; | |
} | |
Log.d(LOG_TAG, "Released media player."); | |
} else { | |
Log.d(LOG_TAG, "Media player was null, did not release."); | |
} | |
} | |
@Override | |
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { | |
Log.d(LOG_TAG, "onMeasure number " + number); | |
int width = getDefaultSize(videoWidth, widthMeasureSpec); | |
int height = getDefaultSize(videoHeight, heightMeasureSpec); | |
if ((videoWidth > 0) && (videoHeight > 0)) { | |
if ((videoWidth * height) > (width * videoHeight)) { | |
Log.d(LOG_TAG, "Image too tall, correcting."); | |
height = (width * videoHeight) / videoWidth; | |
} else if ((videoWidth * height) < (width * videoHeight)) { | |
Log.d(LOG_TAG, "Image too wide, correcting."); | |
width = (height * videoWidth) / videoHeight; | |
} else { | |
Log.d(LOG_TAG, "Aspect ratio is correct."); | |
} | |
} | |
Log.d(LOG_TAG, "Setting size: " + width + '/' + height + " for number " + number); | |
setMeasuredDimension(width, height); | |
} | |
@Override | |
public boolean onTouchEvent(MotionEvent ev) { | |
if (isInPlaybackState() && mMediaController != null) | |
toggleMediaControlsVisiblity(); | |
return false; | |
} | |
@Override | |
public boolean onTrackballEvent(MotionEvent ev) { | |
if (isInPlaybackState() && mMediaController != null) | |
toggleMediaControlsVisiblity(); | |
return false; | |
} | |
@Override | |
public boolean onKeyDown(int keyCode, KeyEvent event) { | |
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; | |
if (isInPlaybackState() && isKeyCodeSupported | |
&& mMediaController != null) { | |
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK | |
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE | |
|| keyCode == KeyEvent.KEYCODE_SPACE) { | |
if (mMediaPlayer.isPlaying()) { | |
pause(); | |
mMediaController.show(); | |
} else { | |
start(); | |
mMediaController.hide(); | |
} | |
return true; | |
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP | |
&& mMediaPlayer.isPlaying()) { | |
pause(); | |
mMediaController.show(); | |
} else { | |
toggleMediaControlsVisiblity(); | |
} | |
} | |
return super.onKeyDown(keyCode, event); | |
} | |
private void toggleMediaControlsVisiblity() { | |
if (mMediaController.isShowing()) { | |
mMediaController.hide(); | |
} else { | |
mMediaController.show(); | |
} | |
} | |
public boolean isPlaying() { | |
return isInPlaybackState() && mMediaPlayer.isPlaying(); | |
} | |
public void start() { | |
if (isInPlaybackState()) { | |
Log.d(LOG_TAG, "Starting media player for number " + number); | |
mMediaPlayer.start(); | |
mCurrentState = STATE_PLAYING; | |
if (null != mMediaControllListener) { | |
mMediaControllListener.onStart(); | |
} else { | |
Log.d(LOG_TAG, "Could not start. Current state " + mCurrentState); | |
} | |
mTargetState = STATE_PLAYING; | |
} | |
} | |
public void pause() { | |
if (isInPlaybackState()) { | |
if (mMediaPlayer.isPlaying()) { | |
mMediaPlayer.pause(); | |
mCurrentState = STATE_PAUSED; | |
if (null != mMediaControllListener) { | |
mMediaControllListener.onPause(); | |
} | |
} | |
} | |
mTargetState = STATE_PAUSED; | |
} | |
private boolean isInPlaybackState() { | |
return ((mMediaPlayer != null) && | |
(mCurrentState != STATE_ERROR) && | |
(mCurrentState != STATE_IDLE) && | |
(mCurrentState != STATE_PREPARING)); | |
} | |
public int getDuration() { | |
if (isInPlaybackState()) { | |
if (mDuration > 0) | |
return (int) mDuration; | |
mDuration = mMediaPlayer.getDuration(); | |
return (int) mDuration; | |
} | |
mDuration = -1; | |
return (int) mDuration; | |
} | |
public int getCurrentPosition() { | |
if (isInPlaybackState()) { | |
long position = mMediaPlayer.getCurrentPosition(); | |
return (int) position; | |
} | |
return 0; | |
} | |
public void seekTo(long msec) { | |
if (isInPlaybackState()) { | |
mMediaPlayer.seekTo(msec); | |
mSeekWhenPrepared = 0; | |
} else { | |
mSeekWhenPrepared = msec; | |
} | |
} | |
public int getBufferPercentage() { | |
if (mMediaPlayer != null) | |
return mCurrentBufferPercentage; | |
return 0; | |
} | |
@Override | |
public boolean canPause() { | |
return mCanPause; | |
} | |
@Override | |
public boolean canSeekBackward() { | |
return mCanSeekBack; | |
} | |
@Override | |
public boolean canSeekForward() { | |
return mCanSeekForward; | |
} | |
public void setVideoLayout(int layout) { | |
LayoutParams lp = getLayoutParams(); | |
Pair<Integer, Integer> res = ScreenResolution.getResolution(mContext); | |
int windowWidth = res.first.intValue(), windowHeight = res.second.intValue(); | |
float windowRatio = windowWidth / (float) windowHeight; | |
int sarNum = mVideoSarNum; | |
int sarDen = mVideoSarDen; | |
if (videoHeight > 0 && videoWidth > 0) { | |
float videoRatio = ((float) (videoWidth)) / videoHeight; | |
if (sarNum > 0 && sarDen > 0) | |
videoRatio = videoRatio * sarNum / sarDen; | |
surfaceHeight = videoHeight; | |
surfaceWidth = videoWidth; | |
if (VIDEO_LAYOUT_ORIGIN == layout && surfaceWidth < windowWidth && surfaceHeight < windowHeight) { | |
lp.width = (int) (surfaceHeight * videoRatio); | |
lp.height = surfaceHeight; | |
} else if (layout == VIDEO_LAYOUT_ZOOM) { | |
lp.width = windowRatio > videoRatio ? windowWidth : (int) (videoRatio * windowHeight); | |
lp.height = windowRatio < videoRatio ? windowHeight : (int) (windowWidth / videoRatio); | |
} else { | |
boolean full = layout == VIDEO_LAYOUT_STRETCH; | |
lp.width = (full || windowRatio < videoRatio) ? windowWidth : (int) (videoRatio * windowHeight); | |
lp.height = (full || windowRatio > videoRatio) ? windowHeight : (int) (windowWidth / videoRatio); | |
} | |
if (videoWidth > 800 && !isTablet(mContext)) { | |
setRotation(90.0f); | |
float scale = (videoWidth * 1.0f) / (videoHeight * 1.0f); | |
setScaleX(scale); | |
setScaleY(scale); | |
} | |
setLayoutParams(lp); | |
//getHolder().setFixedSize(surfaceWidth, surfaceHeight); | |
setMeasuredDimension(surfaceWidth, surfaceHeight); | |
DebugLog.dfmt( | |
TAG, | |
"VIDEO: %dx%dx%f[SAR:%d:%d], Surface: %dx%d, LP: %dx%d, Window: %dx%dx%f", | |
videoWidth, videoHeight, videoRatio, mVideoSarNum, | |
mVideoSarDen, surfaceWidth, surfaceHeight, lp.width, | |
lp.height, windowWidth, windowHeight, windowRatio); | |
} | |
mVideoLayout = layout; | |
} | |
public static boolean isTablet(Context context) { | |
return (context.getResources().getConfiguration().screenLayout | |
& Configuration.SCREENLAYOUT_SIZE_MASK) | |
>= Configuration.SCREENLAYOUT_SIZE_LARGE; | |
} | |
// Listeners | |
OnVideoSizeChangedListener mSizeChangedListener = new OnVideoSizeChangedListener() { | |
public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNum, int sarDen) { | |
DebugLog.dfmt(TAG, "onVideoSizeChanged: (%dx%d) - (%dx%d)", width, height, sarNum, sarDen); | |
videoWidth = mp.getVideoWidth(); | |
videoHeight = mp.getVideoHeight(); | |
mVideoSarNum = sarNum; | |
mVideoSarDen = sarDen; | |
if (videoWidth != 0 && videoHeight != 0) { | |
setVideoLayout(mVideoLayout); | |
} | |
} | |
}; | |
OnPreparedListener mPreparedListener = new OnPreparedListener() { | |
public void onPrepared(IMediaPlayer mp) { | |
DebugLog.d(TAG, "onPrepared"); | |
mCurrentState = STATE_PREPARED; | |
mTargetState = STATE_PLAYING; | |
if (mOnPreparedListener != null) | |
mOnPreparedListener.onPrepared(mMediaPlayer); | |
if (mMediaController != null) | |
mMediaController.setEnabled(true); | |
videoWidth = mp.getVideoWidth(); | |
videoHeight = mp.getVideoHeight(); | |
long seekToPosition = mSeekWhenPrepared; | |
if (seekToPosition != 0) | |
seekTo(seekToPosition); | |
if (videoWidth != 0 && videoHeight != 0) { | |
setVideoLayout(mVideoLayout); | |
if (surfaceWidth == videoWidth && surfaceHeight == videoHeight) { | |
if (mTargetState == STATE_PLAYING) { | |
start(); | |
if (mMediaController != null) | |
mMediaController.show(); | |
} else if (!isPlaying() | |
&& (seekToPosition != 0 || getCurrentPosition() > 0)) { | |
if (mMediaController != null) | |
mMediaController.show(0); | |
} | |
} | |
} else if (mTargetState == STATE_PLAYING) { | |
start(); | |
} | |
} | |
}; | |
private OnCompletionListener mCompletionListener = new OnCompletionListener() { | |
public void onCompletion(IMediaPlayer mp) { | |
DebugLog.d(TAG, "onCompletion"); | |
mCurrentState = STATE_PLAYBACK_COMPLETED; | |
mTargetState = STATE_PLAYBACK_COMPLETED; | |
mSurface.release(); | |
if (mMediaController != null) | |
mMediaController.hide(); | |
if (mOnCompletionListener != null) | |
mOnCompletionListener.onCompletion(mMediaPlayer); | |
} | |
}; | |
private OnErrorListener mErrorListener = new OnErrorListener() { | |
public boolean onError(IMediaPlayer mp, int framework_err, int impl_err) { | |
DebugLog.dfmt(TAG, "Error: %d, %d", framework_err, impl_err); | |
mCurrentState = STATE_ERROR; | |
mTargetState = STATE_ERROR; | |
if (mMediaController != null) | |
mMediaController.hide(); | |
if (mOnErrorListener != null) { | |
if (mOnErrorListener.onError(mMediaPlayer, framework_err, | |
impl_err)) | |
return true; | |
} | |
if (getWindowToken() != null) { | |
int message = framework_err == IMediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK ? R.string.videoview_error_text_invalid_progressive_playback | |
: R.string.videoview_error_text_unknown; | |
new AlertDialog.Builder(mContext) | |
.setTitle(R.string.videoview_error_title) | |
.setMessage(message) | |
.setPositiveButton( | |
R.string.videoview_error_button, | |
new DialogInterface.OnClickListener() { | |
public void onClick(DialogInterface dialog, int whichButton) { | |
if (mOnCompletionListener != null) | |
mOnCompletionListener | |
.onCompletion(mMediaPlayer); | |
} | |
}).setCancelable(false).show(); | |
} | |
return true; | |
} | |
}; | |
private OnBufferingUpdateListener mBufferingUpdateListener = new OnBufferingUpdateListener() { | |
public void onBufferingUpdate(IMediaPlayer mp, int percent) { | |
mCurrentBufferPercentage = percent; | |
if (mOnBufferingUpdateListener != null) | |
mOnBufferingUpdateListener.onBufferingUpdate(mp, percent); | |
} | |
}; | |
private OnInfoListener mInfoListener = new OnInfoListener() { | |
@Override | |
public boolean onInfo(IMediaPlayer mp, int what, int extra) { | |
DebugLog.dfmt(TAG, "onInfo: (%d, %d)", what, extra); | |
if (mOnInfoListener != null) { | |
mOnInfoListener.onInfo(mp, what, extra); | |
} else if (mMediaPlayer != null) { | |
if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_START) { | |
DebugLog.dfmt(TAG, "onInfo: (MEDIA_INFO_BUFFERING_START)"); | |
if (mMediaBufferingIndicator != null) | |
mMediaBufferingIndicator.setVisibility(View.VISIBLE); | |
} else if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_END) { | |
DebugLog.dfmt(TAG, "onInfo: (MEDIA_INFO_BUFFERING_END)"); | |
if (mMediaBufferingIndicator != null) | |
mMediaBufferingIndicator.setVisibility(View.GONE); | |
} | |
} | |
return true; | |
} | |
}; | |
private OnSeekCompleteListener mSeekCompleteListener = new OnSeekCompleteListener() { | |
@Override | |
public void onSeekComplete(IMediaPlayer mp) { | |
DebugLog.d(TAG, "onSeekComplete"); | |
if (mOnSeekCompleteListener != null) | |
mOnSeekCompleteListener.onSeekComplete(mp); | |
} | |
}; | |
public void setOnPreparedListener(OnPreparedListener l) { | |
mOnPreparedListener = l; | |
} | |
public void setOnCompletionListener(OnCompletionListener l) { | |
mOnCompletionListener = l; | |
} | |
public void setOnErrorListener(OnErrorListener l) { | |
mOnErrorListener = l; | |
} | |
public void setOnBufferingUpdateListener(OnBufferingUpdateListener l) { | |
mOnBufferingUpdateListener = l; | |
} | |
public void setOnSeekCompleteListener(OnSeekCompleteListener l) { | |
mOnSeekCompleteListener = l; | |
} | |
public void setOnInfoListener(OnInfoListener l) { | |
mOnInfoListener = l; | |
} | |
public static interface MediaControllListener { | |
public void onStart(); | |
public void onPause(); | |
public void onStop(); | |
public void onComplete(); | |
} | |
MediaControllListener mMediaControllListener; | |
public void setMediaControllListener(MediaControllListener mediaControllListener) { | |
mMediaControllListener = mediaControllListener; | |
} | |
TextureView.SurfaceTextureListener mSurfaceTextureListener = new SurfaceTextureListener() | |
{ | |
@Override | |
public void onSurfaceTextureSizeChanged(final SurfaceTexture surface, final int width, final int height) { | |
surfaceWidth = width; | |
surfaceHeight = height; | |
boolean isValidState = (mTargetState == STATE_PLAYING); | |
boolean hasValidSize = (videoWidth == width && videoHeight == height); | |
if (mMediaPlayer != null && isValidState && hasValidSize) { | |
if (mSeekWhenPrepared != 0) { | |
seekTo(mSeekWhenPrepared); | |
} | |
start(); | |
} | |
} | |
@Override | |
public void onSurfaceTextureAvailable(final SurfaceTexture ssurface, final int width, final int height) { | |
mSurface = new Surface(ssurface); | |
openVideo(); | |
} | |
@Override | |
public boolean onSurfaceTextureDestroyed(final SurfaceTexture ssurface) { | |
// after we return from this we can't use the mSurface any more | |
if (mSurface != null) { | |
mSurface.release(); | |
mSurface = null; | |
} | |
if (mMediaController != null) mMediaController.hide(); | |
release(true); | |
return true; | |
} | |
@Override | |
public void onSurfaceTextureUpdated(final SurfaceTexture surface) { | |
// do nothing | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment