利用VideoView简单实现视频播放 包括 横竖屏切换 声音 亮度 暂停

来源:互联网 发布:python re 匹配域名 编辑:程序博客网 时间:2024/05/29 07:37
          利用Google给的原组件VideoView来简单的实现视频播放.包括播放,暂停,横竖屏切换,声音的改变,屏幕亮度的改变,当声音改变时,会自动调用系统给的声音条,而当滑动亮度的时候需要自己给写个seekbar.

         由于如果刚开始我想让视频在竖屏的时候充满整个屏幕,当在布局中写上mach_parent的时候,他不会充满屏幕,所以我重写了一个类,让它继承VideoView,重写onMeasure方法,在这个里边会获取设备的宽高,然后设置给它.


public class FullVideoView extends VideoView {    public FullVideoView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //必须得注掉 不然的话就会默认的返回布局中的宽高//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取设备中的的总宽高        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        //将这些值返回到布局当中使得可以使用        setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);    }}


       进入布局的设置  把你所有需要的设置上


<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_video"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fei.advanceseven.VideoActivity">    <FrameLayout        android:id="@+id/video_container"        android:layout_width="match_parent"        android:layout_height="240dp">        <com.example.fei.advanceseven.widget.FullVideoView            android:id="@+id/videoView"            android:layout_width="match_parent"            android:layout_height="match_parent"/>        <!-- 播放的控制器 :                            屏幕中间有播放暂停的按钮                            屏幕的底部,播放时间,总时间,seekBar                            是否全屏按钮        -->        <FrameLayout            android:layout_width="match_parent"            android:layout_height="match_parent">            <SeekBar                android:visibility="gone"                android:id="@+id/brightness_display"                android:layout_marginTop="20dp"                android:layout_width="200dp"                android:layout_gravity="center_horizontal"                android:layout_height="wrap_content"/>            <CheckBox                android:layout_width="50dp"                android:layout_height="50dp"                android:layout_gravity="center"                android:id="@+id/pause_play"                android:button="@null"                android:gravity="center"                android:background="@drawable/pause_play_selector"                />            <LinearLayout                android:id="@+id/bottem_controller"                android:layout_width="match_parent"                android:layout_height="40dp"                android:layout_gravity="bottom"                android:orientation="horizontal"                >                <TextView                    android:id="@+id/current_position"                    android:layout_width="50dp"                    android:layout_height="match_parent"                    android:text="00:00"                    android:textColor="#fff"                    android:gravity="center"                    android:layout_marginLeft="5dp"                    />                <SeekBar                    android:id="@+id/progress_controller"                    android:layout_width="0dp"                    android:layout_gravity="center"                    android:layout_height="match_parent"                    android:layout_weight="1"                    />                <TextView                    android:id="@+id/duration"                    android:gravity="center"                    android:text="29:59"                    android:textColor="#fff"                    android:layout_width="50dp"                    android:layout_height="match_parent"/>                <CheckBox                    android:id="@+id/full_screen_controller"                    android:layout_width="40dp"                    android:button="@null"                    android:gravity="center"                    android:background="@drawable/full_screen_selector"                    android:layout_height="40dp"/>            </LinearLayout>        </FrameLayout>    </FrameLayout></RelativeLayout>


