利用VideoView简单实现视频播放 包括 横竖屏切换 声音 亮度 暂停
来源:互联网 发布:python re 匹配域名 编辑:程序博客网 时间:2024/05/29 07:37
利用Google给的原组件VideoView来简单的实现视频播放.包括播放,暂停,横竖屏切换,声音的改变,屏幕亮度的改变,当声音改变时,会自动调用系统给的声音条,而当滑动亮度的时候需要自己给写个seekbar.
由于如果刚开始我想让视频在竖屏的时候充满整个屏幕,当在布局中写上mach_parent的时候,他不会充满屏幕,所以我重写了一个类,让它继承VideoView,重写onMeasure方法,在这个里边会获取设备的宽高,然后设置给它.
进入布局的设置 把你所有需要的设置上
进入主界面的代码设置,上边基本上都备注上每一步的原理 里边还包含了当点击回退键的时候让它在2秒内连续点击时退出程序.
由于主页面代码太多,所以给横屏设置亮度和声音的代码都写到了另外一个类中,主页面只声明了方法.
以下是在另外一个类中设置声音的代码
以下是在另外一个类中,设置亮度的代码
如果哪里可以优化 尽请留言交流
由于如果刚开始我想让视频在竖屏的时候充满整个屏幕,当在布局中写上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
- 利用VideoView简单实现视频播放 包括 横竖屏切换 声音 亮度 暂停
- Android使用VideoView和MediaController播放网络视频(包括横竖排切换的处理)
- android关于VideoView或Vitamio视频播放器横竖屏切换
- 基于VideoView实现视频播放文件切换
- videoview 横竖屏切换
- android利用VideoView实现视频全屏播放
- Android:利用VideoView实现视频播放器
- 利用VideoView播放视频
- 利用VideoView播放视频
- iOS Swift3.0实现视频播放横竖屏切换效果
- 使用VideoView实现简单视频播放器
- 使用VideoView实现简单视频播放器
- 魅族MX5——视频播放,横竖屏切换黑屏,有声音没图像
- VideoView简单视频播放
- VideoView简单视频播放
- 使用VideoView播放、暂停、快进视频
- videoview实现视频播放
- videoview实现视频播放
- 解读机器学习基础概念:VC维的来龙去脉
- "viewport" content="width=device-width
- Machine Learning第六讲[应用机器学习的建议] --(五)使用大的数据集
- Tomcat下HTTPS(SSL)搭建工作的始末
- Android 事件
- 利用VideoView简单实现视频播放 包括 横竖屏切换 声音 亮度 暂停
- 程序员日常工作英文20170504
- ssm整合之五 分页以及按时间查询
- Jquery简单过滤选择器(应用最广泛的选择器)
- JQuery Form表单转JSON(支持复杂数据版)
- Faster-R-CNN(Python).1:从配置到demo
- 海康IPC+ffmpeg+nginx+ckplayer实现网页实时预览监控视频
- RMQ+ST 区间最值/区间最多频次
- linux经常管理与查看指令:ps、pstree、top、kill、jobs和nice