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图,更具人性化。

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:orientation="vertical"
android:paddingTop="0dp"
tools:context="com.example.videodong.MainActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="视频播放器:\n"
android:textSize="15dp"
android:id="@+id/textView" />
<FrameLayout
android:layout_width="match_parent"
android:background="@color/colorBlack"
android:layout_height="300dp">
<VideoView
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="300dp"
android:id="@+id/videoView"
/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
android:text="点击播放"
android:textColor="@color/colorWhite"
android:id="@+id/vv_text"
android:layout_gravity="center" />
</FrameLayout> <ProgressBar
android:id="@+id/vv_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/> <TextView
android:layout_width="wrap_content"
android:text="时间轴为:0.00/000"
android:id="@+id/vv_starttime"
android:layout_height="wrap_content" /> <LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_gravity="center"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="开始"
android:id="@+id/vv_start"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="暂停"
android:id="@+id/vv_pause"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="重播"
android:id="@+id/vv_restart"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="下一个"
android:id="@+id/vv_next"
android:layout_height="wrap_content" /> </LinearLayout>
<TextView
android:layout_width="wrap_content"
android:id="@+id/vv_state"
android:layout_height="wrap_content" />
</LinearLayout>

需要添加的权限:

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

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

寻找到VideoView控件:

vv=(VideoView)findViewById(R.id.videoView);

视频预装完成监听:

 //视频准备完成时进入
vv.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//设置屏幕提示信息为空
vv_text.setText("");
}
});

视频播放完成监听:

 vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
String strres="播放完成";
//判断视频的总长度与当前长度是否在误差区间内
if(Math.abs(vv.getDuration()-vv.getCurrentPosition())>1000){ strres="播放错误,可能无网络连接"; }
//设置屏幕提示信息
vv_text.setText(strres); }
});

视频播放错误监听:

 vv.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
//设置屏幕显示信息
vv_text.setText("视频未知错误"); return false;
}
});

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

 vv.setOnInfoListener(new MediaPlayer.OnInfoListener(){
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra){ switch(what){
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
//设置屏幕显示信息,开始卡顿
vv_text.setText("视频卡顿,加载中.....");
break ;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
//设置屏幕显示信息,卡顿结束
vv_text.setText("");
break ;
}
return true;
}
}) ;

设置播放资源:

 //本地文件
vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4"); //URL形式,支持本地URL和网络URL
//vv.setVideoURI(Uri.parse("https://www.bilibili.com/video/xxxxx")); //设置自带的播放控件
//vv.setMediaController(new MediaController(this));

播放开始按钮监听:

 //开始播放视频按钮
vv_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //设置屏幕显示信息
vv_text.setText(""); //开始播放
vv.start(); }
});

播放暂停按钮监听:

 //暂停播放视频按钮
vv_pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //设置屏幕显示信息
vv_text.setText("视频暂停中"); //暂停视频播放
vv.pause(); }
});

重新播放按钮监听:

 //重新播放视频
vv_restart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置屏幕显示信息
vv_text.setText("正在重新播放中,请稍等"); //设置时间轴显示为0
vv_starttime.setText("时间轴为:0.00/0.00"); //设置进度条显示为0
vv_bar.setProgress(0); //重新播放视频
vv.resume();
vv.start(); }
});

播放下一个视频监听:

 vv_next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置屏幕显示信息
vv_text.setText("正在切换,请稍等"); //设置时间轴为0
vv_starttime.setText("时间轴为:0.00/0.00"); //设置进度条为0
vv_bar.setProgress(0); //停止播放
vv.pause();//暂停
vv.stopPlayback();//停止播放并释放资源 //得到下一个视频的资源
if(nextbool){
nextbool=false;
//网络资源,该url已经过期
vv.setVideoURI(Uri.parse("http://193.112.87.88/video/xx.flv"));
} else {
nextbool=true;
//本地资源
vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
} //开始播放下一个
vv.start(); }
});

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

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

 new Thread(new Runnable() {
@Override
public void run() {
while (true){
//延时1秒
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} //进入主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
if(vv.isPlaying()) { //获取到视频播放进度
int maxx=vv.getDuration();
int progress=vv.getCurrentPosition(); //设置进度条信息
vv_bar.setMax(maxx);
vv_bar.setProgress(progress); //得到时间轴字符串
String strtime=String.format("时间轴为:%02d:%02d/%02d:%02d", (progress % 3600000) / 60000,(progress % 60000 ) / 1000, (maxx % 3600000) / 60000,(maxx % 60000 ) / 1000);
//显示时间轴信息
vv_starttime.setText(strtime); }
}
});
} }
}).start();

视频播放进阶

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

                                       

 布局文件改变:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:orientation="vertical"
