VideoView是安卓自带的视频播放器类,该类集成有显示和控制两大部分,在布局文件中添加VideoView然后在java文件中简单的调用控制命令,即可实现本地或者网络视频的播放。本章实现视频的居中播放、网络视频播放、本地视频播放、视频卡顿监听、网络连接错误监听、视频外自定义视频控件、视频内自定义视频控件等。
支持的格式:flv、3gp、mp4
类的一些重要方法
void start(); //开始播放
void pause(); //暂停
void resume(); //重新播放,使用时需要在本句后加上开始播放
void seekTo(int msec); //从第几毫秒开始播放
void stopPlayback(); //停止播放并释放资源
int getCurrentPosition(); //获取当前播放的位置。
int getDuration(); //获取当前播放视频的总长度。
void setVideoPath(String path); //以文件路径的方式设置VideoView播放的视频源。
void setVideoURI(Uri uri); //以Uri的方式设置VideoView播放的视频源,可以是网络Uri或本地Uri
void isPlaying(); //当前VideoView是否在播放视频
setMediaController(MediaController controller); //设置MediaController控制器
setOnCompletionListener(MediaPlayer.onCompletionListener l); //监听播放完成的事件
setOnErrorListener(MediaPlayer.OnErrorListener l); //监听播放发生错误时候的事件
setOnPreparedListener(MediaPlayer.OnPreparedListener l); //监听视频装载完成的事件
setOnInfoListener(new MediaPlayer.OnInfoListener(){}); //视频卡顿监听
实现简单的视频播放
布局文件:
实现视频播放重要在于VideoView标签,如果让该标签的父级标签为FramLayout,设置相应属性就可以实现视频居中播放和默认的播放控件 MediaController 在视频内显示效果,还可以在VidoView标签上层加入TextView标签,实现视频播放的一些状态显示,如播放卡顿、切换播放、播放失败等的提示信息显示。另外可加入ImageView标签,即可显示图片或gif图,更具人性化。
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:paddingBottom="0dp"
7 android:paddingLeft="0dp"
8 android:paddingRight="0dp"
9 android:orientation="vertical"
10 android:paddingTop="0dp"
11 tools:context="com.example.videodong.MainActivity">
12
13 <TextView
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:text="视频播放器:\n"
17 android:textSize="15dp"
18 android:id="@+id/textView" />
19 <FrameLayout
20 android:layout_width="match_parent"
21 android:background="@color/colorBlack"
22 android:layout_height="300dp">
23 <VideoView
24 android:layout_width="match_parent"
25 android:layout_gravity="center"
26 android:layout_height="300dp"
27 android:id="@+id/videoView"
28 />
29
30 <TextView
31 android:layout_width="wrap_content"
32 android:layout_height="wrap_content"
33 android:textSize="15dp"
34 android:text="点击播放"
35 android:textColor="@color/colorWhite"
36 android:id="@+id/vv_text"
37 android:layout_gravity="center" />
38 </FrameLayout>
39
40 <ProgressBar
41 android:id="@+id/vv_bar"
42 style="?android:attr/progressBarStyleHorizontal"
43 android:layout_width="match_parent"
44 android:layout_height="wrap_content"/>
45
46 <TextView
47 android:layout_width="wrap_content"
48 android:text="时间轴为:0.00/000"
49 android:id="@+id/vv_starttime"
50 android:layout_height="wrap_content" />
51
52
53 <LinearLayout
54 android:layout_width="match_parent"
55 android:orientation="horizontal"
56 android:layout_gravity="center"
57 android:layout_height="wrap_content">
58 <TextView
59 android:layout_width="wrap_content"
60 android:layout_weight="1"
61 android:layout_height="wrap_content" />
62 <Button
63 android:layout_width="wrap_content"
64 android:text="开始"
65 android:id="@+id/vv_start"
66 android:layout_height="wrap_content" />
67 <Button
68 android:layout_width="wrap_content"
69 android:text="暂停"
70 android:id="@+id/vv_pause"
71 android:layout_height="wrap_content" />
72 <Button
73 android:layout_width="wrap_content"
74 android:text="重播"
75 android:id="@+id/vv_restart"
76 android:layout_height="wrap_content" />
77 <Button
78 android:layout_width="wrap_content"
79 android:text="下一个"
80 android:id="@+id/vv_next"
81 android:layout_height="wrap_content" />
82
83 </LinearLayout>
84 <TextView
85 android:layout_width="wrap_content"
86 android:id="@+id/vv_state"
87 android:layout_height="wrap_content" />
88 </LinearLayout>
View Code
需要添加的权限:
因为视频来源可以是网络或者本地,所以需要动态申请网络访问权限和本地文件读写权限,文件读写权限一般还需要手动获取
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
寻找到VideoView控件:
vv=(VideoView)findViewById(R.id.videoView);
视频预装完成监听:
1 //视频准备完成时进入
2 vv.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
3 @Override
4 public void onPrepared(MediaPlayer mp) {
5 //设置屏幕提示信息为空
6 vv_text.setText("");
7 }
8 });
视频播放完成监听:
1 vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
2 @Override
3 public void onCompletion(MediaPlayer mp) {
4 String strres="播放完成";
5 //判断视频的总长度与当前长度是否在误差区间内
6 if(Math.abs(vv.getDuration()-vv.getCurrentPosition())>1000){
7
8 strres="播放错误,可能无网络连接";
9
10 }
11 //设置屏幕提示信息
12 vv_text.setText(strres);
13
14 }
15 });
视频播放错误监听:
1 vv.setOnErrorListener(new MediaPlayer.OnErrorListener() {
2 @Override
3 public boolean onError(MediaPlayer mp, int what, int extra)
4 {
5 //设置屏幕显示信息
6 vv_text.setText("视频未知错误");
7
8 return false;
9 }
10 });
视频卡顿和停止卡顿监听:
1 vv.setOnInfoListener(new MediaPlayer.OnInfoListener(){
2 @Override
3 public boolean onInfo(MediaPlayer mp, int what, int extra){
4
5 switch(what){
6 case MediaPlayer.MEDIA_INFO_BUFFERING_START:
7 //设置屏幕显示信息,开始卡顿
8 vv_text.setText("视频卡顿,加载中.....");
9 break ;
10 case MediaPlayer.MEDIA_INFO_BUFFERING_END:
11 //设置屏幕显示信息,卡顿结束
12 vv_text.setText("");
13 break ;
14 }
15 return true;
16 }
17 }) ;
设置播放资源:
1 //本地文件
2 vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
3
4 //URL形式,支持本地URL和网络URL
5 //vv.setVideoURI(Uri.parse("https://www.bilibili.com/video/xxxxx"));
6
7 //设置自带的播放控件
8 //vv.setMediaController(new MediaController(this));
播放开始按钮监听:
1 //开始播放视频按钮
2 vv_start.setOnClickListener(new View.OnClickListener() {
3 @Override
4 public void onClick(View v) {
5
6 //设置屏幕显示信息
7 vv_text.setText("");
8
9 //开始播放
10 vv.start();
11
12 }
13 });
播放暂停按钮监听:
1 //暂停播放视频按钮
2 vv_pause.setOnClickListener(new View.OnClickListener() {
3 @Override
4 public void onClick(View v) {
5
6 //设置屏幕显示信息
7 vv_text.setText("视频暂停中");
8
9 //暂停视频播放
10 vv.pause();
11
12 }
13 });
重新播放按钮监听:
1 //重新播放视频
2 vv_restart.setOnClickListener(new View.OnClickListener() {
3 @Override
4 public void onClick(View v) {
5 //设置屏幕显示信息
6 vv_text.setText("正在重新播放中,请稍等");
7
8 //设置时间轴显示为0
9 vv_starttime.setText("时间轴为:0.00/0.00");
10
11 //设置进度条显示为0
12 vv_bar.setProgress(0);
13
14 //重新播放视频
15 vv.resume();
16 vv.start();
17
18 }
19 });
播放下一个视频监听:
1 vv_next.setOnClickListener(new View.OnClickListener() {
2 @Override
3 public void onClick(View v) {
4 //设置屏幕显示信息
5 vv_text.setText("正在切换,请稍等");
6
7 //设置时间轴为0
8 vv_starttime.setText("时间轴为:0.00/0.00");
9
10 //设置进度条为0
11 vv_bar.setProgress(0);
12
13 //停止播放
14 vv.pause();//暂停
15 vv.stopPlayback();//停止播放并释放资源
16
17 //得到下一个视频的资源
18 if(nextbool){
19 nextbool=false;
20 //网络资源,该url已经过期
21 vv.setVideoURI(Uri.parse("http://193.112.87.88/video/xx.flv"));
22 } else {
23 nextbool=true;
24 //本地资源
25 vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
26 }
27
28 //开始播放下一个
29 vv.start();
30
31 }
32 });
时间轴时间显示和进度条更新实现:
时间轴时间显示计算将在后文给出解释,另外 %02d 可以实现自动补零效果,runOnUiThread可以在普通线程中进入UI线程,可以实现UI的一系列操作。
1 new Thread(new Runnable() {
2 @Override
3 public void run() {
4 while (true){
5 //延时1秒
6 try {
7 Thread.sleep(1);
8 } catch (InterruptedException e) {
9 e.printStackTrace();
10 }
11
12 //进入主线程更新UI
13 runOnUiThread(new Runnable() {
14 @Override
15 public void run() {
16 if(vv.isPlaying()) {
17
18 //获取到视频播放进度
19 int maxx=vv.getDuration();
20 int progress=vv.getCurrentPosition();
21
22 //设置进度条信息
23 vv_bar.setMax(maxx);
24 vv_bar.setProgress(progress);
25
26 //得到时间轴字符串
27 String strtime=String.format("时间轴为:%02d:%02d/%02d:%02d", (progress % 3600000) / 60000,(progress % 60000 ) / 1000, (maxx % 3600000) / 60000,(maxx % 60000 ) / 1000);
28 //显示时间轴信息
29 vv_starttime.setText(strtime);
30
31 }
32 }
33 });
34 }
35
36 }
37 }).start();
View Code
视频播放进阶
利用FrameLayout的层叠效果,实现视频控件面板在视频层之上显示,利用视频控件的点击事件,实现视频点击监听然后改变视频控制面板的隐藏和显示。其他的视频播放控制代码基本以上相似
布局文件改变:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:paddingBottom="0dp"
7 android:paddingLeft="0dp"
8 android:paddingRight="0dp"
9 android:orientation="vertical"
10 android:paddingTop="0dp"
11 tools:context="com.example.videodong.MainActivity">
12
13 <TextView
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:text="视频播放器:\n"
17 android:textSize="15dp"
18 android:id="@+id/textView" />
19 <FrameLayout
20 android:layout_width="match_parent"
21 android:background="@color/colorBlack"
22 android:layout_height="230dp">
23 <VideoView
24 android:layout_width="match_parent"
25 android:layout_gravity="center"
26 android:layout_height="230dp"
27 android:id="@+id/videoView"
28 />
29 <FrameLayout
30 android:layout_width="match_parent"
31 android:layout_gravity="bottom"
32 android:id="@+id/vv_framel"
33 android:layout_height="wrap_content">
34 <ImageView
35 android:layout_width="match_parent"
36 android:background="@color/colorWhite"
37 android:alpha="0.5"
38 android:layout_height="match_parent" />
39 <LinearLayout
40 android:layout_width="match_parent"
41 android:orientation="vertical"
42
43 android:layout_height="wrap_content">
44 <ProgressBar
45 android:id="@+id/vv_bar"
46 style="?android:attr/progressBarStyleHorizontal"
47 android:layout_width="match_parent"
48 android:layout_height="wrap_content"/>
49 <LinearLayout
50 android:layout_width="match_parent"
51 android:orientation="horizontal"
52 android:layout_gravity="center"
53 android:layout_height="wrap_content">
54 <TextView
55 android:layout_width="wrap_content"
56 android:text="时间轴为:0.00/000"
57 android:id="@+id/vv_starttime"
58 android:layout_weight="1"
59 android:layout_height="wrap_content" />
60 <Button
61 android:layout_width="wrap_content"
62 android:text="开始"
63 style="?android:attr/buttonStyleSmall"
64 android:id="@+id/vv_start"
65 android:layout_height="wrap_content" />
66 <Button
67 android:layout_width="wrap_content"
68 android:text="暂停"
69 android:id="@+id/vv_pause"
70 style="?android:attr/buttonStyleSmall"
71 android:layout_height="wrap_content" />
72 <Button
73 android:layout_width="wrap_content"
74 android:text="重播"
75 style="?android:attr/buttonStyleSmall"
76 android:id="@+id/vv_restart"
77 android:layout_height="wrap_content" />
78 <Button
79 android:layout_width="wrap_content"
80 android:text="下一个"
81 style="?android:attr/buttonStyleSmall"
82 android:id="@+id/vv_next"
83 android:layout_height="wrap_content" />
84
85 </LinearLayout>
86 </LinearLayout>
87 </FrameLayout>
88
89 <TextView
90 android:layout_width="wrap_content"
91 android:layout_height="wrap_content"
92 android:textSize="15dp"
93 android:text="点击播放"
94 android:textColor="@color/colorWhite"
95 android:id="@+id/vv_text"
96 android:layout_gravity="center" />
97 </FrameLayout>
98 </LinearLayout>
View Code
寻找播放控件标签:
vv_framel=(FrameLayout)findViewById(R.id.vv_framel);
设置视频播放控件点击事件监听:
c
内容补充:
视频播放时间轴时间计算:
如果只知道毫秒数,如何转换为对应的时、分、秒,因为1秒为1000毫秒,1分钟为60秒,1小时为60分,所以如果求秒则需要去掉分钟的值,如果求分钟则需要去掉小时的值。
得到秒:【(t % (60*1000) ) / 1000】