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

  • 相关阅读:
    linux 下高精度时间
    pstack
    linux 调试常用命令
    定位 UNIX 上常见问题的经验总结
    在 POSIX 线程编程中避免内存泄漏
    ulimit
    设计模式之迭代器模式(PHP实现)
    设计模式之责任链模式(php实现)
    设计模式之代理模式(php实现)
    设计模式之享元模式(PHP实现)
  • 原文地址:https://www.cnblogs.com/Catherine-Brain/p/4089748.html
Copyright © 2011-2022 走看看