安卓视频播放器VideoView

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 6     android:paddingBottom="0dp"
 7     android:paddingLeft 8     android:paddingRight 9     android:orientation="vertical"
10     android:paddingTop11     tools:context="com.example.videodong.MainActivity">
12 
13     TextView
14         android:layout_width="wrap_content"
15         android:layout_height16         android:text="视频播放器:\n"
17         android:textSize="15dp"
18         android:id="@+id/textView" />
19     FrameLayout
20         21         android:background="@color/colorBlack"
22 ="300dp"23        VideoView
24         25         android:layout_gravity="center"
26 ="300dp"
27 ="@+id/videoView"
28         29 
30         31             32             android:layout_height33             android:textSize34             android:text="点击播放"
35             android:textColor="@color/colorWhite"
36             android:id="@+id/vv_text"
37             android:layout_gravity="center" 38     </FrameLayout39 
40     ProgressBar
41         android:id="@+id/vv_bar"
42         style="?android:attr/progressBarStyleHorizontal"
43         android:layout_width44 ="wrap_content"45 
46         47             48 ="时间轴为:0.00/000"
49 ="@+id/vv_starttime"
50 ="wrap_content" 51 
52 
53      LinearLayout
54          55          android:orientation="horizontal"
56          android:layout_gravity57          android:layout_height58          59              60              android:layout_weight="1"
61              android:layout_height62          Button
63              64              android:text="开始"
65              android:id="@+id/vv_start"
66 67          68              69 ="暂停"
70 ="@+id/vv_pause"
71 72          73              74 ="重播"
75 ="@+id/vv_restart"
76 77          78              79 ="下一个"
80 ="@+id/vv_next"
81 82          
83      LinearLayout84     85         86 ="@+id/vv_state"
87 88 >
View Code

需要添加的权限:

因为视频来源可以是网络或者本地,所以需要动态申请网络访问权限和本地文件读写权限,文件读写权限一般还需要手动获取

