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. vue项目获取地址栏参数(非路由传参)

    在项目中,遇到一个需求,就是另一个系统直接跳转到我们项目中的某个页面,不需要做用户的校验直接单纯的跳转新页面,再初始化查询数据,参数以地址栏的形式传入 由于原来项目做过权限控制,所以在路由那边需要进行 ...

  2. mr统计每年中每月温度的前三名

    weatherMapper package com.laoxiao.mr.weather; import java.text.ParseException; import java.text.Simp ...

  3. 安卓学习第一节--环境搭建及Android Studio 安装

    1.安装JDK 2.安装AS 安装参考网址 https://www.cnblogs.com/xiadewang/p/7820377.html 下载网址: http://www.android-stud ...

  4. Mysql中存储引擎区别【 InnoDB、MyISAM】

    区别: 1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事 ...

  5. csu1804

    /* csu 1804 因为define和const总出错,到现在也不明白为什么 不知道define 和 const 出来的 mod 有什么区别 */ #include<iostream> ...

  6. Difference between Load / Stress / Performance Testing

    Load and stress testing are subsets of performance testing. Performance testing means how best somet ...

  7. 20155312 张竞予 Exp9 Web安全基础

    Exp9 Web安全基础 目录 基础问题回答 (1)SQL注入攻击原理,如何防御 (2)XSS攻击的原理,如何防御 (3)CSRF攻击原理,如何防御 实践过程记录 WebGoat准备工作 1.XSS攻 ...

  8. Web表现层

    目录 Web表现层调用过程... 2 延迟... 3 什么是延迟... 3 延迟的构成... 3 最基本的优化思路:... 4 Web表现层性能优化... 4 Web性能的基本指标... 4 Web性 ...

  9. Fiddler-设置取消自动更新

    fiddler 启动时老弹出要更新,但不想更新,可以这样设置 Tools-Optons->General 把第一个√去掉

  10. 实现ueditor的自动上传word中的……

    UEditor的配置和使用(单独图片与文件上传) Word图片上传控件发布-Xproer.WordPaster ueditor 图片粘贴上传,实现图文粘贴,图片自动上传 打开工程: 文档的上传. 运行 ...