本节使用系统的示例类VideoView继续SurfaceView类相关内容的讲解,以让大家能更深入理解Android系统中图形绘制基础类的实现原理。也许你会发现无法改变VideoView类的控制方面,我们可以通过重构VideoView类来实现更加个性化的播放器。

创新互联服务项目包括利川网站建设、利川网站制作、利川网页制作以及利川网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,利川网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到利川省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
下面是VideoView类的相关代码。
- public class VideoView extends SurfaceView implements MediaPlayerControl {
 - private String TAG = "VideoView";
 - // settable by the client
 - 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 int mVideoWidth;
 - private int mVideoHeight;
 - private int mSurfaceWidth;
 - private int mSurfaceHeight;
 - private MediaController mMediaController;
 - private OnCompletionListener mOnCompletionListener;
 - private MediaPlayer.OnPreparedListener mOnPreparedListener;
 - private int mCurrentBufferPercentage;
 - private OnErrorListener mOnErrorListener;
 - private int mSeekWhenPrepared; // recording the seek position while preparing
 - private boolean mCanPause;
 - private boolean mCanSeekBack;
 - private boolean mCanSeekForward;
 - public VideoView(Context context) {
 - super(context);
 - initVideoView();
 - }
 - public VideoView(Context context, AttributeSet attrs) {
 - this(context, attrs, 0);
 - initVideoView();
 - }
 - public VideoView(Context context, AttributeSet attrs, int defStyle) {
 - super(context, attrs, defStyle);
 - initVideoView();
 - }
 - @Override
 - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 - //Log.i("@@@@", "onMeasure");
 - int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
 - int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
 - if (mVideoWidth > 0 && mVideoHeight > 0) {
 - if ( mVideoWidth * height > width * mVideoHeight ) {
 - //Log.i("@@@", "image too tall, correcting");
 - height = width * mVideoHeight / mVideoWidth;
 - } else if ( mVideoWidth * height < width * mVideoHeight ) {
 - //Log.i("@@@", "image too wide, correcting");
 - width = height * mVideoWidth / mVideoHeight;
 - } else {
 - //Log.i("@@@", "aspect ratio is correct: " +
 - //width+"/"+height+"="+
 - //mVideoWidth+"/"+mVideoHeight);
 - }
 - }
 - //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
 - setMeasuredDimension(width, height);
 - }
 - public int resolveAdjustedSize(int desiredSize, int measureSpec) {
 - int result = desiredSize;
 - int specMode = MeasureSpec.getMode(measureSpec);
 - int specSize = MeasureSpec.getSize(measureSpec);
 - switch (specMode) {
 - case MeasureSpec.UNSPECIFIED:
 - /* Parent says we can be as big as we want. Just don't be larger
 - * than max size imposed on ourselves.
 - */
 - result = desiredSize;
 - break;
 - case MeasureSpec.AT_MOST:
 - /* Parent says we can be as big as we want, up to specSize.
 - * Don't be larger than specSize, and don't be larger than
 - * the max size imposed on ourselves.
 - */
 - result = Math.min(desiredSize, specSize);
 - break;
 - case MeasureSpec.EXACTLY:
 - // No choice. Do what we are told.
 - result = specSize;
 - break;
 - }
 - return result;
 - }
 - private void initVideoView() {
 - mVideoWidth = 0;
 - mVideoHeight = 0;
 - getHolder().addCallback(mSHCallback);
 - getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 - setFocusable(true);
 - setFocusableInTouchMode(true);
 - requestFocus();
 - mCurrentState = STATE_IDLE;
 - mTargetState = STATE_IDLE;
 - }
 - public void setVideoPath(String path) {
 - setVideoURI(Uri.parse(path));
 - }
 - public void setVideoURI(Uri uri) {
 - mUri = uri;
 - mSeekWhenPrepared = 0;
 - openVideo();
 - requestLayout();
 - invalidate();
 - }
 - public void stopPlayback() {
 - if (mMediaPlayer != null) {
 - mMediaPlayer.stop();
 - mMediaPlayer.release();
 - mMediaPlayer = null;
 - mCurrentState = STATE_IDLE;
 - mTargetState = STATE_IDLE;
 - }
 - }
 - private void openVideo() {
 - if (mUri == null || mSurfaceHolder == null) {
 - // not ready for playback just yet, will try again later
 - return;
 - }
 - // Tell the music playback service to pause
 - // TODO: these constants need to be published somewhere in the framework.
 - Intent i = new Intent("com.android.music.musicservicecommand");
 - i.putExtra("command", "pause");
 - mContext.sendBroadcast(i);
 - // we shouldn't clear the target state, because somebody might have
 - // called start() previously
 - release(false);
 - try {
 - mMediaPlayer = new MediaPlayer();
 - mMediaPlayer.setOnPreparedListener(mPreparedListener);
 - mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
 - mDuration = -1;
 - mMediaPlayer.setOnCompletionListener(mCompletionListener);
 - mMediaPlayer.setOnErrorListener(mErrorListener);
 - mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
 - mCurrentBufferPercentage = 0;
 - mMediaPlayer.setDataSource(mContext, mUri);
 - mMediaPlayer.setDisplay(mSurfaceHolder); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 - mMediaPlayer.setScreenOnWhilePlaying(true);
 - mMediaPlayer.prepareAsync();
 - // we don't set the target state here either, but preserve the
 - // target state that was there before.
 - mCurrentState = STATE_PREPARING;
 - attachMediaController();
 - } catch (IOException ex) {
 - Log.w(TAG, "Unable to open content: " + mUri, ex);
 - mCurrentState = STATE_ERROR;
 - mTargetState = STATE_ERROR;
 - mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
 - return;
 - } catch (IllegalArgumentException ex) {
 - Log.w(TAG, "Unable to open content: " + mUri, ex);
 - mCurrentState = STATE_ERROR;
 - mTargetState = STATE_ERROR;
 - mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
 - return;
 - }
 - }
 - public void setMediaController(MediaController controller) {
 - if (mMediaController != null) {
 - mMediaController.hide();
 - }
 - mMediaController = controller;
 - attachMediaController();
 - }
 - 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());
 - }
 - }
 - MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
 - new MediaPlayer.OnVideoSizeChangedListener() {
 - public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
 - mVideoWidth = mp.getVideoWidth();
 - mVideoHeight = mp.getVideoHeight();
 - if (mVideoWidth != 0 && mVideoHeight != 0) {
 - getHolder().setFixedSize(mVideoWidth, mVideoHeight);
 - }
 - }
 - };
 - MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
 - public void onPrepared(MediaPlayer mp) {
 - mCurrentState = STATE_PREPARED;
 - // Get the capabilities of the player for this stream
 - Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,
 - MediaPlayer.BYPASS_METADATA_FILTER);
 - if (data != null) {
 - mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)
 - || data.getBoolean(Metadata.PAUSE_AVAILABLE);
 - mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)
 - || data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);
 - mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)
 - || data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);
 - } else {
 - mCanPause = mCanSeekForward = mCanSeekForward = true;
 - }
 - if (mOnPreparedListener != null) {
 - mOnPreparedListener.onPrepared(mMediaPlayer);
 - }
 - if (mMediaController != null) {
 - mMediaController.setEnabled(true);
 - }
 - 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);
 - if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) {
 - // 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 (mTargetState == STATE_PLAYING) {
 - start();
 - if (mMediaController != null) {
 - mMediaController.show();
 - }
 - } else if (!isPlaying() &&
 - (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);
 - }
 - }
 - }
 - } else {
 - // We don't know the video size yet, but should start anyway.
 - // The video size might be reported to us later.
 - if (mTargetState == STATE_PLAYING) {
 - start();
 - }
 - }
 - }
 - };
 - private MediaPlayer.OnCompletionListener mCompletionListener =
 - new MediaPlayer.OnCompletionListener() {
 - public void onCompletion(MediaPlayer mp) {
 - mCurrentState = STATE_PLAYBACK_COMPLETED;
 - mTargetState = STATE_PLAYBACK_COMPLETED;
 - if (mMediaController != null) {
 - mMediaController.hide();
 - }
 - if (mOnCompletionListener != null) { mOnCompletionListener.onCompletion(mMediaPlayer);
 - }
 - }
 - };
 - private MediaPlayer.OnErrorListener mErrorListener =
 - 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();
 - }
 - /* If an error handler has been supplied, use it and finish. */
 - if (mOnErrorListener != null) {
 - if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {
 - return true;
 - }
 - }
 - /* Otherwise, pop up an error dialog so the user knows that
 - * something bad has happened. Only try and pop up the dialog
 - * if we're attached to a window. When we're going away and no
 - * longer have a window, don't bother showing the user an error.
 - */
 - if (getWindowToken() != null) {
 - Resources r = mContext.getResources();
 - int messageId;
 - if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
 - messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
 - } else {
 - messageId = com.android.internal.R.string.VideoView_error_text_unknown;
 - }
 - new AlertDialog.Builder(mContext)
 - .setTitle(com.android.internal.R.string.VideoView_error_title)
 - .setMessage(messageId)
 - .setPositiveButton(com.android.internal.R.string.VideoView_error_button,
 - new DialogInterface.OnClickListener() {
 - public void onClick(DialogInterface dialog, int whichButton) {
 - /* If we get here, there is no onError listener, so
 - * at least inform them that the video is over.
 - */
 - if (mOnCompletionListener != null) {
 - mOnCompletionListener.onCompletion(mMediaPlayer);
 - }
 - }
 - })
 - .setCancelable(false)
 - .show();
 - }
 - return true;
 - }
 - };
 - private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
 - new MediaPlayer.OnBufferingUpdateListener() {
 - public void onBufferingUpdate(MediaPlayer mp, int percent) {
 - mCurrentBuffe
 新闻标题:Android游戏开发之九:VideoView类实例讲解
网页路径:http://www.csdahua.cn/qtweb/news5/244955.html网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网