zoukankan      html  css  js  c++  java
  • Android自己定制MediaController

       今天终于把这个给调通了。怪自己太笨。留着

     我把三个主要的类公布:先是MediaController

    /*
     * Copyright (C) 2006 The Android Open Source Project
     * Copyright (C) 2013 YIXIA.COM
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package com.android.widget;
    
    import android.annotation.SuppressLint;
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.graphics.Rect;
    import android.media.AudioManager;
    import android.os.Build;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    import android.widget.ImageButton;
    import android.widget.PopupWindow;
    import android.widget.SeekBar;
    import android.widget.SeekBar.OnSeekBarChangeListener;
    import android.widget.TextView;
    
    import java.lang.reflect.Method;
    
    import com.android.widget.OutlineTextView;
    import com.example.revideoview.R;
    
    //import io.vov.vitamio.utils.Log;
    
    /**
     * 针对普通播放的MediaController
     * 
     * @author Catherine
     * 
     */
    public class MediaController extends FrameLayout {
        private static final int sDefaultTimeout = 3000;
        private static final int FADE_OUT = 1;
        private static final int SHOW_PROGRESS = 2;
        private MediaPlayerControl mPlayer;
        private Context mContext;
        private PopupWindow mWindow;
        private int mAnimStyle;
        private View mAnchor;
        private View mRoot;
        private SeekBar mProgress;
        private TextView mEndTime, mCurrentTime;
        private TextView mFileName;
        private OutlineTextView mInfoView;
        private String mTitle;
        private long mDuration;
        private boolean mShowing;
        private boolean mDragging;
        private boolean mInstantSeeking = true;
        private boolean mFromXml = false;
        private ImageButton mPauseButton;
        private AudioManager mAM;
        private OnShownListener mShownListener;
        private OnHiddenListener mHiddenListener;
        @SuppressLint("HandlerLeak")
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                long pos;
                switch (msg.what) {
                case FADE_OUT:
                    hide();
                    break;
                case SHOW_PROGRESS:
                    pos = setProgress();
                    if (!mDragging && mShowing) {
                        msg = obtainMessage(SHOW_PROGRESS);
                        sendMessageDelayed(msg, 1000 - (pos % 1000));
                        updatePausePlay();
                    }
                    break;
                }
            }
        };
        private View.OnClickListener mPauseListener = new View.OnClickListener() {
            public void onClick(View v) {
                System.out.println("dot the pause");
                doPauseResume();
                show(sDefaultTimeout);
            }
        };
        private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
            public void onStartTrackingTouch(SeekBar bar) {
                mDragging = true;
                show(3600000);
                mHandler.removeMessages(SHOW_PROGRESS);
                if (mInstantSeeking)
                    mAM.setStreamMute(AudioManager.STREAM_MUSIC, true);
                if (mInfoView != null) {
                    mInfoView.setText("");
                    mInfoView.setVisibility(View.VISIBLE);
                }
            }
    
            public void onProgressChanged(SeekBar bar, int progress,
                    boolean fromuser) {
                if (!fromuser)
                    return;
    
                long newposition = (mDuration * progress) / 1000;
                String time = StringTools.generateTime(newposition);
                if (mInstantSeeking)
                    mPlayer.seekTo(newposition);
                if (mInfoView != null)
                    mInfoView.setText(time);
                if (mCurrentTime != null)
                    mCurrentTime.setText(time);
            }
    
            public void onStopTrackingTouch(SeekBar bar) {
                if (!mInstantSeeking)
                    mPlayer.seekTo((mDuration * bar.getProgress()) / 1000);
                if (mInfoView != null) {
                    mInfoView.setText("");
                    mInfoView.setVisibility(View.GONE);
                }
                show(sDefaultTimeout);
                mHandler.removeMessages(SHOW_PROGRESS);
                mAM.setStreamMute(AudioManager.STREAM_MUSIC, false);
                mDragging = false;
                mHandler.sendEmptyMessageDelayed(SHOW_PROGRESS, 1000);
            }
        };
    
        public MediaController(Context context, AttributeSet attrs) {
            super(context, attrs);
            mRoot = this;
            mFromXml = true;
            initController(context);
        }
    
        public MediaController(Context context) {
            super(context);
            if (!mFromXml && initController(context))
                initFloatingWindow();
        }
    
        private boolean initController(Context context) {
            mContext = context;
            mAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
            return true;
        }
    
        @Override
        public void onFinishInflate() {
            if (mRoot != null)
                initControllerView(mRoot);
        }
    
        private void initFloatingWindow() {
            mWindow = new PopupWindow(mContext);
            mWindow.setFocusable(false);
            mWindow.setBackgroundDrawable(null);
            mWindow.setOutsideTouchable(true);
            mAnimStyle = android.R.style.Animation;
        }
    
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        public void setWindowLayoutType() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                try {
                    mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
                    Method setWindowLayoutType = PopupWindow.class.getMethod(
                            "setWindowLayoutType", new Class[] { int.class });
                    setWindowLayoutType
                            .invoke(mWindow,
                                    WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG);
                } catch (Exception e) {
                    // Log.e("setWindowLayoutType", e);
                }
            }
        }
    
        /**
         * Set the view that acts as the anchor for the control view. This can for
         * example be a VideoView, or your Activity's main view.
         * 
         * @param view
         *            The view to which to anchor the controller when it is visible.
         */
        public void setAnchorView(View view) {
            mAnchor = view;
            if (!mFromXml) {
                removeAllViews();
                mRoot = makeControllerView();
                mWindow.setContentView(mRoot);
                mWindow.setWidth(LayoutParams.MATCH_PARENT);
                mWindow.setHeight(LayoutParams.WRAP_CONTENT);
            }
            initControllerView(mRoot);
        }
    
        /**
         * Create the view that holds the widgets that control playback. Derived
         * classes can override this to create their own.
         * 
         * @return The controller view.
         */
        protected View makeControllerView() {
            return ((LayoutInflater) mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                    R.layout.mediacontroller, this);
        }
    
        private void initControllerView(View v) {
            mPauseButton = (ImageButton) v
                    .findViewById(R.id.mediacontroller_play_pause);
            if (mPauseButton != null) {
                mPauseButton.requestFocus();
                mPauseButton.setOnClickListener(mPauseListener);
            }
    
            mProgress = (SeekBar) v.findViewById(R.id.mediacontroller_seekbar);
            if (mProgress != null) {
                if (mProgress instanceof SeekBar) {
                    SeekBar seeker = (SeekBar) mProgress;
                    seeker.setOnSeekBarChangeListener(mSeekListener);
                    seeker.setThumbOffset(1);
                }
                mProgress.setMax(1000);
            }
    
            mEndTime = (TextView) v.findViewById(R.id.mediacontroller_time_total);
            mCurrentTime = (TextView) v
                    .findViewById(R.id.mediacontroller_time_current);
            mFileName = (TextView) v.findViewById(R.id.mediacontroller_file_name);
            if (mFileName != null)
                mFileName.setText(mTitle);
        }
    
        public void setMediaPlayer(MediaPlayerControl player) {
            mPlayer = player;
            updatePausePlay();
        }
    
        /**
         * Control the action when the seekbar dragged by user
         * 
         * @param seekWhenDragging
         *            True the media will seek periodically
         */
        public void setInstantSeeking(boolean seekWhenDragging) {
            mInstantSeeking = seekWhenDragging;
        }
    
        public void show() {
            show(sDefaultTimeout);
        }
    
        /**
         * Set the content of the file_name TextView
         * 
         * @param name
         */
        public void setFileName(String name) {
            mTitle = name;
            if (mFileName != null)
                mFileName.setText(mTitle);
        }
    
        /**
         * Set the View to hold some information when interact with the
         * MediaController
         * 
         * @param v
         */
        public void setInfoView(OutlineTextView v) {
            mInfoView = v;
        }
    
        private void disableUnsupportedButtons() {
            try {
                if (mPauseButton != null && !mPlayer.canPause())
                    mPauseButton.setEnabled(true);
            } catch (IncompatibleClassChangeError ex) {
            }
        }
    
        /**
         * <p>
         * Change the animation style resource for this controller.
         * </p>
         * <p/>
         * <p>
         * If the controller is showing, calling this method will take effect only
         * the next time the controller is shown.
         * </p>
         * 
         * @param animationStyle
         *            animation style to use when the controller appears and
         *            disappears. Set to -1 for the default animation, 0 for no
         *            animation, or a resource identifier for an explicit animation.
         */
        public void setAnimationStyle(int animationStyle) {
            mAnimStyle = animationStyle;
        }
    
        /**
         * Show the controller on screen. It will go away automatically after
         * 'timeout' milliseconds of inactivity.
         * 
         * @param timeout
         *            The timeout in milliseconds. Use 0 to show the controller
         *            until hide() is called.
         */
        public void show(int timeout) {
            if (!mShowing && mAnchor != null && mAnchor.getWindowToken() != null) {
                if (mPauseButton != null)
                    mPauseButton.requestFocus();
                disableUnsupportedButtons();
    
                if (mFromXml) {
                    setVisibility(View.VISIBLE);
                } else {
                    int[] location = new int[2];
    
                    mAnchor.getLocationOnScreen(location);
                    Rect anchorRect = new Rect(location[0], location[1],
                            location[0] + mAnchor.getWidth(), location[1]
                                    + mAnchor.getHeight());
    
                    mWindow.setAnimationStyle(mAnimStyle);
                    setWindowLayoutType();
                    mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY,
                            anchorRect.left, anchorRect.bottom);
                }
                mShowing = true;
                if (mShownListener != null)
                    mShownListener.onShown();
            }
            updatePausePlay();
            mHandler.sendEmptyMessage(SHOW_PROGRESS);
    
            if (timeout != 0) {
                mHandler.removeMessages(FADE_OUT);
                mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT),
                        timeout);
            }
        }
    
        public boolean isShowing() {
            return mShowing;
        }
    
        public void hide() {
            if (mAnchor == null)
                return;
    
            if (mShowing) {
                try {
                    mHandler.removeMessages(SHOW_PROGRESS);
                    if (mFromXml)
                        setVisibility(View.GONE);
                    else
                        mWindow.dismiss();
                } catch (IllegalArgumentException ex) {
                    // Log.d("MediaController already removed");
                }
                mShowing = false;
                if (mHiddenListener != null)
                    mHiddenListener.onHidden();
            }
        }
    
        public void setOnShownListener(OnShownListener l) {
            mShownListener = l;
        }
    
        public void setOnHiddenListener(OnHiddenListener l) {
            mHiddenListener = l;
        }
    
        private long setProgress() {
            if (mPlayer == null || mDragging)
                return 0;
    
            long position = mPlayer.getCurrentPosition();
            long duration = mPlayer.getDuration();
            if (mProgress != null) {
                if (duration > 0) {
                    long pos = 1000L * position / duration;
                    mProgress.setProgress((int) pos);
                }
                int percent = mPlayer.getBufferPercentage();
                mProgress.setSecondaryProgress(percent * 10);
            }
    
            mDuration = duration;
    
            if (mEndTime != null)
                mEndTime.setText(StringTools.generateTime(mDuration));
            if (mCurrentTime != null)
                mCurrentTime.setText(StringTools.generateTime(position));
    
            return position;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            show(sDefaultTimeout);
            return true;
        }
    
        @Override
        public boolean onTrackballEvent(MotionEvent ev) {
            show(sDefaultTimeout);
            return false;
        }
    
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            System.out.println("this is dispatchKeyEvent");
            int keyCode = event.getKeyCode();
            if (event.getRepeatCount() == 0
                    && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
                            || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) {
                doPauseResume();
                show(sDefaultTimeout);
                if (mPauseButton != null)
                    mPauseButton.requestFocus();
                return true;
            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
                if (mPlayer.isPlaying()) {
                    mPlayer.pause();
                    updatePausePlay();
                }
                return true;
            } else if (keyCode == KeyEvent.KEYCODE_BACK
                    || keyCode == KeyEvent.KEYCODE_MENU) {
                hide();
                return true;
            } else {
                show(sDefaultTimeout);
            }
            return super.dispatchKeyEvent(event);
        }
    
        private void updatePausePlay() {
            if (mRoot == null || mPauseButton == null)
                return;
    
            if (mPlayer.isPlaying())
                mPauseButton
                        .setImageResource(R.drawable.mediacontroller_pause_button);
            else
                mPauseButton
                        .setImageResource(R.drawable.mediacontroller_play_button);
        }
    
        private void doPauseResume() {
            if (mPlayer.isPlaying())
                mPlayer.pause();
            else
                mPlayer.start();
            updatePausePlay();
        }
    
        @Override
        public void setEnabled(boolean enabled) {
            if (mPauseButton != null)
                mPauseButton.setEnabled(enabled);
            if (mProgress != null)
                mProgress.setEnabled(enabled);
            disableUnsupportedButtons();
            super.setEnabled(enabled);
        }
    
        public interface OnShownListener {
            public void onShown();
        }
    
        public interface OnHiddenListener {
            public void onHidden();
        }
    
        public interface MediaPlayerControl {
            void start();
    
            void pause();
    
            long getDuration();
    
            long getCurrentPosition();
    
            void seekTo(long pos);
    
            boolean isPlaying();
    
            int getBufferPercentage();
    
            boolean canPause();
    
            boolean canSeekBackward();
    
            boolean canSeekForward();
        }
    
    }
    package com.android.widget;
    
    import java.io.IOException;
    
    import com.android.widget.CustomProgressDialog;
    import com.android.widget.MediaController.MediaPlayerControl;
    
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Rect;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnErrorListener;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.view.ViewGroup.LayoutParams;
    import android.widget.FrameLayout;
    
    /**
     * 针对普通播放的VideoView
     * 
     * @author Catherine
     * 
     */
    public class VideoView extends SurfaceView implements MediaPlayerControl,
            View.OnClickListener {
    
        private Context mContext;
    
        private String mUri = "";
    
        private int mDuration;
    
        // All the stuff we need for playing and showing a video
        private SurfaceHolder mSurfaceHolder = null;
        private MediaPlayer mMediaPlayer = null;
        private boolean mIsPrepared;
        public static int mVideoWidth;
        public static int mVideoHeight;
        private int mSurfaceWidth;
        private int mSurfaceHeight;
        private MediaController mMediaController;
        public OnCompletionListener mOnCompletionListener;
        private MediaPlayer.OnPreparedListener mOnPreparedListener;
        private int mCurrentBufferPercentage;
        private OnErrorListener mOnErrorListener;
        private boolean mStartWhenPrepared;
        private int mSeekWhenPrepared;
    
        private MySizeChangeLinstener mMyChangeLinstener;
    
        public int getVideoWidth() {
            return mVideoWidth;
        }
    
        public int getVideoHeight() {
            return mVideoHeight;
        }
    
        public void setVideoScale(int width, int height) {
            LayoutParams lp = getLayoutParams();
            lp.height = height;
            lp.width = width;
            setLayoutParams(lp);
        }
    
        public interface MySizeChangeLinstener {
            public void doMyThings();
        }
    
        public void setMySizeChangeLinstener(MySizeChangeLinstener l) {
            mMyChangeLinstener = l;
        }
    
        public VideoView(Context context) {
            super(context);
            mContext = context;
            initVideoView();
        }
    
        public VideoView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
            mContext = context;
            initVideoView();
        }
    
        public VideoView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            mContext = context;
            initVideoView();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // Log.i("@@@@", "onMeasure");
            int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
            int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
            setMeasuredDimension(width, height);
        }
    
        public void setVideofullScale(int width, int height) {
            FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams) getLayoutParams();
            lp.height = height;
            lp.width = width;
            lp.setMargins(0, 0, 0, 0);
            setLayoutParams(lp);
            getHolder().setFixedSize(width, height);
        }
    
        public void setVideoDefaultScale(int width, int height) {
            FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams) getLayoutParams();
            lp.height = height;
            lp.width = width;
            lp.setMargins(258, 85, 0, 0);
            setLayoutParams(lp);
            getHolder().setFixedSize(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:
    
                result = desiredSize;
                break;
    
            case MeasureSpec.AT_MOST:
    
                result = Math.min(desiredSize, specSize);
                break;
    
            case MeasureSpec.EXACTLY:
                // No choice. Do what we are told.
                result = specSize;
                break;
            }
            return result;
        }
    
        private CustomProgressDialog dialog;
    
        private WindowManager wm;
    
        private void initVideoView() {
            
            mVideoWidth = 0;
            mVideoHeight = 0;
            getHolder().addCallback(mSHCallback);
            getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            setFocusable(true);
            setFocusableInTouchMode(true);
            requestFocus();
    
            dialog = new CustomProgressDialog(mContext);
        }
    
        public void setVideoPath(String path) {
            setVideoURI(path);
        }
    
        public void setVideoURI(String uri) {
            mUri = uri;
            mStartWhenPrepared = false;
            mSeekWhenPrepared = 0;
            openVideo();
            requestLayout();
            invalidate();
        }
    
        public void stopPlayback() {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    
        private void openVideo() {
            if (mUri == null || mSurfaceHolder == null) {
    
                return;
            }
    
            if (mMediaPlayer != null) {
                mMediaPlayer.reset();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
            try {
                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setOnPreparedListener(mPreparedListener);
                mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
                mMediaPlayer.setOnInfoListener(mInfoListener);
                mIsPrepared = false;
                mDuration = -1;
                mMediaPlayer.setOnCompletionListener(mCompletionListener);
                mMediaPlayer.setOnErrorListener(mErrorListener);
                mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
                mCurrentBufferPercentage = 0;
                mMediaPlayer.setDataSource(mUri);
    
                mMediaPlayer.setDisplay(mSurfaceHolder);
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mMediaPlayer.setScreenOnWhilePlaying(true);
                mMediaPlayer.prepareAsync();
                attachMediaController();
            } catch (IOException ex) {
                return;
            } catch (IllegalArgumentException ex) {
                return;
            }
        }
    
        MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
    
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                WindowManager.LayoutParams params = new WindowManager.LayoutParams();
                params.gravity = Gravity.CENTER;
                params.width = LayoutParams.WRAP_CONTENT;
                params.height = LayoutParams.WRAP_CONTENT;
                switch (what) {
                case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                    if (dialog != null && !dialog.isShowing()) {
                        dialog.show();
                    }
                    break;
                case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                    if (dialog != null && dialog.isShowing()) {
                        dialog.cancel();
                    }
                    break;
                case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    if (dialog != null && dialog.isShowing()) {
                        dialog.cancel();
                    }
                    break;
                }
                return true;
            }
    
        };
    
        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(mIsPrepared);
            }
        }
    
        MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                mVideoWidth = mp.getVideoWidth();
                mVideoHeight = mp.getVideoHeight();
    
                if (mMyChangeLinstener != null) {
                    mMyChangeLinstener.doMyThings();
                }
    
                if (mVideoWidth != 0 && mVideoHeight != 0) {
                    getHolder().setFixedSize(mVideoWidth, mVideoHeight);
                }
            }
        };
    
        MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
            public void onPrepared(MediaPlayer mp) {
                // briefly show the mediacontroller
                mIsPrepared = true;
                if (mOnPreparedListener != null) {
                    mOnPreparedListener.onPrepared(mMediaPlayer);
                }
                if (mMediaController != null) {
                    mMediaController.setEnabled(true);
                }
                mVideoWidth = mp.getVideoWidth();
                mVideoHeight = mp.getVideoHeight();
                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 (mSeekWhenPrepared != 0) {
                            mMediaPlayer.seekTo(mSeekWhenPrepared);
                            mSeekWhenPrepared = 0;
                        }
                        if (mStartWhenPrepared) {
                            mMediaPlayer.start();
                            mStartWhenPrepared = false;
                            if (mMediaController != null) {
                                mMediaController.show();
                            }
                        } else if (!isPlaying()
                                && (mSeekWhenPrepared != 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 (mSeekWhenPrepared != 0) {
                        mMediaPlayer.seekTo(mSeekWhenPrepared);
                        mSeekWhenPrepared = 0;
                    }
                    if (mStartWhenPrepared) {
                        mMediaPlayer.start();
                        mStartWhenPrepared = false;
                    }
                }
            }
        };
    
        private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                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) {
                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;
                    }
                }
                if (getWindowToken() != null) {
                    Resources r = mContext.getResources();
                    int messageId;
                }
                return true;
            }
        };
    
        private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
            public void onBufferingUpdate(MediaPlayer mp, int percent) {
                mCurrentBufferPercentage = percent;
            }
        };
    
        /**
         * Register a callback to be invoked when the media file is loaded and ready
         * to go.
         * 
         * @param l
         *            The callback that will be run
         */
        public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
            mOnPreparedListener = l;
        }
    
        /**
         * Register a callback to be invoked when the end of a media file has been
         * reached during playback.
         * 
         * @param l
         *            The callback that will be run
         */
        public void setOnCompletionListener(OnCompletionListener l) {
            mOnCompletionListener = l;
        }
    
        /**
         * Register a callback to be invoked when an error occurs during playback or
         * setup. If no listener is specified, or if the listener returned false,
         * VideoView will inform the user of any errors.
         * 
         * @param l
         *            The callback that will be run
         */
        public void setOnErrorListener(OnErrorListener l) {
            mOnErrorListener = l;
        }
    
        SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() {
            public void surfaceChanged(SurfaceHolder holder, int format, int w,
                    int h) {
                mSurfaceWidth = w;
                mSurfaceHeight = h;
                if (mMediaPlayer != null && mIsPrepared && mVideoWidth == w
                        && mVideoHeight == h) {
                    if (mSeekWhenPrepared != 0) {
                        mMediaPlayer.seekTo(mSeekWhenPrepared);
                        mSeekWhenPrepared = 0;
                    }
                    mMediaPlayer.start();
                    if (mMediaController != null) {
                        mMediaController.show();
                    }
                }
            }
    
            public void surfaceCreated(SurfaceHolder holder) {
                mSurfaceHolder = holder;
                openVideo();
            }
    
            public void surfaceDestroyed(SurfaceHolder holder) {
                // after we return from this we can't use the surface any more
                mSurfaceHolder = null;
                if (mMediaController != null)
                    mMediaController.hide();
                if (mMediaPlayer != null) {
                    mMediaPlayer.reset();
                    mMediaPlayer.release();
                    mMediaPlayer = null;
                }
            }
        };
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (mIsPrepared && mMediaPlayer != null && mMediaController != null) {
                toggleMediaControlsVisiblity();
            }
            return false;
        }
    
        @Override
        public boolean onTrackballEvent(MotionEvent ev) {
            if (mIsPrepared && mMediaPlayer != null && mMediaController != null) {
                toggleMediaControlsVisiblity();
            }
            return false;
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            System.out.println("this is videoview keyevent");
    
            if (mIsPrepared && 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) {
                if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
                        || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
                        || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                    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 false;
        }
    
        private void toggleMediaControlsVisiblity() {
            // if (mMediaController.isShowing()) {
            // mMediaController.hide();
            // } else {
            mMediaController.show();
            if (mMediaController.isShowing() && mMediaPlayer.isPlaying()) {
                pause();
            } else {
                start();
            }
            // }
        }
    
        public void start() {
            if (mMediaPlayer != null && mIsPrepared) {
                mMediaPlayer.start();
                mStartWhenPrepared = false;
            } else {
                mStartWhenPrepared = true;
            }
        }
    
        public void pause() {
            if (mMediaPlayer != null && mIsPrepared) {
                if (mMediaPlayer.isPlaying()) {
                    mMediaPlayer.pause();
                }
            }
            mStartWhenPrepared = false;
        }
    
        public long getDuration() {
            if (mMediaPlayer != null && mIsPrepared) {
                if (mDuration > 0) {
                    return mDuration;
                }
                mDuration = mMediaPlayer.getDuration();
                return mDuration;
            }
            mDuration = -1;
            return mDuration;
        }
    
        public long getCurrentPosition() {
            if (mMediaPlayer != null && mIsPrepared) {
                return mMediaPlayer.getCurrentPosition();
            }
            return 0;
        }
    
        public void seekTo(int msec) {
            if (mMediaPlayer != null && mIsPrepared) {
                mMediaPlayer.seekTo(msec);
            } else {
                mSeekWhenPrepared = msec;
            }
        }
    
        public boolean isPlaying() {
            if (mMediaPlayer != null && mIsPrepared) {
                return mMediaPlayer.isPlaying();
            }
            return false;
        }
    
        public int getBufferPercentage() {
            if (mMediaPlayer != null) {
                return mCurrentBufferPercentage;
            }
            return 0;
        }
    
        public final static int A_DEFALT = 0; // 原始比例
        public final static int A_4X3 = 1;
        public final static int A_16X9 = 2;
        public final static int A_RAW = 4; // 原始大小
    
        /**
         * 全屏状态才可以使用选择比例
         * 
         * @param flg
         */
        public void selectScales(int flg) {
            if (getWindowToken() != null) {
                Rect rect = new Rect();
                getWindowVisibleDisplayFrame(rect);
    
                double height = rect.bottom - rect.top;
                double width = rect.right - rect.left;
    
                if (height <= 0.0 || width <= 0.0 || mVideoHeight <= 0.0
                        || mVideoWidth <= 0.0) {
                    return;
                }
                ViewGroup.LayoutParams param = getLayoutParams();
    
                switch (flg) {
                case A_DEFALT:
                    if (width / height >= mVideoWidth / mVideoHeight) { //
                        // 屏幕 宽了以屏幕高为基础
                        param.height = (int) height;
                        param.width = (int) (mVideoWidth * height / mVideoHeight);
                    } else { // 屏幕 高了 以宽为基础
                        param.width = (int) width;
                        param.height = (int) (mVideoHeight * width / mVideoWidth);
                    }
                    setLayoutParams(param);
                    break;
    
                case A_4X3:
                    if (width / height >= 4.0 / 3.0) {
                        // 屏幕 宽了 以屏幕高为基础
                        param.height = (int) height;
                        param.width = (int) (4 * height / 3);
                    } else { // 屏幕 高了 以宽为基础
                        param.width = (int) width;
                        param.height = (int) (3 * width / 4);
                    }
                    setLayoutParams(param);
                    break;
                case A_16X9:
                    if (width / height >= 16.0 / 9.0) {
                        // 屏幕 宽了 以屏幕高为基础
                        param.height = (int) height;
                        param.width = (int) (16 * height / 9);
                    } else { // 屏幕 高了 以宽为基础
                        param.width = (int) width;
                        param.height = (int) (9 * width / 16);
                    }
                    setLayoutParams(param);
                    break;
                }
    
            }
    
        }
    
        @Override
        public boolean canPause() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public boolean canSeekBackward() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public boolean canSeekForward() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public void seekTo(long pos) {
            if (mMediaPlayer != null && mIsPrepared) {
                mMediaPlayer.seekTo((int) pos);
            } else {
                mSeekWhenPrepared = (int) pos;
            }
        }
    
        @Override
        public void onClick(View v) {
            System.out.println("this is pause");
    
        }
    
    }

     然后:

    自定义的VideoView:

     ,最后才是主要类“基本上完全了,想要更深,自己DIY即可:

    package com.example.revideoview;
    
    import java.io.File;
    
    import com.android.widget.CustomProgressDialog;
    import com.android.widget.VodCtrTop;
    import com.android.widget.MediaController;
    import com.android.widget.StringTools;
    import com.android.widget.VideoView;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.PixelFormat;
    import android.graphics.drawable.BitmapDrawable;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnErrorListener;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.os.MessageQueue.IdleHandler;
    import android.util.DisplayMetrics;
    import android.view.Gravity;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.PopupWindow;
    import android.widget.TextView;
    import android.widget.RelativeLayout.LayoutParams;
    
    /**
     * 
     * @author Catherine
     * */
    
    public class MainActivity extends Activity {
        VideoView videoView;
    
        MediaController mMediaController;
    
        public static MainActivity instance;
        String title;
        String numText;
    
        int resourceId;
        String path;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
            instance = this;
            path = Environment.getExternalStorageDirectory()
                    + "/c234b_08_hd_h264_1280_720.mp4";
            System.out.println("the path is===>" + path);
            File file = new File(path);
            if (file.exists()) {
    
                // tvTitle = (TextView) findViewById(R.id.title);
    
                videoView = (VideoView) findViewById(R.id.myVideoView);
                videoView.setOnCompletionListener(new OnCompletionListener() {
    
                    @Override
                    public void onCompletion(MediaPlayer arg0) {
                        finish();
                    }
                });
                resourceId = R.drawable.ic_launcher;
                setDataSource(path);
    
                initControlView();
                initOperatHintPop();
    
                setMediaPlayer();
    
                Looper.myQueue().addIdleHandler(new IdleHandler() {
    
                    @Override
                    public boolean queueIdle() {
                        if (ctrTop != null && videoView.isPlaying()) {
                            showCtrTop();
                        }
                        return false;
                    }
                });
            } else {
                System.out.println("文件不存在");
            }
    
        }
    
        int btn_judge = 0;
    
        private void showCtrTop() {
            ctrTop.showAtLocation(videoView, Gravity.TOP, 0, 0);
            ctrTop.setSourceTag(resourceId);
    
            if (StringTools.isNullOrEmpty(numText)) {
                ctrTop.setVideoName(title);
            } else {
                ctrTop.setVideoName(title + "(" + numText + ")");
            }
        }
    
        VodCtrTop ctrTop;
        // VodCtrBot ctrBot;
    
        private PopupWindow hintPop;
        private ImageView hintPopImg;
    
        private void initControlView() {
    
            // ctrBot = new VodCtrBot(this, videoView, new Handler() {
    
            // });
    
            ctrTop = new VodCtrTop(this, new Handler() {
                @Override
                public void handleMessage(Message msg) {
    
                    super.handleMessage(msg);
                }
    
            });
    
        }
    
        private void initOperatHintPop() {
            hintPop = new PopupWindow();
            hintPopImg = new ImageView(this);
            hintPop.setWindowLayoutMode(
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                    android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
            hintPop.setBackgroundDrawable(new BitmapDrawable());
            WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams(
                    android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
                    android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
            this.hintPopImg.setLayoutParams(localLayoutParams);
            this.hintPop.setContentView(this.hintPopImg);
        }
    
        private void setMediaPlayer() {
            // 全屏之后设置进度条
    
            mMediaController = new MediaController(this);
            videoView.setMediaController(mMediaController);
            mMediaController.show();
        }
    
        @Override
        protected void onResume() {
            // setDataSource(url, title);
            super.onResume();
    
            // getCookies();
        }
    
        public WindowManager windowManager;
        private Handler handler;
        private OverlayThread overlayThread;
    
        private LinearLayout overlay_ll;
        public TextView overlay;
    
    
        private Handler mHandler = new Handler() {
    
            public void handleMessage(Message msg) {
                if (msg.what == 0) {
    
                }
            };
        };
    
        public void initOverlay() {
            handler = new Handler();
            overlayThread = new OverlayThread();
            final LayoutInflater inflater = LayoutInflater.from(instance);
            overlay_ll = (LinearLayout) inflater.inflate(R.layout.overlay, null);
            overlay = (TextView) overlay_ll.findViewById(R.id.tv_center);
    
            final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                    PixelFormat.TRANSLUCENT);
            windowManager = (WindowManager) instance
                    .getSystemService(Context.WINDOW_SERVICE);
            windowManager.addView(overlay_ll, lp);
            // windowManager.addView(overlay_bottom, lp);
        }
    
        /**
         * 设置overlay不可见
         * 
         * 
         */
        class OverlayThread implements Runnable {
    
            @Override
            public void run() {
                overlay_ll.setVisibility(View.GONE);
            }
        }
    
    
        public void setDataSource(String url) {
    
            playVideo(url);
    
        }
    
        /**
         * 获取屏幕的宽和高
         */
        private void getScreenSize() {
            DisplayMetrics dm = new DisplayMetrics();
            this.getWindowManager().getDefaultDisplay().getMetrics(dm);
            // VitaVideoView.mVideoWidth = dm.widthPixels;
            // VitaVideoView.mVideoHeight = dm.heightPixels;
        }
    
        public void playVideo(String url) {
    
            Message msg = new Message();
            msg.what = 0;
            // 发送一个隐藏的消息
            mHandler.sendMessageDelayed(msg, 5 * 1000);
    
            videoView.setVideoPath(url);
    
            // 展示一个进度
            final CustomProgressDialog dialog = new CustomProgressDialog(instance);
            if (!dialog.isShowing()) {
                dialog.show();
            }
    
            videoView.setOnPreparedListener(new OnPreparedListener() {
    
                @Override
                public void onPrepared(MediaPlayer mp) {
    
                    // 取消进度
                    if (null != dialog) {
                        dialog.cancel();
                    }
                    // setMediaPlayer();
                    videoView.start();
                }
            });
    
            videoView.requestFocus();
        }
    
        int playNum = 0;
        int titleNum = 0;
    
        //
    
        protected void exitApp() {
            UserDialogRunnable userRun = new UserDialogRunnable();
            new Handler().postDelayed(userRun, 300L);
        }
    
        class UserDialogRunnable implements Runnable {
    
            @Override
            public void run() {
                finish();
                overridePendingTransition(R.anim.hyperspace_in,
                        R.anim.hyperspace_out);
                // android.os.Process.killProcess(android.os.Process.myPid());
            }
    
        }
    
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            System.out.println("this is mainactivity onKeyDown");
            switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                System.out.println("this is mainactivity keyevent");
                // mMediaController.show();
                if (videoView.isPlaying()) {
                    // 暂停
                    videoView.pause();
                    // 展示暂停
                    hintPopImg.setImageResource(R.drawable.osd_pause);
                    hintPop.showAtLocation(videoView, 17, 0, 0);
                } else {
                    hintPop.dismiss();
                    videoView.start();
                }
    
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                // mMediaController.show();
                showCtrTop();
                // ctrBot.show();
                // if (event.getRepeatCount() == 0 && event.getEventTime() > 2 *
                // 1000) {
                // videoBack();
                // }
                return false;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                mMediaController.show();
                showCtrTop();
                return false;
            case KeyEvent.KEYCODE_BACK:
                finish();
                // return true;
            case KeyEvent.KEYCODE_MENU:
    
                return true;
            }
    
            return false;
        };
    
        public boolean onTouchEvent(android.view.MotionEvent event) {
            return false;
        };
    
        Handler menuHandler = new Handler();
    
        int addOrbackNum = 30 * 1000;
    
        // private void videoBack() {
        // long pos = videoView.getCurrentPosition();
        // pos -= addOrbackNum;
        // videoView.seekTo(pos);
        // }
        //
        // private void videoAdd() {
        // long pos = videoView.getCurrentPosition();
        // pos += addOrbackNum;
        // videoView.seekTo(pos);
        // }
    
        public void changeScales(int whatMode) {
            videoView.selectScales(whatMode);
    
        }
    
        OnErrorListener errorListener = new OnErrorListener() {
    
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
    
                return true;
            }
        };
    
        protected void onDestroy() {
            if (ctrTop != null) {
                ctrTop.dismiss();
            }
            if (hintPop != null) {
                hintPop.dismiss();
            }
            super.onDestroy();
        };
    }

    具体源码,可以看我的文件里面的“自定义Videoview.jar”

    里面也有继承TextView,以及Toast以及Processbar。。。。可参考

    当然,这个给出一个灵感链接:http://blog.sina.com.cn/s/blog_640b806d0100q2wo.html#commonComment

  • 相关阅读:
    不常用的cmd命令
    js获取宽度
    Marshaling Data with Platform Invoke 概览
    Calling a DLL Function 之三 How to: Implement Callback Functions
    Marshaling Data with Platform Invoke 之四 Marshaling Arrays of Types
    Marshaling Data with Platform Invoke 之一 Platform Invoke Data Types
    Marshaling Data with Platform Invoke 之三 Marshaling Classes, Structures, and Unions(用时查阅)
    Calling a DLL Function 之二 Callback Functions
    WCF 引论
    Marshaling Data with Platform Invoke 之二 Marshaling Strings (用时查阅)
  • 原文地址:https://www.cnblogs.com/Catherine-Brain/p/4089748.html
Copyright © 2011-2022 走看看