Android基于surfaceview与mediaplayer的视频播放器(android-studio)

来源:互联网 发布:平移旋转变换矩阵 编辑:程序博客网 时间:2024/05/16 05:28

最近闲来无事写了一个较为完整的视频播放器,但由于有了新的项目,就把这个搁浅了,就差一个横竖屏切换的时候切换不同的控制栏了,以及横屏的自动锁定了。


surfaceview的测量,视频缩略图




实现了双击横屏 单击控制栏的显示与隐藏,手势控制播放进度,屏幕亮度和音量的调节




重力切换横竖屏与点击切换横竖屏也解决了,手机固定屏幕重力切换失效也搞定了


由于并没有高度封装,很适合初学者,大神勿喷罗





package com.wyt.hcy.wyt_microclassroomapp;import android.app.Activity;import android.content.Context;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.graphics.Bitmap;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.ThumbnailUtils;import android.os.AsyncTask;import android.os.Handler;import android.os.Message;import android.provider.Settings;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Display;import android.view.GestureDetector;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.widget.FrameLayout;import android.widget.ImageView;import android.widget.MediaController;import android.widget.RelativeLayout;import android.widget.SeekBar;import android.widget.TextView;import java.io.IOException;import java.lang.ref.WeakReference;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import Utils.ProjectUtils;import wseemann.media.FFmpegMediaMetadataRetriever;/** * created by  hcy 2016.8.4 * <p> * bug: 只有声音没有图片 * cause: * 1.在用SurfaceView播放视频时,如果处理不当,会出现有声音无图像的问题,主要的原因是, * 在调用MediaPlayer开始播放视频时,SurfaceView却还未创建成功, * 解决办法是判断SurfaceView创建成功后再调用MediaPlayer的播放, * 通过surfaceHolder的addCallBack()方法来监听surfaceCreated。 * 2.注意测量的时间 应该在prepare之后 * 应为在视频初始化时获得视频的高宽都为0 , * 这个必须要注意,必须播放后延时 修改view 大小 * bug:手动切换与自动切换横竖屏的冲突:手动点击横竖屏切换,手机再横竖屏就没法驱使 * bug:屏幕切换时能够流畅的播放 * bug:双击全屏 * bug:横屏的锁屏机制 * bug:手势操作:调节音量、亮度、快进、快退 * bug:检测系统屏幕旋转的开关 * bug:横竖屏切换不同风格的控制栏 * bug:缓存进度与下载进度 * bug: */public class VideoPlayerActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnVideoSizeChangedListener, MediaController.MediaPlayerControl, View.OnTouchListener, View.OnClickListener {    private static final String TAG = "VideoPlayerActivity";    private Display display;    private SurfaceHolder surfaceHolder;//监控在底层表面上发生的事情    private SurfaceView surfaceView;    private MediaPlayer mediaPlayer;    private int videoWidth;    private int videoHeight;    private MyHandler mHandler;    private static final int MEASURE_VIDEO_SIZE = 1;//测量视频的大小    private static final int CONTROLLER_AUTO_HIDE_TIME = 5000;//5s自动隐藏控制条    private static final int PLAY_TIME = 0;    private ImageView iv_play;    private SeekBar seekbar;    private TextView tv_start, tv_end;    private ImageView iv_full;    private ImageView imageView_main_show;//func:点击该按钮 ,按钮消失 ,视频播放    private Timer timer;    private SurfaceHolder currentSurfaceHolder;    private boolean sennorFlag = true;    private boolean stretch_flag = true;    private int screenHeight;    private int screenWidth;    private SensorManager sm;    private SensorManager sm2;    private OrientationSensorListener listener;    private OrientationSensorListener2 listener2;    private Sensor sensor;    private Sensor sensor2;    private FrameLayout fl_controller;    private String filepath;    private ImageView iv_suolue;//缩略图    private int currentPosition;//当前的播放位置    private RelativeLayout rl_show;    private ImageView iv_flag;    private TextView tv_pro;    /**     * 手势控制     */    private GestureDetector gestureDetector;    private ImageView iv_lock;    public interface GestureOperationHelper {        void SingleTap();    }    private GestureOperationHelper gestureOperationHelper;    private static enum GestureOperationType {        NONE,//无手势操作类型        VOLUME,//音量        BRIGHTNESS,//亮度        FASTFORWARDORBACKWARD,//快进  快退    }    private GestureOperationType mGestureOperationType = GestureOperationType.NONE;    private AudioManager manager;    private ImageView iv_voice;    /**     * 为了结局点击surfaceview与控制器出现与隐藏的联动bug     * func:等上一个Runnable执行完才会执行下一个Runnable     */    private Runnable mRunnable = new Runnable() {        @Override        public void run() {            if (fl_controller.getVisibility() == View.VISIBLE) {                fl_controller.setVisibility(View.GONE);                // isTimeUp = true;                if (imageView_main_show.getVisibility() == View.VISIBLE && imageView_main_show.isSelected()) {                    imageView_main_show.setVisibility(View.GONE);                }            }        }    };    /**     * 控制模块的显示或者隐藏     */    private void showOrHideController() {        if (rl_show.getVisibility() == View.VISIBLE) {            rl_show.setVisibility(View.GONE);            mHandler.removeMessages(11);        }        if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {            //横屏的时候显现锁屏按钮            iv_lock.setVisibility(View.VISIBLE);        } else {            iv_lock.setVisibility(View.GONE);        }        if (fl_controller.getVisibility() == View.VISIBLE) {            fl_controller.setVisibility(View.GONE);            iv_lock.setVisibility(View.GONE);            if (imageView_main_show.getVisibility() == View.VISIBLE && imageView_main_show.isSelected()) {                imageView_main_show.setVisibility(View.GONE);            }        } else {            fl_controller.setVisibility(View.VISIBLE);            mHandler.removeCallbacks(mRunnable);            mHandler.postDelayed(mRunnable, CONTROLLER_AUTO_HIDE_TIME);            if (mediaPlayer != null && mediaPlayer.isPlaying() && imageView_main_show.isSelected()) {                imageView_main_show.setSelected(true);                imageView_main_show.setVisibility(View.VISIBLE);                Log.i("<<<???", imageView_main_show.isSelected() + "");            }        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_video_player);        mHandler = new MyHandler(this);        manager = (AudioManager) getSystemService(AUDIO_SERVICE);        Log.i("TTTTT", "onCreate");        initSurfaceView();        initController();        initGestureController();    }    /**     * 初始化手势控制     */    private void initGestureController() {        gestureOperationHelper = new GestureOperationHelper() {            @Override            public void SingleTap() {            }        };        gestureDetector = new GestureDetector(VideoPlayerActivity.this, new GestureDetector.SimpleOnGestureListener() {            //双击            @Override            public boolean onDoubleTap(MotionEvent e) {                //双击横竖屏切换                if (stretch_flag) {                    //切换成横屏                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);                    stretch_flag = false;                } else {                    //切换成竖屏                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);                    stretch_flag = true;                }                return true;            }            @Override            public void onShowPress(MotionEvent e) {                super.onShowPress(e);                showOrHideController();            }            /**             * ,一次单独的轻击抬起操作,也就是轻击一下屏幕             * @param e             * @return             */            @Override            public boolean onSingleTapUp(MotionEvent e) {                mHandler.postDelayed(mSwitchTitleRunnable, 200);                return true;            }            @Override            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {                if (Math.abs(distanceX) > Math.abs(distanceY)) {                    //如果X轴的绝对值大于Y轴的绝对值  说明此时在快进或者快退                    Log.i("KKKKKK", "快进");                    mGestureOperationType = GestureOperationType.FASTFORWARDORBACKWARD;                } else {                    if (e1.getX() < surfaceView.getWidth() / 2) {                        //说名在屏幕的左侧,左侧调节亮度                        Log.i("KKKKKK", "亮度");                        mGestureOperationType = GestureOperationType.BRIGHTNESS;                    } else {                        //右侧调节音量                        Log.i("KKKKKK", "音量");                        mGestureOperationType = GestureOperationType.VOLUME;                    }                }                return DealWithScrollGestureOperation(e1, e2, distanceX, distanceY);            }        });    }    private boolean DealWithScrollGestureOperation(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        if (fl_controller.getVisibility() == View.VISIBLE) {            fl_controller.setVisibility(View.GONE);            imageView_main_show.setVisibility(View.GONE);            iv_lock.setVisibility(View.GONE);            mHandler.removeCallbacks(mRunnable);        }        rl_show.setVisibility(View.VISIBLE);        if (mGestureOperationType == GestureOperationType.FASTFORWARDORBACKWARD) {            //快进,快退操作的处理            if (mediaPlayer == null || !mediaPlayer.isPlaying()) {                //不执行                return false;            }            if (iv_voice.getVisibility() == View.VISIBLE) {                iv_voice.setVisibility(View.GONE);            }            /**             * 向右边滑动disX为负数 向左边滑动disX为正数             * func:无论快进还是快退都是一分钟             *             */            int pos = mediaPlayer.getCurrentPosition();            int total = mediaPlayer.getDuration();            if (distanceX < 0) {                //右话                iv_flag.setImageResource(R.mipmap.fast);                pos = pos + 1 * 10 * 1000;            } else if (distanceX > 0) {                //左话                iv_flag.setImageResource(R.mipmap.rewind);                pos = pos - 1 * 10 * 1000;            }            mHandler.removeMessages(11);            mHandler.sendEmptyMessageDelayed(11, 5000);            int progress = (int) ((pos / (float) total) * 100);            // Log.i("GGGGG:",progress+" ");            seekbar.setProgress(progress);            if (pos < 0) {                pos = 0;            } else if (pos > total) {                pos = total;            }            mediaPlayer.seekTo(pos);            int currentPosition = mediaPlayer.getCurrentPosition();            String start = null;            if (currentPosition > 0) {                start = formatTime(currentPosition);            } else {                start = "00:00";            }            String str = new StringBuffer().append(start).append("/").append(tv_end.getText().toString()).toString();            tv_pro.setText(str);        } else if (mGestureOperationType == GestureOperationType.VOLUME) {            iv_flag.setImageResource(R.mipmap.huatong);            iv_voice.setVisibility(View.VISIBLE);            if (imageView_main_show.getVisibility() == View.VISIBLE) {                imageView_main_show.setVisibility(View.GONE);            }            int maxVolume = manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);            int currentVolume = manager.getStreamVolume(AudioManager.STREAM_MUSIC);            Log.i("音量:当前", currentVolume + "");            Log.i("音量:最大", maxVolume + "");            /*             * 发现音量最小0 最大15             */            /**             * 上滑是正数,下滑是负数             */            float percent = (distanceY / (float) surfaceView.getMeasuredHeight());            float volumeOffsetAccurate = maxVolume * percent * 0.5f;            int volumeOffset = (int) volumeOffsetAccurate;            if (volumeOffset == 0 && Math.abs(volumeOffsetAccurate) > 0.2f) {                if (distanceY > 0) {                    volumeOffset = 1;                } else if (distanceY < 0) {                    volumeOffset = -1;                }            }            currentVolume += volumeOffset;            if (currentVolume < 0) {                currentVolume = 0;            } else if (currentVolume >= maxVolume) {                currentVolume = maxVolume;            }            if (currentVolume == 0) {                iv_voice.setImageResource(R.mipmap.vc_0);            } else if (currentVolume <= 2) {                iv_voice.setImageResource(R.mipmap.vc_1);            } else if (currentVolume <= 4) {                iv_voice.setImageResource(R.mipmap.vc_2);            } else if (currentVolume <= 6) {                iv_voice.setImageResource(R.mipmap.vc_3);            } else if (currentVolume <= 8) {                iv_voice.setImageResource(R.mipmap.vc_4);            } else if (currentVolume <= 11) {                iv_voice.setImageResource(R.mipmap.vc_5);            } else if (currentVolume <= 14) {                iv_voice.setImageResource(R.mipmap.vc_6);            } else if (currentVolume == 15) {                iv_voice.setImageResource(R.mipmap.vc_7);            }            tv_pro.setText(currentVolume * 100 / maxVolume + "%");            mHandler.removeMessages(11);            mHandler.sendEmptyMessageDelayed(11, 5000);            manager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0);        } else if (mGestureOperationType == GestureOperationType.BRIGHTNESS) {            iv_flag.setImageResource(R.mipmap.video_brightness_bg);            if (iv_voice.getVisibility() == View.VISIBLE) {                iv_voice.setVisibility(View.GONE);            }            float percent = distanceY / (float) surfaceView.getMeasuredHeight();            float currentBrightness = getBrightnessPercent(VideoPlayerActivity.this);            float brightnessOffset = percent * 5;            currentBrightness += brightnessOffset;            if (currentBrightness < 0) {                currentBrightness = 0;            } else if (currentBrightness > 1) {                currentBrightness = 1;            }            int progress = (int) (currentBrightness * 100);            Log.i("FFFFF", progress + "");            tv_pro.setText(progress + "%");            setBrightness(VideoPlayerActivity.this, currentBrightness);            mHandler.removeMessages(11);            mHandler.sendEmptyMessageDelayed(11, 5000);        }        return true;    }    /**     * 设置屏幕亮度     */    private void setBrightness(Activity activity, float percent) {        if (activity == null) {            return;        }        if (percent < 0.01f) {            percent = 0.01f;        } else if (percent > 1.0f) {            percent = 1.0f;        }        WindowManager.LayoutParams params = activity.getWindow().getAttributes();        params.screenBrightness = percent;        activity.getWindow().setAttributes(params);    }    /**     * 获得当前屏幕亮度     *     * @param activity     * @return     */    private float getBrightnessPercent(Activity activity) {        WindowManager.LayoutParams params = activity.getWindow().getAttributes();        return params.screenBrightness;    }    private Runnable mSwitchTitleRunnable = new Runnable() {        @Override        public void run() {            gestureOperationHelper.SingleTap();        }    };    @Override    protected void onStart() {        super.onStart();        Log.i("TTTTT", "onStart");    }    private void initSensor() {        //初始化重力感应器,func:重力感应屏幕切换        sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);        //获得重力传感器        sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);        listener = new OrientationSensorListener(mHandler);        sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI);        sm2 = (SensorManager) getSystemService(Context.SENSOR_SERVICE);        sensor2 = sm2.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);        listener2 = new OrientationSensorListener2();        sm2.registerListener(listener2, sensor2, SensorManager.SENSOR_DELAY_UI);    }    private void initMediaPlayer() {        /**         * 获取屏幕宽高         */        display = getWindowManager().getDefaultDisplay();        screenWidth = display.getWidth();        screenHeight = display.getHeight();        mediaPlayer = null;        mediaPlayer = new MediaPlayer();        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//边播放边缓冲        mediaPlayer.setDisplay(currentSurfaceHolder);//指定mediaplayer用于播放    /*    *         * 监听视频播放结束*/        mediaPlayer.setOnCompletionListener(this);      /*  *         * 播放视频出错的监听*/        mediaPlayer.setOnErrorListener(this);   /*     *         *  注册一个回调函数,在有警告或错误信息时调用*/        mediaPlayer.setOnInfoListener(this);   /*     *         *   注册一个回调函数,在视频预处理完成后调用。*/        mediaPlayer.setOnPreparedListener(this);       /* *         * 注册一个回调函数,在seek操作完成后调用。*/        mediaPlayer.setOnSeekCompleteListener(this);      /*  *         * 注册一个回调函数,在视频大小已知或更新后调用。*/        mediaPlayer.setOnVideoSizeChangedListener(this);        /**         * 视频路径         */        filepath = ProjectUtils.getDiskCacheDir(this, "video") + "/test2.mp4";        try {            mediaPlayer.setDataSource(filepath);            mediaPlayer.setLooping(false);//不重复            mediaPlayer.prepareAsync();        } catch (IOException e) {            Log.i(TAG, "setDataSource-IOException:" + e.getMessage());            //  finish();        } catch (IllegalArgumentException e) {            Log.i(TAG, "setDataSource-IllegalArgumentException:" + e.getMessage());            // finish();        } catch (IllegalStateException e) {            Log.i(TAG, "setDataSource-IllegalStateException:" + e.getMessage());            //  finish();        }        //初始化重力传感器        initSensor();    }    /**     * 控制条     */    private void initController() {        fl_controller = (FrameLayout) findViewById(R.id.fl_controller);        iv_play = (ImageView) findViewById(R.id.iv_play);        iv_play.setSelected(false);        seekbar = (SeekBar) findViewById(R.id.seekbar);        tv_start = (TextView) findViewById(R.id.tv_start);        tv_end = (TextView) findViewById(R.id.tv_end);        iv_full = (ImageView) findViewById(R.id.iv_full);        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {            @Override            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                //   mHandler.postDelayed()                if (fromUser && mediaPlayer != null) {                    currentPosition = progress * mediaPlayer.getDuration() / 100;                    mediaPlayer.seekTo(currentPosition);                }            }            /**             * 正在拖动进度条 并且手指没有离开屏幕             * @param seekBar             */            @Override            public void onStartTrackingTouch(SeekBar seekBar) {                //取消延时器                mHandler.removeCallbacks(mRunnable);            }            /**             * 手指拖动完毕  手机离开屏幕的时候触发             * @param seekBar             */            @Override            public void onStopTrackingTouch(SeekBar seekBar) {                //让延时器启动                mHandler.postDelayed(mRunnable, CONTROLLER_AUTO_HIDE_TIME);            }        });        //播放&暂停        iv_play.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                /**                 * 隐藏缩略图                 */                if (iv_suolue != null && iv_suolue.getVisibility() == View.VISIBLE) {                    iv_suolue.setVisibility(View.GONE);                }                if (mediaPlayer != null && mediaPlayer.isPlaying()) {                    //正在播放 此时该暂停                    try {                        iv_play.setSelected(false);                        mediaPlayer.pause();                        //此时应该显示大暂停按钮                        imageView_main_show.setSelected(false);                        imageView_main_show.setVisibility(View.VISIBLE);                    } catch (IllegalArgumentException e) {                        Log.i(TAG, "iv_play播放暂停-IllegalArgumentException:" + e.getMessage());                        finish();                    } catch (IllegalStateException e) {                        Log.i(TAG, "iv_play播放暂停-IllegalStateException:" + e.getMessage());                        finish();                    }                } else if (mediaPlayer != null) {                    try {                        iv_play.setSelected(true);                        mediaPlayer.start();                        imageView_main_show.setSelected(true);                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                imageView_main_show.setVisibility(View.GONE);                            }                        }, 500);                    } catch (IllegalArgumentException e) {                        Log.i(TAG, "iv_play开始播放-IllegalArgumentException:" + e.getMessage());                        finish();                    } catch (IllegalStateException e) {                        Log.i(TAG, "iv_play开始播放-IllegalStateException:" + e.getMessage());                        finish();                    }                }            }        });        /**         * 全屏 或者 退出全屏 播放         */        iv_full.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.i("HHHH", "切换横屏)))" + stretch_flag);                //  stretch_flag = sp1.getBoolean("stretch_flag", true);                if (stretch_flag) {                    //切换成横屏                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);                    stretch_flag = false;                } else {                    //切换成竖屏                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);                    stretch_flag = true;                }            }        });    }    @Override    public void start() {        mediaPlayer.start();    }    @Override    public void pause() {        if (mediaPlayer.isPlaying()) {            mediaPlayer.pause();        }    }    @Override    public int getDuration() {        return mediaPlayer.getDuration();    }    @Override    public int getCurrentPosition() {        return mediaPlayer.getCurrentPosition();    }    @Override    public void seekTo(int pos) {        mediaPlayer.seekTo(pos);    }    @Override    public boolean isPlaying() {        return mediaPlayer.isPlaying();    }    @Override    public int getBufferPercentage() {        return 0;    }    @Override    public boolean canPause() {        return true;    }    @Override    public boolean canSeekBackward() {        return true;    }    @Override    public boolean canSeekForward() {        return true;    }    @Override    public int getAudioSessionId() {        return 0;    }    /**     * surfaceView的Touch监听     *     * @param v     * @param event     * @return     */    @Override    public boolean onTouch(View v, MotionEvent event) {        gestureDetector.onTouchEvent(event);        return true;    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.imageView_main_play:                if (iv_suolue != null && iv_suolue.getVisibility() == View.VISIBLE) {                    iv_suolue.setVisibility(View.GONE);                }                Log.i(TAG, "imageView_main_play::播放" + imageView_main_show.isSelected());                //  if (mediaPlayer != null  && imageView_main_show.isSelected()&& mediaPlayer.isPlaying()) {                //说明此时正在播放,播放按钮处于播放状态                try {                    if (mediaPlayer != null && imageView_main_show.isSelected() && mediaPlayer.isPlaying()) {                        mediaPlayer.pause();                        //此时控制条的播放组件应该是显示暂停状态                        if (iv_play != null) {                            iv_play.setSelected(false);                            // iv_play.setImageResource(R.drawable.fvl_selector_play);                        }                        imageView_main_show.setSelected(false);                    } else if (mediaPlayer != null && !imageView_main_show.isSelected()) {                        imageView_main_show.setSelected(true);                        mediaPlayer.start();                        //此时控制条的播放组件应该是显示播放状态                        if (iv_play != null) {                            iv_play.setSelected(true);                        }                        imageView_main_show.setVisibility(View.GONE);                    }                } catch (IllegalArgumentException e) {                    Log.i(TAG, "imageView_main_play-IllegalArgumentException:" + e.getMessage());                    finish();                } catch (IllegalStateException e) {                    Log.i(TAG, "imageView_main_play-IllegalStateException:" + e.getMessage());                }                break;        }    }    private class MyHandler extends Handler {        private WeakReference<Activity> weakReference;        public MyHandler(Activity activity) {            weakReference = new WeakReference<Activity>(activity);        }        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            Activity activity = weakReference.get();            if (activity != null) {                switch (msg.what) {                    case MEASURE_VIDEO_SIZE:                        /**                         * 测量的视频大小                         */                        /**                         * 设置播放大小,如果视频的大小>显示器  设置显示器  反之 视频,取小的设置比率                         */                        videoWidth = mediaPlayer.getVideoWidth();                        Log.i(TAG, "视频的宽度:" + videoWidth);                        Log.i(TAG, "视频的宽度:::" + screenWidth);                        videoHeight = mediaPlayer.getVideoHeight();                        Log.i(TAG, "视频的高度:" + videoHeight);                        Log.i(TAG, "视频的高度:::" + screenHeight);                        // screenHeight = display.getHeight();                        if (videoWidth > display.getWidth() || videoHeight > screenHeight) {                            //视频的大小>显示器的大小                            float heightRatio = (float) videoHeight / (float) screenHeight;//高度比率                            float widthRatio = (float) videoWidth / (float) screenWidth;//宽度比率                            if (heightRatio > widthRatio) {                                videoHeight = (int) Math.ceil((float) videoHeight / heightRatio);                                videoWidth = (int) Math.ceil((float) videoWidth / heightRatio);                            } else {                                videoHeight = (int) Math.ceil((float) videoHeight / widthRatio);                                videoWidth = (int) Math.ceil((float) videoWidth / widthRatio);                            }                        }                        surfaceView.setLayoutParams(new RelativeLayout.LayoutParams(videoWidth, videoHeight));                        if (iv_suolue.getVisibility() == View.VISIBLE) {                            iv_suolue.setVisibility(View.GONE);                            new GetVideoBitmapAsyncTask(iv_suolue, surfaceView).execute(filepath);                        }                        break;                    case PLAY_TIME:                        if (mediaPlayer != null) {                            try {                                int currentPosition = mediaPlayer.getCurrentPosition();                                if (currentPosition > 0) {                                    int progress = (int) ((currentPosition / (float) mediaPlayer                                            .getDuration()) * 100);                                    Log.i("PRogress::", progress + "");                                    seekbar.setProgress(progress);                                    tv_start.setText(formatTime(currentPosition));                                } else {                                    tv_start.setText("00:00");                                    seekbar.setProgress(0);                                }                            } catch (IllegalStateException ex) {                                mediaPlayer.release();                            }                        }                        break;                    case 10001:                        int orientation = msg.arg1;                        if (orientation > 45 && orientation < 135) {                        } else if (orientation > 135 && orientation < 225) {                        } else if (orientation > 225 && orientation < 315) {                            Log.i(TAG, "切换成横屏");                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);                            sennorFlag = false;                            stretch_flag = false;                        } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {                            Log.i(TAG, "切换成竖屏");                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);                            sennorFlag = true;                            stretch_flag = true;                        }                        break;                    case 11:                        rl_show.setVisibility(View.GONE);                        if (imageView_main_show.isSelected() == false && imageView_main_show.getVisibility() == View.GONE) {                            imageView_main_show.setVisibility(View.VISIBLE);                        }                        break;                }            }        }    }    private void initSurfaceView() {        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);        iv_voice = (ImageView) findViewById(R.id.iv_voice);        tv_pro = (TextView) findViewById(R.id.tv_pro);        iv_suolue = (ImageView) findViewById(R.id.iv_suolue);        rl_show = (RelativeLayout) findViewById(R.id.rl_show);        iv_flag = (ImageView) findViewById(R.id.iv_flag);        iv_lock = (ImageView) findViewById(R.id.iv_lock);//锁屏        imageView_main_show = (ImageView) findViewById(R.id.imageView_main_play);        imageView_main_show.setOnClickListener(this);        imageView_main_show.setSelected(false);//初始状态  是处于暂停的状态        surfaceHolder = surfaceView.getHolder();        /**         * 确保底层的表面是一个推送缓冲区表面,用于视频播放和摄像头的浏览         */        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        surfaceView.setOnTouchListener(this);        surfaceHolder.addCallback(this);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        Log.i(TAG, "surfaceCreated");        currentSurfaceHolder = holder;        initMediaPlayer();    }    /**     * 当SurfaceView 的底层表面的宽度、高度或者其他参数发生变化时  调用     *     * @param holder     * @param format     * @param width     * @param height     */    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        Log.i(TAG, "surfaceChanged:" + width + " " + height);    }    /*当销毁 SurfaceView的底层表面时,调用     */    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        Log.i(TAG, "surfaceDestroyed:");    }    @Override    public void onCompletion(MediaPlayer mp) {        Log.i(TAG, "onCompletion:");        if (iv_play != null) {            iv_play.setSelected(false);        }        if (imageView_main_show != null) {            imageView_main_show.setSelected(false);            imageView_main_show.setVisibility(View.VISIBLE);        }    }    @Override    public boolean onError(MediaPlayer mp, int what, int extra) {        Log.i(TAG, "onError:");        //  initMediaPlayer();        switch (what) {            case -1004:                Log.d(TAG, "MEDIA_ERROR_IO");                break;            case -1007:                Log.d(TAG, "MEDIA_ERROR_MALFORMED");                break;            case 200:                Log.d(TAG, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");                break;            case 100:                Log.d(TAG, "MEDIA_ERROR_SERVER_DIED");                break;            case -110:                Log.d(TAG, "MEDIA_ERROR_TIMED_OUT");                break;            case 1:                Log.d(TAG, "MEDIA_ERROR_UNKNOWN");                break;            case -1010:                Log.d(TAG, "MEDIA_ERROR_UNSUPPORTED");                break;        }        switch (extra) {            case 800:                Log.d(TAG, "MEDIA_INFO_BAD_INTERLEAVING");                break;            case 702:                Log.d(TAG, "MEDIA_INFO_BUFFERING_END");                break;            case 701:                Log.d(TAG, "MEDIA_INFO_METADATA_UPDATE");                break;            case 802:                Log.d(TAG, "MEDIA_INFO_METADATA_UPDATE");                break;            case 801:                Log.d(TAG, "MEDIA_INFO_NOT_SEEKABLE");                break;            case 1:                Log.d(TAG, "MEDIA_INFO_UNKNOWN");                break;            case 3:                Log.d(TAG, "MEDIA_INFO_VIDEO_RENDERING_START");                break;            case 700:                Log.d(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING");                break;        }        /**         * false:表明错误没有被处理 调用 onCompletion  此时mediaplayer处于错误状态         */        return false;    }    /**     * 当出现关于播放媒体的特定信息或者需要发出警告的时候,将调用onInfo     *     * @param mp     * @param what     * @param extra     * @return     */    @Override    public boolean onInfo(MediaPlayer mp, int what, int extra) {        Log.i(TAG, "onInfo:");        if (what == MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING) {            //当文件中的音频和视频数据不正确的交错的时候会触发            Log.i(TAG, "onInfo:MEDIA_INFO_BAD_INTERLEAVING:" + extra);        } else if (what == MediaPlayer.MEDIA_INFO_NOT_SEEKABLE) {            //当媒体不能正确的定位            Log.i(TAG, "onInfo:MEDIA_INFO_NOT_SEEKABLE:" + extra);        } else if (what == MediaPlayer.MEDIA_INFO_UNKNOWN) {            //媒体信息尚未指定或者未知            Log.i(TAG, "onInfo:MEDIA_INFO_UNKNOWN:" + extra);        } else if (what == MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING) {            //无法播放视频或者音频太复杂或者码率过高            Log.i(TAG, "onInfo:MEDIA_INFO_VIDEO_TRACK_LAGGING:" + extra);        } else if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {            //当新的元数据可用时            Log.i(TAG, "onInfo:MEDIA_INFO_METADATA_UPDATE:" + extra);        }        return false;    }    @Override    public void onPrepared(MediaPlayer mp) {        try {             /*当不是全屏的时候才需要测量,才需要比较*/            if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {                //因为配置文件中并未设置横竖屏                mHandler.sendEmptyMessageDelayed(MEASURE_VIDEO_SIZE, 1000);            } else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {                mHandler.sendEmptyMessageDelayed(MEASURE_VIDEO_SIZE, 1000);            } else {                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);                surfaceView.setLayoutParams(params);            }            //Log.i("屏幕方向:::", isLandScape + "");            /**             * 获取缩略图             */            tv_end.setText(formatTime(mediaPlayer.getDuration()));            //初始化计时器            timer = new Timer();            timer.schedule(new TimerTask() {                @Override                public void run() {                    mHandler.sendEmptyMessage(PLAY_TIME);                }            }, 0, 1000);        } catch (IllegalStateException e) {            Log.i(TAG, "prepare-IllegalStateException:" + e.getMessage());            finish();        }    }    private String formatTime(long time) {        SimpleDateFormat formatter = new SimpleDateFormat("mm:ss");        return formatter.format(new Date(time));    }    @Override    public void onSeekComplete(MediaPlayer mp) {        Log.i(TAG, "onSeekComplete:");    }    /**     * 当视频的大小发生变化的时候调用一次  当指定的数据源和读取视频的元数据后将至少调用它一次     *     * @param mp     * @param width     * @param height     */    @Override    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {        Log.i(TAG, "onVideoSizeChanged:");    }    @Override    public boolean onTouchEvent(MotionEvent event) {        return false;    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.i("TTTTT", "onDestroy");    }    @Override    protected void onPause() {        super.onPause();        Log.i("TTTTT", "onPause");    }    //重力感应监听    public class OrientationSensorListener implements SensorEventListener {        private static final int _DATA_X = 0;        private static final int _DATA_Y = 1;        private static final int _DATA_Z = 2;        public static final int ORIENTATION_UNKNOWN = -1;        private MyHandler myHandler;        private boolean isSupportGravity = false;        public OrientationSensorListener(MyHandler myHandler) {            this.myHandler = myHandler;        }        public void onAccuracyChanged(Sensor arg0, int arg1) {            // TODO Auto-generated method stub        }        public void onSensorChanged(SensorEvent event) {            /**             * 检测手机自动旋转屏幕的功能是否打开             */            isSupportGravity = isscreenAutoRotate();            if (!isSupportGravity) {                return;            }            if (sennorFlag != stretch_flag)  //只有两个不相同才开始监听行为            {                float[] values = event.values;                int orientation = ORIENTATION_UNKNOWN;                float X = -values[_DATA_X];                float Y = -values[_DATA_Y];                float Z = -values[_DATA_Z];                float magnitude = X * X + Y * Y;                // Don't trust the angle if the magnitude is small compared to the y value                if (magnitude * 4 >= Z * Z) {                    //屏幕旋转时                    float OneEightyOverPi = 57.29577957855f;                    float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;                    orientation = 90 - (int) Math.round(angle);                    // normalize to 0 - 359 range                    while (orientation >= 360) {                        orientation -= 360;                    }                    while (orientation < 0) {                        orientation += 360;                    }                }                if (myHandler != null) {                    myHandler.obtainMessage(10001, orientation, 0).sendToTarget();                }            }        }    }    public class OrientationSensorListener2 implements SensorEventListener {        //初始化重力感应器的坐标轴        private static final int sensor_X = 0;        private static final int sensor_Y = 1;        private static final int sensor_Z = 2;        private static final int ORIENTATION_UNKNOW = -1;        private boolean isSupportGravity = false;        public OrientationSensorListener2() {        }        @Override        public void onSensorChanged(SensorEvent event) {            /**             * 检测手机自动旋转屏幕的功能是否打开             */            isSupportGravity = isscreenAutoRotate();            if (!isSupportGravity) {                return;            }            float[] values = event.values;            int orientation = ORIENTATION_UNKNOW;            float X = -values[sensor_X];            float Y = -values[sensor_Y];            float Z = -values[sensor_Z];            /**             * 重力传感器监听手机的摆放状态的算法             */            float magnitude = X * X + Y * Y;            // Don't trust the angle if the magnitude is small compared to the y value            if (magnitude * 4 >= Z * Z) {                //屏幕旋转时                float OneEightyOverPi = 57.29577957855f;                float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;                orientation = 90 - (int) Math.round(angle);                // normalize to 0 - 359 range                while (orientation >= 360) {                    orientation -= 360;                }                while (orientation < 0) {                    orientation += 360;                }            }            if (orientation > 225 && orientation < 315) {  //横屏                sennorFlag = false;            } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {  //竖屏                sennorFlag = true;            }            if (stretch_flag == sennorFlag) {  //点击变成横屏  屏幕 也转横屏 激活                Log.i(TAG, "激活");                sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI);            }        }        @Override        public void onAccuracyChanged(Sensor sensor, int accuracy) {        }    }    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        Log.i("TTTTT", "onConfigurationChanged");        if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {            //如果是横屏            Log.i("WWWWWW", "横屏");            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);            surfaceView.setLayoutParams(params);            if (iv_suolue.getVisibility() == View.VISIBLE && !iv_play.isSelected() && !imageView_main_show.isSelected()) {                iv_suolue.setVisibility(View.GONE);                new GetVideoBitmapAsyncTask(iv_suolue, surfaceView).execute(filepath);            }        } else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {            mHandler.sendEmptyMessage(MEASURE_VIDEO_SIZE);            Log.i("WWWWWW", "竖屏");        } else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {            mHandler.sendEmptyMessage(MEASURE_VIDEO_SIZE);            Log.i("WWWWWW", "无屏");        }    }    /**     * 获取屏幕的缩略图     */    private class GetVideoBitmapAsyncTask extends AsyncTask<String, Void, Bitmap> {        private ImageView iv;        private SurfaceView sv;        public GetVideoBitmapAsyncTask(ImageView iv, SurfaceView sv) {            this.iv = iv;            this.sv = sv;        }        @Override        protected void onPreExecute() {            super.onPreExecute();        }        @Override        protected Bitmap doInBackground(String... params) {            /**             * 第三方库获得视频里的缩略图             */            FFmpegMediaMetadataRetriever fmmr = new FFmpegMediaMetadataRetriever();            try {                fmmr.setDataSource(params[0]);                Bitmap bitmap = fmmr.getFrameAtTime();                if (bitmap != null) {                    Bitmap b2 = fmmr                            .getFrameAtTime(                                    4000000,                                    FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC);                    if (b2 != null) {                        bitmap = b2;                    }                    if (bitmap.getWidth() > 640) {// 如果图片宽度规格超过640px,则进行压缩                        bitmap = ThumbnailUtils.extractThumbnail(bitmap,                                640, 480,                                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);                    }                    return bitmap;                }            } catch (IllegalArgumentException ex) {                ex.printStackTrace();            } finally {                fmmr.release();            }            return null;        }        @Override        protected void onPostExecute(Bitmap bitmap) {            super.onPostExecute(bitmap);            if (bitmap != null && !iv_play.isSelected() && !imageView_main_show.isSelected()) {                /**                 * 缩略图的大小应该和surfaceview的大小一样,无论竖屏还是横屏                 */                ViewGroup.LayoutParams layoutParams = iv.getLayoutParams();                ViewGroup.LayoutParams layoutParams1 = sv.getLayoutParams();                layoutParams.width = layoutParams1.width;                layoutParams.height = layoutParams1.height;                iv.setLayoutParams(layoutParams);                iv.setImageBitmap(bitmap);                iv.setVisibility(View.VISIBLE);            }        }    }    /**     * 检测手机自动旋转的是否打开     *     * @return     */    private boolean isscreenAutoRotate() {        int gravity = 0;        try {            gravity = Settings.System.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);        } catch (Settings.SettingNotFoundException e) {            e.printStackTrace();            Log.i(TAG, "检测手机是否打开屏幕旋转出错");        }        return gravity == 1;    }}


1 0
原创粉丝点击