         进入主界面的代码设置,上边基本上都备注上每一步的原理  里边还包含了当点击回退键的时候让它在2秒内连续点击时退出程序.


public class VideoActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, CompoundButton.OnCheckedChangeListener,Handler.Callback, SeekBar.OnSeekBarChangeListener {    private FullVideoView mFullVideoView;    private TextView curent_position,duration;    private CheckBox pause_play,full_screen_controller;    //VideoView的容器    private FrameLayout video_container;    private String video_url = "http://ips.ifeng.com/video19.ifeng.com/video09/2017/05/02/4604457-102-1119.mp4";    private Handler mHandler = new Handler(this);    private SeekBar progress_ctroller;    private LinearLayout bottem_controller;    private int mHeight;    private SeekBar bright_display;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_video);        initView();    }    public SeekBar getBright_display() {        return bright_display;    }    private void initView() {        //设置亮度的seekbar        bright_display = (SeekBar) findViewById(R.id.brightness_display);        mFullVideoView = (FullVideoView) findViewById(R.id.videoView);        //时间控件        curent_position = (TextView) findViewById(R.id.current_position);        duration = (TextView) findViewById(R.id.duration);        // 2 设置暂停        pause_play = (CheckBox) findViewById(R.id.pause_play);        pause_play.setOnCheckedChangeListener(this);        // 3 是否全屏        full_screen_controller = (CheckBox) findViewById(R.id.full_screen_controller);        full_screen_controller.setOnCheckedChangeListener(this);        // 5 设置SeekBard 并设置他的点击事件        progress_ctroller = (SeekBar) findViewById(R.id.progress_controller);        progress_ctroller.setOnSeekBarChangeListener(this);//        mFullVideoView.setVideoPath(video_url);        mFullVideoView.setVideoURI(Uri.parse("android.resource://"+getPackageName()+ File.separator+R.raw.music_video));        // 1, 设置mFullVideoView的点击事件  是指预加载和加载错误        mFullVideoView.setOnPreparedListener(this);        mFullVideoView.setOnErrorListener(this);        bottem_controller = (LinearLayout) findViewById(R.id.bottem_controller);        // 4 设置最外层frameLayout的点击事件        video_container = (FrameLayout) findViewById(R.id.video_container);        //因为设置点击事件,他的事件分发就会被消费掉,使得下边的ontouth没用  因为他没有返回值 默认是消费掉//        video_container.setOnClickListener(new View.OnClickListener() {//            @Override//            public void onClick(View view) {//                bottem_controller.setVisibility(View.VISIBLE);//                mHandler.sendEmptyMessageDelayed(PAUSE_AUTO_DISAPPEAR,3000);//            }//        });        video_container.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View view, MotionEvent motionEvent) {                switch (motionEvent.getAction()){                    case MotionEvent.ACTION_DOWN:                        //checkBox和LinearLayout显示                        pause_play.setVisibility(View.VISIBLE);                        bottem_controller.setVisibility(View.VISIBLE);                         mHandler.sendEmptyMessageDelayed(PAUSE_AUTO_DISAPPEAR,3000);                        break;                }                return false;//不修改 点击事件还会继续传递            }        });        //handler发送消息  3秒之后播放和暂停的按钮消失        mHandler.sendEmptyMessageDelayed(PAUSE_AUTO_DISAPPEAR,3000);    }    @Override    public void onPrepared(MediaPlayer mediaPlayer) {        //当刚进入时让按钮默认是选中状态,视屏默认是播放状态        pause_play.setChecked(true);//让视屏进行播放    }    @Override    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {        //当视屏播放错误时,弹出一个对话框        AlertDialog.Builder builder = new AlertDialog.Builder(this);        builder.setIcon(R.mipmap.ic_launcher);        builder.setMessage("无法播放");        builder.setTitle("问题");        builder.setNegativeButton("取消",null);        builder.create().show();        return true;    }    //checkBox状态栏发生改变的监听  两个checkbox的状态栏    @Override    public void onCheckedChanged(CompoundButton compoundButton, boolean user) {        switch (compoundButton.getId()){            case R.id.pause_play:                if (user){//用户选中 视频播放 显示成暂停的图标                    //首先视频播放                    mFullVideoView.start();                    //修改播放的时间 handler帮助每隔一秒更新播放进度                    mHandler.sendEmptyMessageDelayed(UPDATE_PROGRESS,1000);                }else {                    mFullVideoView.pause();                    //移除 不让他继续去发送handler                    mHandler.removeMessages(UPDATE_PROGRESS);                }                break;            case R.id.full_screen_controller:                if (user){//用户点击了  全屏展示                    //设置全屏                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);                    //设置手机屏幕横向                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);                    //需要修改VieoView 的高度  如果不修改 当它横屏时不会去充满整个屏幕                    //首先获得原来的高度                    mHeight = video_container.getHeight();                    //重新制定高度                    ViewGroup.LayoutParams params = video_container.getLayoutParams();                    params.height = ViewGroup.LayoutParams.MATCH_PARENT;                    video_container.setLayoutParams(params);                }else {//从全屏状态回去                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);                    //还原之前的高度                    ViewGroup.LayoutParams portrait_params = video_container.getLayoutParams();                    portrait_params.height = mHeight;                    video_container.setLayoutParams(portrait_params);                }                break;        }    }    //更新进度的标志    public static final int UPDATE_PROGRESS = 1;    public static final int PAUSE_AUTO_DISAPPEAR = 2;//播放和暂停按钮设置    public static final int BRIGHTNESS_DISPLAY_DISAPPEAR = 3;    @Override    public boolean handleMessage(Message message) {        switch (message.what){            case UPDATE_PROGRESS://更新进度                //视频总时间  设置它的总时间是多少                int duration = mFullVideoView.getDuration();                if (progress_ctroller.getMax()==100){                    progress_ctroller.setMax(duration);                }                CharSequence format = DateFormat.format("mm:ss", duration);                this.duration.setText(format);                //设置当前播放的进度 并将当前的播放进度设置文本中                int currentPosition = mFullVideoView.getCurrentPosition();                CharSequence current_position = DateFormat.format("mm:ss", currentPosition);                this.curent_position.setText(current_position);                //设置seekbar的当前进度                progress_ctroller.setProgress(currentPosition);                mHandler.sendEmptyMessageDelayed(UPDATE_PROGRESS,1000);                break;            case PAUSE_AUTO_DISAPPEAR:                bottem_controller.setVisibility(View.GONE);                pause_play.setVisibility(View.GONE);                break;            case BRIGHTNESS_DISPLAY_DISAPPEAR:                bright_display.setVisibility(View.GONE);                break;        }        return true;    }    //seekbar点击事件实现的方法 当拉动的时候使得视屏也跟着动    @Override    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {        if (b){            mFullVideoView.seekTo(i);        }    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {    }    private  boolean isLandscape;    //横竖屏回调的方法 当没法在返回事件中写的时候 应该去重写这个方法,当横竖屏切换时必然会回调该方法    @Override    public void onConfigurationChanged(Configuration newConfig) {        switch (newConfig.orientation){            case Configuration.ORIENTATION_LANDSCAPE://横屏                isLandscape = true;                break;            case Configuration.ORIENTATION_PORTRAIT://竖屏                isLandscape = false;                break;        }        super.onConfigurationChanged(newConfig);    }    private long last_time = 0;    //点击回退键  如果是全屏,点击时首先回到竖屏    @Override    public void onBackPressed() {        Log.e("flag", "onBackPressed: +aaaaaaaaaaaaaaaaaaaaaaaaaa" );        //判断是否是横屏        if (isLandscape){            //设置屏幕为竖屏            full_screen_controller.setChecked(false);        }else {            //超过两秒            if (System.currentTimeMillis()-last_time>2000){                Toast.makeText(this,"再次点击退出程序",Toast.LENGTH_LONG).show();                last_time = System.currentTimeMillis();            }else {                super.onBackPressed();            }        }    }    private float laxt_x,laxt_y;    //手指在屏幕上滑动时 快进 快退 声音 屏幕亮度    @Override    public boolean onTouchEvent(MotionEvent event) {        if (isLandscape){//手机横屏            switch (event.getAction()){                case MotionEvent.ACTION_DOWN://手指按下                    //手指按下 记录                    laxt_x = event.getX();                    laxt_y = event.getY();                    break;                case MotionEvent.ACTION_MOVE://手指在屏幕上移动                    //如果在x轴方向移动的变化大于y轴  快进 快退                    float x = event.getX();                    float y = event.getY();                    if (Math.abs(x-laxt_x)>Math.abs(y-laxt_y)){//快进,退                        if (Math.abs(x-laxt_x)>10){                                int widthPixels = this.getResources().getDisplayMetrics().widthPixels;                                float xDelta = x - laxt_x;                            if (x-laxt_x>10){//进                                forwa(xDelta,widthPixels);                            }else if (x-laxt_x<-10){//退                                backward(xDelta,widthPixels);// 该值是负数                            }                        }                    }else {//视屏亮度                        //手机屏幕左半部分 修改亮度                        if (Math.abs(y-laxt_y)>10){//用户有意识进行滑动                            float yDilta = y - laxt_y;                            //y轴方向的总高度                            int heightPixels = this.getResources().getDisplayMetrics().heightPixels;                            if (x<this.getResources().getDisplayMetrics().widthPixels/2){                                //                                if (y-laxt_y>10){                                    LightnessController.turnDown(this,yDilta,heightPixels);                                }else if (y-laxt_y<-10){                                    LightnessController.turnUp(this,yDilta,heightPixels);                                }                            }else {                                //手机屏幕右半部分 修改声音                                    if (y-laxt_y>10){//向下移动 声音降低                                        AudioController.turnDown(this,yDilta,heightPixels);                                    }else if (y-laxt_y<-10){//向上移动,声音反放打                                        AudioController.turnup(this,yDilta,heightPixels);                                    }                            }                        }                    }                    break;                case MotionEvent.ACTION_UP:                    //修改手指滑动的位置                    laxt_x = event.getX();                    laxt_y = event.getY();                mHandler.sendEmptyMessageDelayed(BRIGHTNESS_DISPLAY_DISAPPEAR,1000);                    break;            }        }else {//竖屏展示        }        return super.onTouchEvent(event);    }    private void backward(float xDelta, int widthPixels) {        int duration = mFullVideoView.getDuration();        int currentPosition = mFullVideoView.getCurrentPosition();        float durationDelta = xDelta / widthPixels * duration;//负数        int video_move_position = (int) Math.max(0, currentPosition + durationDelta);        mFullVideoView.seekTo(video_move_position);        progress_ctroller.setProgress(video_move_position);        //当前播放的时间        curent_position.setText(DateFormat.format("mm:ss",video_move_position));    }    //视屏快进    private void forwa(float xDelta, int widthPixels) {        int duration = mFullVideoView.getDuration();        int currentPosition = mFullVideoView.getCurrentPosition();        float durationDelta = xDelta / widthPixels * duration;        //参数二是相加得到的  有可能大于视屏的总长度        int video_move_position = (int) Math.min(duration, currentPosition + durationDelta);        mFullVideoView.seekTo(video_move_position);        //移动seekbar        progress_ctroller.setProgress(video_move_position);        //当前播放的时间        curent_position.setText(DateFormat.format("mm:ss",video_move_position));    }    //程序退出  将handler中所发送的消息移除    @Override    protected void onDestroy() {        super.onDestroy();        mHandler.removeMessages(UPDATE_PROGRESS);    }}