android:paddingTop="0dp"
tools:context="com.example.videodong.MainActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="视频播放器:\n"
android:textSize="15dp"
android:id="@+id/textView" />
<FrameLayout
android:layout_width="match_parent"
android:background="@color/colorBlack"
android:layout_height="230dp">
<VideoView
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="230dp"
android:id="@+id/videoView"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:id="@+id/vv_framel"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:background="@color/colorWhite"
android:alpha="0.5"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical" android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/vv_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_gravity="center"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:text="时间轴为:0.00/000"
android:id="@+id/vv_starttime"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="开始"
style="?android:attr/buttonStyleSmall"
android:id="@+id/vv_start"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="暂停"
android:id="@+id/vv_pause"
style="?android:attr/buttonStyleSmall"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="重播"
style="?android:attr/buttonStyleSmall"
android:id="@+id/vv_restart"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:text="下一个"
style="?android:attr/buttonStyleSmall"
android:id="@+id/vv_next"
android:layout_height="wrap_content" /> </LinearLayout>
</LinearLayout>
</FrameLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
android:text="点击播放"
android:textColor="@color/colorWhite"
android:id="@+id/vv_text"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>

寻找播放控件标签:

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

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

 vv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//判断是否是显示
if(vv_framel.getVisibility()==View.VISIBLE) //隐藏视频播放控件
vv_framel.setVisibility(View.INVISIBLE); else //显示视频播放控件
vv_framel.setVisibility(View.VISIBLE); }
});

内容补充:

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

如果只知道毫秒数,如何转换为对应的时、分、秒,因为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

安卓视频播放器(VideoView)的更多相关文章

  1. Android 视频播放器 VideoView 的使用,播放本地视频 和 网络 视频

    1.布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:and ...

  2. android视频播放器开发

    http://blog.csdn.net/u010181592/article/details/49301703 http://blog.csdn.net/qq_33291295/article/de ...

  3. 安卓TV开发(四) 实现主流智能TV视频播放器UI

    前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...

  4. Android 视频播放器 (一):使用VideoView播放视频

    一.简介 作为Android开发,我们不可避免的会接触到视频播放,VideoView做为最简单的播放器,我们是不应该不会的. 下面简单介绍一下VideoView: VideoView是使用MediaP ...

  5. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  6. 开源安卓Android流媒体音视频播放器实现声音自动停止、恢复、一键静音功能源码

    本文转自EasyDarwin团队John的博客:http://blog.csdn.net/jyt0551/article/details/60802145 我们在开发安卓Android流媒体音视频播放 ...

  7. android视频播放器

    RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetworks公司提交的 ...

  8. 建站技能get(1)— Asp.net MVC快速集成ckplayer网页视频播放器

    故事背景大概是这样的,我厂两年前给山西晋城人民政府做了一个门户网站(地址:http://jccq.cn/),运行了一年多固若金汤,duang的有一天市场部门过来说,新闻管理模块带视频的内容播放不了了. ...

  9. C语言基于GTK+Libvlc实现的简易视频播放器

    小编心语:现下,各种视频播放软件层出不穷,竞争也越演越烈,不知道大家有木有这个想法,小编有时在想能不能做一款属于自己的视频播放器呢~小编特意去实验楼,整理出了这篇关于如何实现简易视频播放器的博文.简易 ...

随机推荐

  1. AX2009 批处理作业中使用多线程---独立任务模式

    每个工单独立一个任务. Class /* 独立任务模式 */ class DemoBatchIndividualTasks extends RunBaseBatch { str 20 SalesOrd ...

  2. 使用nginx反向代理实现隐藏端口号

    使用nginx反向代理实现隐藏端口号 在服务器上下载安装nginx,主要是修改配置nginx.conf. 用proxy_pass里面配置要转发的域名+端口,相当于这一部分是被域名替换的部分,在http ...

  3. Spring 缓存注解之@Cacheable,@CacheEvit

    Spring引入了Cache的支持,其使用方法类似于Spring对事务的支持.Spring Cache是作用于方法上的,其核心思想是,当我们调用一个缓存方法时,把该方法参数和返回结果作为一个键值对存放 ...

  4. U3D一些使用

    1,UGUI Button同时监听点击事件和长按事件:https://blog.csdn.net/yye4520/article/details/80844870

  5. STL之vector容器详解

    vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...

  6. UE4行为树

    这是 UE4中行为树编辑器 中可用的默认节点.取决于开发项目的不同(如射击游戏),可能会有更多节点.这里介绍五种行为树节点类型:   节点类型 描述 Composite(流程控制节点) 这种节点定义一 ...

  7. ASP.NET代码调用SQL Server带DateTime类型参数的存储过程抛出异常问题

    ASP.NET代码调用SQL Server带DateTime类型参数的存储过程,如果DateTime类型参数的值是'0001/1/1 0:00:00'时,就会抛出异常“Message: SqlDate ...

  8. html图片上传阅览并且点击放大

                  关闭   qq_31540195的博客       目录视图 摘要视图 订阅 异步赠书:9月重磅新书升级,本本经典           程序员9月书讯      每周荐书: ...

  9. android-audioRecord

    android 录音功能 录音的大致流程,流程图可以在文件下载:mediarecord.vsdx 切换设备.谁去更新播放流,自动选择新的设备?流程?

  10. css3等待框

    第1种效果: <div class="loading"> <span></span> <span></span> < ...