Android游戏开发之九:VideoView类实例讲解

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

创新互联服务项目包括利川网站建设、利川网站制作、利川网页制作以及利川网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,利川网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到利川省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

下面是VideoView类的相关代码。

 
 
  1.     public class VideoView extends SurfaceView implements MediaPlayerControl {    
  2.         private String TAG = "VideoView";    
  3.         // settable by the client    
  4.         private Uri         mUri;    
  5.         private int         mDuration;    
  6.         // all possible internal states    
  7.         private static final int STATE_ERROR              = -1;    
  8.         private static final int STATE_IDLE               = 0;    
  9.         private static final int STATE_PREPARING          = 1;    
  10.         private static final int STATE_PREPARED           = 2;    
  11.         private static final int STATE_PLAYING            = 3;    
  12.         private static final int STATE_PAUSED             = 4;    
  13.         private static final int STATE_PLAYBACK_COMPLETED = 5;    
  14.         // mCurrentState is a VideoView object's current state.    
  15.         // mTargetState is the state that a method caller intends to reach.    
  16.         // For instance, regardless the VideoView object's current state,    
  17.         // calling pause() intends to bring the object to a target state    
  18.         // of STATE_PAUSED.    
  19.         private int mCurrentState = STATE_IDLE;    
  20.         private int mTargetState  = STATE_IDLE;    
  21.         // All the stuff we need for playing and showing a video    
  22.         private SurfaceHolder mSurfaceHolder = null;    
  23.         private MediaPlayer mMediaPlayer = null;    
  24.         private int         mVideoWidth;    
  25.         private int         mVideoHeight;    
  26.         private int         mSurfaceWidth;    
  27.         private int         mSurfaceHeight;    
  28.         private MediaController mMediaController;    
  29.         private OnCompletionListener mOnCompletionListener;    
  30.         private MediaPlayer.OnPreparedListener mOnPreparedListener;    
  31.         private int         mCurrentBufferPercentage;    
  32.         private OnErrorListener mOnErrorListener;    
  33.         private int         mSeekWhenPrepared;  // recording the seek position while preparing    
  34.         private boolean     mCanPause;    
  35.         private boolean     mCanSeekBack;    
  36.         private boolean     mCanSeekForward;    
  37.         public VideoView(Context context) {    
  38.             super(context);    
  39.             initVideoView();    
  40.         }    
  41.         public VideoView(Context context, AttributeSet attrs) {    
  42.             this(context, attrs, 0);    
  43.             initVideoView();    
  44.         }    
  45.         public VideoView(Context context, AttributeSet attrs, int defStyle) {    
  46.             super(context, attrs, defStyle);    
  47.             initVideoView();    
  48.         }    
  49.         @Override   
  50.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    
  51.             //Log.i("@@@@", "onMeasure");    
  52.             int width = getDefaultSize(mVideoWidth, widthMeasureSpec);    
  53.             int height = getDefaultSize(mVideoHeight, heightMeasureSpec);    
  54.             if (mVideoWidth > 0 && mVideoHeight > 0) {    
  55.                 if ( mVideoWidth * height  > width * mVideoHeight ) {    
  56.                     //Log.i("@@@", "image too tall, correcting");    
  57.                     height = width * mVideoHeight / mVideoWidth;    
  58.                 } else if ( mVideoWidth * height  < width * mVideoHeight ) {    
  59.                     //Log.i("@@@", "image too wide, correcting");    
  60.                     width = height * mVideoWidth / mVideoHeight;    
  61.                 } else {    
  62.                     //Log.i("@@@", "aspect ratio is correct: " +    
  63.                             //width+"/"+height+"="+    
  64.                             //mVideoWidth+"/"+mVideoHeight);    
  65.                 }    
  66.             }    
  67.             //Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);    
  68.             setMeasuredDimension(width, height);    
  69.         }    
  70.         public int resolveAdjustedSize(int desiredSize, int measureSpec) {    
  71.             int result = desiredSize;    
  72.             int specMode = MeasureSpec.getMode(measureSpec);    
  73.             int specSize =  MeasureSpec.getSize(measureSpec);    
  74.             switch (specMode) {    
  75.                 case MeasureSpec.UNSPECIFIED:    
  76.                     /* Parent says we can be as big as we want. Just don't be larger   
  77.                      * than max size imposed on ourselves.   
  78.                      */   
  79.                     result = desiredSize;    
  80.                     break;    
  81.                 case MeasureSpec.AT_MOST:    
  82.                     /* Parent says we can be as big as we want, up to specSize.    
  83.                      * Don't be larger than specSize, and don't be larger than    
  84.                      * the max size imposed on ourselves.   
  85.                      */   
  86.                     result = Math.min(desiredSize, specSize);    
  87.                     break;    
  88.                 case MeasureSpec.EXACTLY:    
  89.                     // No choice. Do what we are told.    
  90.                     result = specSize;    
  91.                     break;    
  92.             }    
  93.             return result;    
  94.     }    
  95.         private void initVideoView() {    
  96.             mVideoWidth = 0;    
  97.             mVideoHeight = 0;    
  98.             getHolder().addCallback(mSHCallback);    
  99. getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    
  100.             setFocusable(true);    
  101.             setFocusableInTouchMode(true);    
  102.             requestFocus();    
  103.             mCurrentState = STATE_IDLE;    
  104.             mTargetState  = STATE_IDLE;    
  105.         }    
  106.         public void setVideoPath(String path) {    
  107.             setVideoURI(Uri.parse(path));    
  108.         }    
  109.         public void setVideoURI(Uri uri) {    
  110.             mUri = uri;    
  111.             mSeekWhenPrepared = 0;    
  112.             openVideo();    
  113.             requestLayout();    
  114.             invalidate();    
  115.         }    
  116.         public void stopPlayback() {    
  117.             if (mMediaPlayer != null) {    
  118.                 mMediaPlayer.stop();    
  119.                 mMediaPlayer.release();    
  120.                 mMediaPlayer = null;    
  121.                 mCurrentState = STATE_IDLE;    
  122.                 mTargetState  = STATE_IDLE;    
  123.             }    
  124.         }    
  125.         private void openVideo() {    
  126.             if (mUri == null || mSurfaceHolder == null) {    
  127.                 // not ready for playback just yet, will try again later    
  128.                 return;    
  129.             }    
  130.             // Tell the music playback service to pause     
  131.             // TODO: these constants need to be published somewhere in the framework.    
  132.             Intent i = new Intent("com.android.music.musicservicecommand");    
  133.             i.putExtra("command", "pause");    
  134.             mContext.sendBroadcast(i);    
  135.             // we shouldn't clear the target state, because somebody might have    
  136.             // called start() previously    
  137.             release(false);    
  138.             try {    
  139.                 mMediaPlayer = new MediaPlayer();    
  140. mMediaPlayer.setOnPreparedListener(mPreparedListener);    
  141. mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);  
  142.                 mDuration = -1;    
  143. mMediaPlayer.setOnCompletionListener(mCompletionListener);    
  144. mMediaPlayer.setOnErrorListener(mErrorListener);    
  145. mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);    
  146.                 mCurrentBufferPercentage = 0;    
  147.                 mMediaPlayer.setDataSource(mContext, mUri);    
  148.                 mMediaPlayer.setDisplay(mSurfaceHolder);   mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);    
  149.                 mMediaPlayer.setScreenOnWhilePlaying(true);    
  150.                 mMediaPlayer.prepareAsync();    
  151.                 // we don't set the target state here either, but preserve the    
  152.                 // target state that was there before.    
  153.                 mCurrentState = STATE_PREPARING;    
  154.                 attachMediaController();    
  155.             } catch (IOException ex) {    
  156.                 Log.w(TAG, "Unable to open content: " + mUri, ex);    
  157.                 mCurrentState = STATE_ERROR;    
  158.                 mTargetState = STATE_ERROR;    
  159.                 mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);    
  160.                 return;    
  161.             } catch (IllegalArgumentException ex) {    
  162.                 Log.w(TAG, "Unable to open content: " + mUri, ex);    
  163.                 mCurrentState = STATE_ERROR;    
  164.                 mTargetState = STATE_ERROR;    
  165.                 mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);    
  166.                 return;    
  167.             }    
  168.         }    
  169.         public void setMediaController(MediaController controller) {    
  170.             if (mMediaController != null) {    
  171.                 mMediaController.hide();    
  172.             }    
  173.             mMediaController = controller;    
  174.             attachMediaController();    
  175.         }    
  176.         private void attachMediaController() {    
  177.             if (mMediaPlayer != null && mMediaController != null) {    
  178.                 mMediaController.setMediaPlayer(this);    
  179.                 View anchorView = this.getParent() instanceof View ?    
  180.                         (View)this.getParent() : this;    
  181.                 mMediaController.setAnchorView(anchorView);   mMediaController.setEnabled(isInPlaybackState());    
  182.             }    
  183.         }    
  184.         MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =    
  185.             new MediaPlayer.OnVideoSizeChangedListener() {    
  186.                 public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {    
  187.                     mVideoWidth = mp.getVideoWidth();    
  188.                     mVideoHeight = mp.getVideoHeight();    
  189.                     if (mVideoWidth != 0 && mVideoHeight != 0) {    
  190.                         getHolder().setFixedSize(mVideoWidth, mVideoHeight);    
  191.                     }    
  192.                 }    
  193.         };    
  194.         MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {    
  195.             public void onPrepared(MediaPlayer mp) {    
  196.                 mCurrentState = STATE_PREPARED;    
  197.                 // Get the capabilities of the player for this stream    
  198.                 Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,    
  199.                                           MediaPlayer.BYPASS_METADATA_FILTER);    
  200.                 if (data != null) {    
  201.                     mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)    
  202.                             || data.getBoolean(Metadata.PAUSE_AVAILABLE);    
  203.                     mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)    
  204.                             || data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);    
  205.                     mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)    
  206.                             || data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);    
  207.                 } else {    
  208.                     mCanPause = mCanSeekForward = mCanSeekForward = true;    
  209.                 }    
  210.                 if (mOnPreparedListener != null) {    
  211.                     mOnPreparedListener.onPrepared(mMediaPlayer);    
  212.                 }    
  213.                 if (mMediaController != null) {    
  214.                     mMediaController.setEnabled(true);    
  215.                 }    
  216.                 mVideoWidth = mp.getVideoWidth();    
  217.                 mVideoHeight = mp.getVideoHeight();    
  218.                 int seekToPosition = mSeekWhenPrepared;  // mSeekWhenPrepared may be changed after seekTo() call    
  219.                 if (seekToPosition != 0) {    
  220.                     seekTo(seekToPosition);    
  221.                 }    
  222.                 if (mVideoWidth != 0 && mVideoHeight != 0) {    
  223.                     //Log.i("@@@@", "video size: " + mVideoWidth +"/"+ mVideoHeight);    
  224.                     getHolder().setFixedSize(mVideoWidth, mVideoHeight);    
  225.                     if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) {    
  226.                         // We didn't actually change the size (it was already at the size    
  227.                         // we need), so we won't get a "surface changed" callback, so    
  228.                         // start the video here instead of in the callback.    
  229.                         if (mTargetState == STATE_PLAYING) {    
  230.                             start();    
  231.                             if (mMediaController != null) {    
  232.                                 mMediaController.show();    
  233.                             }    
  234.                         } else if (!isPlaying() &&    
  235.                                    (seekToPosition != 0 || getCurrentPosition() > 0)) {    
  236.                            if (mMediaController != null) {    
  237.                                // Show the media controls when we're paused into a video and make 'em stick.    
  238.                                mMediaController.show(0);    
  239.                            }    
  240.                        }    
  241.                     }    
  242.                 } else {    
  243.                     // We don't know the video size yet, but should start anyway.    
  244.                     // The video size might be reported to us later.    
  245.                     if (mTargetState == STATE_PLAYING) {    
  246.                         start();    
  247.                     }    
  248.                 }    
  249.             }    
  250.         };    
  251.         private MediaPlayer.OnCompletionListener mCompletionListener =    
  252.             new MediaPlayer.OnCompletionListener() {    
  253.             public void onCompletion(MediaPlayer mp) {    
  254.                 mCurrentState = STATE_PLAYBACK_COMPLETED;    
  255.                 mTargetState = STATE_PLAYBACK_COMPLETED;    
  256.                 if (mMediaController != null) {    
  257.                     mMediaController.hide();    
  258.                 }    
  259.                 if (mOnCompletionListener != null) {   mOnCompletionListener.onCompletion(mMediaPlayer);    
  260.                 }    
  261.             }    
  262.         };    
  263.         private MediaPlayer.OnErrorListener mErrorListener =    
  264.             new MediaPlayer.OnErrorListener() {    
  265.             public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {    
  266.                 Log.d(TAG, "Error: " + framework_err + "," + impl_err);    
  267.                 mCurrentState = STATE_ERROR;    
  268.                 mTargetState = STATE_ERROR;    
  269.                 if (mMediaController != null) {    
  270.                     mMediaController.hide();    
  271.                 }    
  272.                 /* If an error handler has been supplied, use it and finish. */   
  273.                 if (mOnErrorListener != null) {    
  274.                     if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {    
  275.                         return true;    
  276.                     }    
  277.                 }    
  278.                 /* Otherwise, pop up an error dialog so the user knows that   
  279.                  * something bad has happened. Only try and pop up the dialog   
  280.                  * if we're attached to a window. When we're going away and no   
  281.                  * longer have a window, don't bother showing the user an error.   
  282.                  */   
  283.                 if (getWindowToken() != null) {    
  284.                     Resources r = mContext.getResources();    
  285.                     int messageId;    
  286.                     if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {    
  287.                         messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;    
  288.                     } else {    
  289.                         messageId = com.android.internal.R.string.VideoView_error_text_unknown;    
  290.                     }    
  291.                     new AlertDialog.Builder(mContext)    
  292. .setTitle(com.android.internal.R.string.VideoView_error_title)    
  293.                             .setMessage(messageId)    
  294.                             .setPositiveButton(com.android.internal.R.string.VideoView_error_button,    
  295.                                     new DialogInterface.OnClickListener() {    
  296.                                         public void onClick(DialogInterface dialog, int whichButton) {    
  297.                                             /* If we get here, there is no onError listener, so   
  298.                                              * at least inform them that the video is over.   
  299.                                              */   
  300.                                             if (mOnCompletionListener != null) {    
  301. mOnCompletionListener.onCompletion(mMediaPlayer);    
  302.                                             }    
  303.                                         }    
  304.                                     })    
  305.                             .setCancelable(false)    
  306.                             .show();    
  307.                 }    
  308.                 return true;    
  309.             }    
  310.         };    
  311.         private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =    
  312.             new MediaPlayer.OnBufferingUpdateListener() {    
  313.             public void onBufferingUpdate(MediaPlayer mp, int percent) {    
  314.                 mCurrentBuffe

    当前名称:Android游戏开发之九:VideoView类实例讲解
    地址分享:http://www.hantingmc.com/qtweb/news5/244955.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联