     由于主页面代码太多,所以给横屏设置亮度和声音的代码都写到了另外一个类中,主页面只声明了方法.

     以下是在另外一个类中设置声音的代码


public class AudioController {    public static void turnDown(Context context, float yDilta, int heightPixels) {        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);        //当前音量        int streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);        //获取最大英两        int streamMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);        //计算音量的改变量        float streamDelta = yDilta / heightPixels * streamMaxVolume;        //改变后的音量        int changeStreamVolume = (int) Math.max(0, streamVolume - streamDelta);        //将改变后的音量设置给西屯        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,changeStreamVolume,AudioManager.FLAG_SHOW_UI);    }    public static void turnup(Context context, float yDilta, int heightPixels) {        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);        //当前音量        int streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);        //获取最大英两        int streamMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);        //计算音量的改变量        float streamDelta = yDilta / heightPixels * streamMaxVolume;        //改变后的音量        int changeStreamVolume = (int) Math.min(streamMaxVolume, streamVolume - streamDelta);        //将改变后的音量设置给西屯        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,changeStreamVolume,AudioManager.FLAG_SHOW_UI);    }}


         以下是在另外一个类中,设置亮度的代码


public class LightnessController {    public static void turnDown(Context context, float yDilta, int heightPixels) {        //获取系统当前的亮度        try {            int current_brightness = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);            //计算亮度的改变值            int brightnessDelta = (int) (yDilta / heightPixels * 255);            //亮度最下,不能小于25            int changedBrightness = Math.max(25, current_brightness - brightnessDelta);            //修改屏幕的亮度            WindowManager.LayoutParams attributes = ((Activity) context).getWindow().getAttributes();//窗体的属性集合            attributes.screenBrightness = changedBrightness*1.0f/255;            ((Activity) context).getWindow().setAttributes(attributes);            //当前的亮度设置给系统            Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,changedBrightness);            //获取SeekBar            SeekBar bright_display = ((VideoActivity) context).getBright_display();            if (bright_display.getMax()!=255){                bright_display.setMax(255);            }            bright_display.setVisibility(View.VISIBLE);            bright_display.setProgress(changedBrightness);        } catch (Settings.SettingNotFoundException e) {            e.printStackTrace();        }    }    public static void turnUp(Context context, float yDilta, int heightPixels) {        //获取系统当前的亮度        try {            int current_brightness = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);            //计算亮度的改变值            int brightnessDelta = (int) (yDilta / heightPixels * 255);            //亮度最下,不能小于25            int changedBrightness = Math.min(255, current_brightness - brightnessDelta);            //修改屏幕的亮度            WindowManager.LayoutParams attributes = ((Activity) context).getWindow().getAttributes();//窗体的属性集合            attributes.screenBrightness = changedBrightness*1.0f/255;            ((Activity) context).getWindow().setAttributes(attributes);            //当前的亮度设置给系统            Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,changedBrightness);            //获取SeekBar            SeekBar bright_display = ((VideoActivity) context).getBright_display();            if (bright_display.getMax()!=255){                bright_display.setMax(255);            }            bright_display.setVisibility(View.VISIBLE);            bright_display.setProgress(changedBrightness);        } catch (Settings.SettingNotFoundException e) {            e.printStackTrace();        }    }}


 

                                                           如果哪里可以优化  尽请留言交流



    




3 0