自定义视频播放器——VideoView和其他控件的组合
来源:互联网 发布:淘宝开放平台 编辑:程序博客网 时间:2024/06/05 14:20
下面是自己写的一个视频播放器,只是用Android已有的控件组合了一下,个人觉得Android提供的MediaController不好看(或许可以修改,没试),自己定义了一个播放控制面板,可以播放、暂停、改变播放进度、全屏和非全屏。
1.播放器的布局文件simple_video_view.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#000000" > <!-- 视频控件 --> <VideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" /> <!-- 播放控制面板 --> <LinearLayout android:id="@+id/control_panel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/video_view" android:orientation="horizontal" android:background="#70000000" android:visibility="gone" > <ImageView android:id="@+id/play_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:src="@drawable/play_icon" android:padding="4dp" android:scaleType="centerInside" android:contentDescription="@string/app_name" /> <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" ><SeekBar android:id="@+id/progress_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxHeight="4dp" android:layout_centerVertical="true" android:paddingStart="8dp" android:paddingEnd="8dp" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignEnd="@id/progress_bar" android:layout_below="@id/progress_bar" android:textSize="12sp" android:textColor="#ffffff" /> </RelativeLayout><ImageView android:id="@+id/full_screen_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/full_screen_icon" android:layout_gravity="center_vertical" android:padding="4dp" android:scaleType="centerInside" android:contentDescription="@string/app_name" /> </LinearLayout> <!-- 大播放按钮 --> <ImageViewandroid:id="@+id/big_play_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/big_play_icon"android:scaleType="centerInside"android:layout_centerInParent="true" android:contentDescription="@string/app_name"/></RelativeLayout>
2.SimpleVideoView类
package com.example.test;import android.app.Activity;import android.content.Context;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.graphics.Point;import android.graphics.drawable.Drawable;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.media.MediaPlayer.OnPreparedListener;import android.net.Uri;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.WindowManager;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import android.widget.TextView;import android.widget.VideoView;public class SimpleVideoView extends RelativeLayout implements OnClickListener{private Context context;private View mView;private VideoView mVideoView;//视频控件private ImageView mBigPlayBtn;//大的播放按钮private ImageView mPlayBtn;//播放按钮private ImageView mFullScreenBtn;//全屏按钮private SeekBar mPlayProgressBar;//播放进度条private TextView mPlayTime;//播放时间private LinearLayout mControlPanel;private Uri mVideoUri = null;private Animation outAnima;//控制面板出入动画private Animation inAnima;//控制面板出入动画private int mVideoDuration;//视频毫秒数private int mCurrentProgress;//毫秒数private Runnable mUpdateTask;private Thread mUpdateThread;private final int UPDATE_PROGRESS = 0;private final int EXIT_CONTROL_PANEL = 1;private boolean stopThread = true;//停止更新进度线程标志private Point screenSize = new Point();//屏幕大小private boolean mIsFullScreen = false;//是否全屏标志private int mWidth;//控件的宽度private int mHeigth;//控件的高度 public SimpleVideoView(Context context){ super(context); init(context, null, 0); } public SimpleVideoView(Context context, AttributeSet attrs){ super(context, attrs); init(context, attrs, 0); } public SimpleVideoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg){ switch(msg.what){ case UPDATE_PROGRESS: mPlayProgressBar.setProgress(mCurrentProgress); setPlayTime(mCurrentProgress); break; case EXIT_CONTROL_PANEL: //执行退出动画 if(mControlPanel.getVisibility() != View.GONE){ mControlPanel.startAnimation(outAnima);mControlPanel.setVisibility(View.GONE); } break; } } }; //初始化控件private void init(Context context, AttributeSet attrs, int defStyleAttr){this.context = context;mView = LayoutInflater.from(context).inflate(R.layout.simple_video_view, this);mBigPlayBtn = (ImageView) mView.findViewById(R.id.big_play_button);mPlayBtn = (ImageView) mView.findViewById(R.id.play_button);mFullScreenBtn = (ImageView) mView.findViewById(R.id.full_screen_button);mPlayProgressBar = (SeekBar) mView.findViewById(R.id.progress_bar);mPlayTime = (TextView) mView.findViewById(R.id.time);mControlPanel = (LinearLayout) mView.findViewById(R.id.control_panel);mVideoView = (VideoView) mView.findViewById(R.id.video_view);//获取屏幕大小((Activity) context).getWindowManager().getDefaultDisplay().getSize(screenSize);//加载动画outAnima = AnimationUtils.loadAnimation(context, R.anim.exit_from_bottom);inAnima = AnimationUtils.loadAnimation(context, R.anim.enter_from_bottom);//设置控制面板初始不可见mControlPanel.setVisibility(View.GONE);//设置大的播放按钮可见mBigPlayBtn.setVisibility(View.VISIBLE);//设置媒体控制器//mMediaController = new MediaController(context);//mMediaController.setVisibility(View.GONE);//mVideoView.setMediaController(mMediaController);mVideoView.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {//视频加载完成后才能获取视频时长initVideo();}});//视频播放完成监听器mVideoView.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {mPlayBtn.setImageResource(R.drawable.play_icon);mVideoView.seekTo(0);mPlayProgressBar.setProgress(0);setPlayTime(0);stopThread = true;sendHideControlPanelMessage();}});mView.setOnClickListener(this);}//初始化视频,设置视频时间和进度条最大值private void initVideo(){//初始化时间和进度条mVideoDuration = mVideoView.getDuration();//毫秒数int seconds = mVideoDuration/1000;mPlayTime.setText("00:00/"+((seconds/60>9)?(seconds/60):("0"+seconds/60))+":"+((seconds%60>9)?(seconds%60):("0"+seconds%60)));mPlayProgressBar.setMax(mVideoDuration);mPlayProgressBar.setProgress(0);//更新进度条和时间任务mUpdateTask = new Runnable(){@Overridepublic void run(){while(!stopThread){mCurrentProgress = mVideoView.getCurrentPosition();handler.sendEmptyMessage(UPDATE_PROGRESS);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}};mBigPlayBtn.setOnClickListener(this);mPlayBtn.setOnClickListener(this);mFullScreenBtn.setOnClickListener(this);//进度条进度改变监听器mPlayProgressBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) { handler.sendEmptyMessageDelayed(EXIT_CONTROL_PANEL, 3000);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) { handler.removeMessages(EXIT_CONTROL_PANEL);}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {if(fromUser){mVideoView.seekTo(progress);//设置视频setPlayTime(progress);//设置时间}}});mWidth = this.getWidth();mHeigth = this.getHeight();}@Overridepublic void onClick(View v) {if(v == mView){if(mBigPlayBtn.getVisibility() == View.VISIBLE){return;}if(mControlPanel.getVisibility() == View.VISIBLE){//执行退出动画mControlPanel.startAnimation(outAnima);mControlPanel.setVisibility(View.GONE);}else {//执行进入动画mControlPanel.startAnimation(inAnima);mControlPanel.setVisibility(View.VISIBLE);sendHideControlPanelMessage();}}else if(v.getId() == R.id.big_play_button){//大的播放按钮mBigPlayBtn.setVisibility(View.GONE);mVideoView.setBackground(null);if(!mVideoView.isPlaying()){mVideoView.start();mPlayBtn.setImageResource(R.drawable.pause_icon);//开始更新进度线程mUpdateThread = new Thread(mUpdateTask);stopThread = false;mUpdateThread.start();}}else if(v.getId() == R.id.play_button){//播放/暂停按钮if(mVideoView.isPlaying()){mVideoView.pause();mPlayBtn.setImageResource(R.drawable.play_icon);}else{if(mUpdateThread == null || !mUpdateThread.isAlive()){//开始更新进度线程mUpdateThread = new Thread(mUpdateTask);stopThread = false;mUpdateThread.start();}mVideoView.start();mPlayBtn.setImageResource(R.drawable.pause_icon);}sendHideControlPanelMessage();}else if(v.getId() == R.id.full_screen_button){//全屏if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){setFullScreen();}else{setNoFullScreen();}sendHideControlPanelMessage();}}//设置当前时间private void setPlayTime(int millisSecond){int currentSecond = millisSecond/1000;String currentTime = ((currentSecond/60>9)?(currentSecond/60+""):("0"+currentSecond/60))+":"+((currentSecond%60>9)?(currentSecond%60+""):("0"+currentSecond%60));StringBuilder text = new StringBuilder(mPlayTime.getText().toString());text.replace(0, text.indexOf("/"), currentTime);mPlayTime.setText(text);}//设置控件的宽高private void setSize(){ViewGroup.LayoutParams lp = this.getLayoutParams();if(mIsFullScreen){lp.width = screenSize.y;lp.height = screenSize.x;}else{lp.width = mWidth;lp.height = mHeigth;}this.setLayoutParams(lp);}//两秒后隐藏控制面板private void sendHideControlPanelMessage(){handler.removeMessages(EXIT_CONTROL_PANEL);handler.sendEmptyMessageDelayed(EXIT_CONTROL_PANEL, 3000);}//设置视频路径public void setVideoUri(Uri uri){this.mVideoUri = uri;mVideoView.setVideoURI(mVideoUri);}//获取视频路径public Uri getVideoUri(){return mVideoUri;}//设置视频初始画面public void setInitPicture(Drawable d){mVideoView.setBackground(d);}//挂起视频public void suspend(){if(mVideoView != null){mVideoView.suspend();}}//设置视频进度public void setVideoProgress(int millisSecond,boolean isPlaying){mVideoView.setBackground(null);mBigPlayBtn.setVisibility(View.GONE);mPlayProgressBar.setProgress(millisSecond);setPlayTime(millisSecond);if(mUpdateThread == null || !mUpdateThread.isAlive()){mUpdateThread = new Thread(mUpdateTask);stopThread = false;mUpdateThread.start();}mVideoView.seekTo(millisSecond);if(isPlaying){mVideoView.start();mPlayBtn.setImageResource(R.drawable.pause_icon);}else{mVideoView.pause();mPlayBtn.setImageResource(R.drawable.play_icon);}}//获取视频进度public int getVideoProgress(){return mVideoView.getCurrentPosition();}//判断视频是否正在播放public boolean isPlaying(){return mVideoView.isPlaying();}//判断是否为全屏状态public boolean isFullScreen(){return mIsFullScreen;}//设置竖屏public void setNoFullScreen(){this.mIsFullScreen = false;Activity ac = (Activity)context;ac.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);ac.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);setSize();}//设置横屏public void setFullScreen(){this.mIsFullScreen = true;Activity ac = (Activity)context;ac.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);ac.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);setSize();}}
3.隐藏和显示播放控制面板的动画
进入动画enter_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromYDelta="100%"android:toYDelta="0"android:duration="400"</translate>
退出动画exit_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromYDelta="0"android:toYDelta="100%"android:duration="400"</translate>
4.播放本地视频和网络视频需要的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET" />
5.改变屏幕方向
<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
不注明keyboardHidden|orientation|screenSize屏幕方向改变时会停止播放
6.activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.test.SimpleVideoView android:id="@+id/video" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
package com.example.test;import android.net.Uri;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity{private SimpleVideoView video;private String videoPath;@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); video = (SimpleVideoView) findViewById(R.id.video); video.setInitPicture(getResources().getDrawable(R.drawable.ic_launcher,null)); //网络视频地址 videoPath = "http://112.253.22.157/17/z/z/y/u/zzyuasjwufnqerzvyxgkuigrkcatxr/hc.yinyuetai.com/D046015255134077DDB3ACA0D7E68D45.flv"; //本地视频路径 //videoPath= "/storage/emulated/0/Android/data/com.boohee.one/.SPORT_VIDEOS/1pfl0bzsp1mhs3ur1cahe82x1.mp4"; videoPath = "/storage/emulated/0/tencent/QQfile_recv/这货是一条鳄鱼.mp4"; video.setVideoUri(Uri.parse(videoPath)); }@Overrideprotected void onDestroy(){super.onDestroy();video.suspend();}@Overridepublic void onBackPressed(){if(video.isFullScreen()){video.setNoFullScreen();}else{super.onBackPressed();}}}
非全屏效果:
全屏效果:
0 0
- 自定义视频播放器——VideoView和其他控件的组合
- android之视频播放系统VideoView和自定义VideoView控件的应用
- 基于videoView的自定义播放控制器的视频播放器
- 基于VideoView的自定义控制面板的视频播放器
- 视频播放控件VideoView的基本使用
- Android中自定义VideoView视频播放器
- 使用VideoView自定义一个播放器控件
- 自定义VideoView播放网络视频
- Android 视频播放器 VideoView 的使用,播放本地视频 和 网络 视频
- VideoView视频播放器
- Android VideoView 自定义播放器 MediaController 实现视频播放控制和横竖屏适配
- VideoView视频播放器的再打开
- 最简单的VideoView视频播放器
- Android开发播放视频控制进度的控件VideoView
- VideoView和SurfaceView播放视频
- VideoView和SurfaceView视频播放
- videoView和mediaController视频播放
- 视频播放,VideoView的使用。
- 基于opencv和c++的均值滤波
- Noip2009解题报告
- SpringMVC 自定义全局PropertyEditor
- Intelli Idea全局替换
- JavaScript-说说为啥循环闭包只显示最后一个i的值
- 自定义视频播放器——VideoView和其他控件的组合
- ajax的data
- opencv实现车牌识别之车牌号定位_1
- gTimer protocol的实现
- servlet的自动加载+init方法+线程并发安全
- C++模板
- python格式化字符串和转义字符
- GraphLab Create API(中文文档)-deeplearning
- NAT与NAPT网络地址转换