uses-permission android:name="android.permission.INTERNET" ="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( MediaPlayer.OnCompletionListener() {
 3              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( MediaPlayer.OnErrorListener() {
boolean onError(MediaPlayer mp,int what,1)">int extra) 
 4            {
 5                设置屏幕显示信息
 6                 vv_text.setText("视频未知错误" 8                 return false 9 10  });

视频卡顿和停止卡顿监听:

 1 vv.setOnInfoListener( MediaPlayer.OnInfoListener(){
boolean onInfo(MediaPlayer mp,1)"> extra){
 4 
switch(what){
 6                     case MediaPlayer.MEDIA_INFO_BUFFERING_START:
 7                         设置屏幕显示信息,开始卡顿
 8                         vv_text.setText("视频卡顿,加载中....." 9                         break ;
10                      MediaPlayer.MEDIA_INFO_BUFFERING_END:
11                         设置屏幕显示信息,卡顿结束
12                         vv_text.setText(""13                         15              true16 17 }) ;

设置播放资源:

本地文件
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        
设置自带的播放控件
8 vv.setMediaController(new MediaController(this));

播放开始按钮监听:

开始播放视频按钮
 2 vv_start.setOnClickListener( View.OnClickListener() {
 3  4              onClick(View v) {
 5                 
//设置屏幕显示信息
 7                 vv_text.setText("" 8 
 9                 开始播放
                vv.start();
11 
13 });

播放暂停按钮监听:

暂停播放视频按钮
 2 vv_pause.setOnClickListener( 5 
 7                 vv_text.setText("视频暂停中"暂停视频播放
                vv.pause();
13 });

重新播放按钮监听:

重新播放视频
 2 vv_restart.setOnClickListener( 6                 vv_text.setText("正在重新播放中,请稍等"设置时间轴显示为0
 9                 vv_starttime.setText("时间轴为:0.00/0.00"10 
11                 设置进度条显示为0
12                 vv_bar.setProgress(013                 
14                 15                 vv.resume();
17 
18 19 });

播放下一个视频监听:

 1 vv_next.setOnClickListener( 4                  5                 vv_text.setText("正在切换,请稍等" 6 
 7                 设置时间轴为0
 8                 vv_starttime.setText("时间轴为:0.00/0.00"10                 设置进度条为0
11                 vv_bar.setProgress(012                 
13                 停止播放
14                 vv.pause();暂停
15                 vv.stopPlayback();停止播放并释放资源
16 
17                 得到下一个视频的资源
18                 if(nextbool){
19                     nextbool=20                     网络资源,该url已经过期
21                     vv.setVideoURI(Uri.parse("http://193.112.87.88/video/xx.flv"));
22                 } else {
23                     nextbool=24                     本地资源
25                     vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4"26 27 
28                 开始播放下一个
29 30 
31 32 });

时间轴时间显示和进度条更新实现:

时间轴时间显示计算将在后文给出解释,另外 %02d 可以实现自动补零效果,runOnUiThread可以在普通线程中进入UI线程,可以实现UI的一系列操作。

new Thread( Runnable() {
 run() {
while ( 5                     延时1秒
try 7                         Thread.sleep(1 8                     } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
12                     进入主线程更新UI
13                     runOnUiThread(                        @Override
15                         16                             (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 ) / 100028                                 显示时间轴信息
                                vv_starttime.setText(strtime);
                            }
32                         }
33                     });
34 35 
36 37  }).start();
View Code

 

视频播放进阶

利用FrameLayout的层叠效果,实现视频控件面板在视频层之上显示,利用视频控件的点击事件,实现视频点击监听然后改变视频控制面板的隐藏和显示。其他的视频播放控制代码基本以上相似

                          

                                       

            

 布局文件改变:

="230dp"="230dp"
29         30             31 ="bottom"
="@+id/vv_framel"
34             ImageView
35                                 android:background                android:alpha="0.5"
38                 android:layout_height="match_parent" 39         40             41             android:orientation42 
44             45                 46                 style47                 android:layout_width49             50                 51                 android:orientation52                 android:layout_gravity53 54                 55                                         android:text                    android:id58                     android:layout_weight59                     android:layout_height60                 61                     62 63                     style="?android:attr/buttonStyleSmall"
66                 67                     68 72                 73                     77 78                 79                     82 83 84 
85             86         87         88 
89         90             91 92 93 94 95 96 97     98 >
View Code

寻找播放控件标签:

vv_framel=(FrameLayout)findViewById(R.id.vv_framel);

设置视频播放控件点击事件监听: 

 1 vv.setOnClickListener(    @Override
 3      4         判断是否是显示
 5         if(vv_framel.getVisibility()==View.VISIBLE)
 7             隐藏视频播放控件
 8             vv_framel.setVisibility(View.INVISIBLE);
10         else
12             显示视频播放控件
13             vv_framel.setVisibility(View.VISIBLE);
14 
    }
16 });

 

内容补充:

视频播放时间轴时间计算:

如果只知道毫秒数,如何转换为对应的时、分、秒,因为1秒为1000毫秒,1分钟为60秒,1小时为60分,所以如果求秒则需要去掉分钟的值,如果求分钟则需要去掉小时的值。

得到秒:【(t % (60*1000) ) / 1000】

得到分:【(t % (60*60*1000)) / (60*1000)】

得到时:【(t / (60*60*1000))】

 

源码资源下载:点我下载

 

 参考:

https://www.jianshu.com/p/0c3ef72c20d1?from=timeline&isappinstalled=0

https://www.cnblogs.com/tangs/articles/5463347.html

https://blog.csdn.net/qq_30983519/article/details/54407122

https://blog.csdn.net/qq_29272491/article/details/80475788

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题,导致无法更新,出现该问题的原因是由于3.0版本与较早的sdk版本之间文件结构有冲突,解决
Android 如何解决dialog弹出时无法捕捉Activity的back事件 在一些情况下,我们需要捕捉back键事件,然后在捕捉到的事件里写入我们需要进行的处理,通常可以采用下面三种办法捕捉到back事件: 1)重写onKeyDown或者onKeyUp方法 2)重写onBackPressed方
Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法。一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现,这种方式代码量最小。在Button的属性中有一个是drawable
Android中的&quot;Unable to start activity ComponentInfo&quot;的错误 最近在做一款音乐播放器的时候,然后在调试的过程中发现一直报这个错误&quot;Unable to start activity ComponentInfo&quot;,从字面
Android 关于长按back键退出应用程序的实现最近在做一个Android上的应用,碰到一个问题就是如何实现长按back键退出应用程序。在网上查找了很多资料,发现几乎没有这样的实现,大部分在处理时是双击back键来退出应用程序。参考了一下双击back键退出应用程序的代码,网上主流的一种方法是下面
android自带的时间选择器只能精确到分,但是对于某些应用要求选择的时间精确到秒级,此时只有自定义去实现这样的时间选择器了。下面介绍一个可以精确到秒级的时间选择器。 先上效果图: 下面是工程目录: 这个控件我也是用的别人的,好像是一个老外写的,com.wheel中的WheelView是滑动控件的主
Android平台下利用zxing实现二维码开发 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing
Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的item默认的外观,下面讲解以下在使用listview时最常见的几个问题。1.如何改变item的背景色和按
如何向Android模拟器中导入含有中文名称的文件在进行Android开发的时候,如果需要向Android模拟器中导入文件进行测试,通过DDMS下手动导入或者在命令行下通过adb push命令是无法导入含有中文文件名的文件的。后来发现借用其他工具可以向模拟器中导入中文名称的文件,这个工具就是Ultr
Windows 下搭建Android开发环境一.下载并安装JDK版本要求JDK1.6+,下载JDK成功后进行安装,安装好后进行环境变量的配置【我的电脑】-——&gt;【属性】——&gt;【高级】 ——&gt;【环境变量】——&gt;【系统变量】中点击【新建】:变量名:CLASSPATH变量值:……
如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题 在android中有时候可能要实现一个底部弹出菜单,此时可以考虑用PopupWindow来实现。下面就来介绍一下如何使用PopupWindow实现一个弹出窗。 主Activity代码:public void onCreat
解决Android中的ERROR: the user data image is used by another emulator. aborting的方法 今天调试代码的时候,突然出现这个错误,折腾了很久没有解决。最后在google上找到了大家给出的两种解决方案,下面给出这两种方法的链接博客:ht
AdvserView.java package com.earen.viewflipper; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory;
ImageView的scaleType的属性有好几种,分别是matrix(默认)、center、centerCrop、centerInside、fitCenter、fitEnd、fitStart、fitXY。 |值|说明| |:--:|:--| |center|保持原图的大小,显示在ImageVie
文章浏览阅读8.8k次,点赞9次,收藏20次。本文操作环境:win10/Android studio 3.21.环境配置 在SDK Tools里选择 CMAKE/LLDB/NDK点击OK 安装这些插件. 2.创建CMakeLists.txt文件 在Project 目录下,右键app,点击新建File文件,命名为CMakeLists.txt点击OK,创建完毕! 3.配置文件 在CMa..._link c++ project with gradle
文章浏览阅读1.2w次,点赞15次,收藏69次。实现目的:由mainActivity界面跳转到otherActivity界面1.写好两个layout文件,activity_main.xml和otherxml.xmlactivity_main.xml&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;RelativeLayout ="http://schemas..._android studio 界面跳转
文章浏览阅读3.8w次。前言:最近在找Android上的全局代理软件来用,然后发现了这两款神作,都是外国的软件,而且都是开源的软件,因此把源码下载了下来,给有需要研究代理这方面的童鞋看看。不得不说,国外的开源精神十分浓,大家相互使用当前基础的开源软件,然后组合成一个更大更强的大开源软件。好吧,废话不多说,下面简单介绍一下这两款开源项目。一、ProxyDroid:ProxyDroid功能比较强大,用到的技术也比较多,源码也_proxydroid
文章浏览阅读2.5w次,点赞17次,收藏6次。创建项目后,运行项目时Gradle Build 窗口却显示错误:程序包R不存在通常情况下是不会出现这个错误的。我是怎么遇到这个错误的呢?第一次创建项目,company Domain我使用的是:aven.com,但是创建过程在卡在了Building 'Calculator' Gradle Project info这个过程中,于是我选择了“Cancel”第二次创建项目,我还是使用相同的项目名称和项目路_r不存在
文章浏览阅读8.9w次,点赞4次,收藏43次。前言:在Android上使用系统自带的代理,限制灰常大,仅支持系统自带的浏览器。这样像QQ、飞信、微博等这些单独的App都不能使用系统的代理。如何让所有软件都能正常代理呢?ProxyDroid这个软件能帮你解决!使用方法及步骤如下:一、推荐从Google Play下载ProxyDroid,目前最新版本是v2.6.6。二、对ProxyDroid进行配置(基本配置:) (1) Auto S_proxydroid使用教程
文章浏览阅读1.1w次,点赞4次,收藏17次。Android Studio提供了一个很实用的工具Android设备监视器(Android device monitor),该监视器中最常用的一个工具就是DDMS(Dalvik Debug Monitor Service),是 Android 开发环境中的Dalvik虚拟机调试监控服务。可以进行的操作有:为测试设备截屏,查看特定进程中正在运行的线程以及堆栈信息、Logcat、广播状态信息、模拟电话_安卓摄像头调试工具