首页 编程设计Android 正文

VideoView详解

云水 Android 2020-10-10 10:15:54 746 0 VideoView

什么是VideoView?

VideoView是Android原生提供的一个封装类,只用以播放视频,视频源可以是本地也可以是网络,支持大部分格式的视频源。

VideoView原理

VideoView继承自SurfaceView,里面封装了一个MediaPlayer用以具体的播放业务,并自带了一个简单的控制界面MediaController。

适用场景

VideoView的功能比较简单,非常适用于那些只单纯地播放视频的场景,如不断循环播放的广告视频。不适用于交互性多的视频播放场景,像调节亮度、调节音量、双击暂停等交互逻辑,VideoView是无法实现的。

1.简单使用步骤

第一步:在布局中添加

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <VideoView
        android:id="@+id/vv_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>1234567891011121314

第二步:设置视频源地址并开始播放

//播放本地视频
 String videoPath= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)+"/dync.mp4";
 //videoPath = "http://vfx.mtime.cn/Video/2019/07/12/mp4/190712140656051701.mp4";
 //设置播放地址,网络视频同样使用此方法,将网址链接放入即可
vvMain.setVideoPath(videoPath);
//开始播放
vvMain.start();1234567

注意:本地视频需要读取存储的权限,网络视频需要网络权限,别忘了添加。

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

简单两步即可实现播放视频,很轻松就能实现视频的播放,这也是VideoView的方便之处。

2.开启视频控制栏

上述VideoView播放视频的方式是没法对其进行任何控制的,如要停止也只能等它播放完毕,VideoView中提供了一个简单的控制栏,具有以下功能。

  • 播放/暂停

  • 查看视频长度与当前位置

  • 进度条拖动

  • 快进15秒

  • 快退5秒

界面如下
在这里插入图片描述
这个控制栏默认是不开启的,如要将之打开,则需要设置MediaController,然后点击视频区域即可弹出此界面。如果视频没有播放或是调用停止方法如stopPlayaback()suspend(),那么此控制栏将不会弹出,调用pause()不影响弹出。

 MediaController mediaController = new MediaController(this);
vvMain.setMediaController(mediaController);12

此处的context一定要传入activity,否则在点击视频区域时程序会崩溃,报如下错误。

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?1

意思是无法将视图添加到window中,因为context不是Activity无法attch Window。

2.1 显示上下首的按钮

如果我想切换到下一个或上一个视频该怎么办,上述界面中并没有这两个按钮啊!难道要自己再添加两个这样的Button,那我还不如自己实现这个控制栏呢。

莫慌,其实MediaController是有这上一首和下一首的按钮的,只不过默认将它隐藏了,只要给他设置个监听方法就可以将之显示出来了。

 mediaController.setPrevNextListeners(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //下一首,实现具体的切换逻辑
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //上一首
            }
        });1234567891011

就算你设置了两个null,也能将之显示出来,只不过点击按钮没有反应罢了。具体要播放哪个视频,就需要自己维护一个播放列表了。

效果如下图。
在这里插入图片描述

2.2 控制栏的显示时间

当点击视频区域控制栏会弹出,过一段时间后会自动隐藏,这个时间是多少呢?
3秒
这是默认时间,由MediaController类控制。

private static final int sDefaultTimeout = 3000;1

这个时间用是无法更改的,除非不用VideoView,而是使用另一种视频播放方式MediaPlayer+SurfaceView+MediaController在点击事件中自己实现显示逻辑。可参考此篇文章!

3.视频的状态获取与控制

VidewView的可调用方法由两部分组成,一是MediaPlayerControl接口规范,二是它自身实现的方法。

3.1 MediaPlayerControl接口提供的方法

方法用途
void start();开始播放视频
void pause();暂停播放视频
int getDuration();获取视频总长度,毫秒值
int getCurrentPosition();获取当前播放位置,毫秒值
void seekTo(int pos);指定播放某个位置
boolean isPlaying();视频是否在播放
int getBufferPercentage();获取缓冲进度,网络视频中使用
boolean canPause();能否暂停
boolean canSeekBackward();能否快退
boolean canSeekForward();能否快进
int getAudioSessionId();获取音频会话ID

3.2 VideoView自身实现的方法

方法用途
void resume();重新播放视频
void stopPlayaback();停止播放视频
void suspend();停止播放
void setOnPreparedListener(MediaPlayer.OnPreparedListener l);视频加载状态的监听
void setOnInfoListener(OnInfoListener l);视频信息的监听,只有播放时才会调用此监听
void setOnCompletionListener(OnCompletionListener l);视频播放完毕的监听
void setOnErrorListener(OnErrorListener l);视频加载或播放异常的监听

4.视频监听器实用技巧

4.1 让视频开始播放的另一种方式

前面说到只需要调用VideoView的start()方法即可完成视频播放的设置,当视频内容加载至内存完成后即会自动开始播放,其实调用VideoView的start方法并不是直接让MediaPlayer开始播放视频,都是需要经过准备阶段这一固定步骤的。

故可在视频的加载监听器中,调用MediaPlayer的start()方法开始视频的播放,效果与VideoView调用start()方法一致。

    vvMain.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });123456

当VideoView调用setVideoPath()方法时就会开始加载视频内容至内存中,调用的是

 mMediaPlayer.prepareAsync();1

所以VideoView的加载过程是一个异步加载。

4.2 实现视频循环播放

一般对于广告视频而言,其必定是不断地循环播放的,而VideoView也可以通过两种方式来达到循环播放的效果。

方式一:通过MediaPlayer方法
mp.setLooping(true);1

此方法可用在OnPreparedListener加载回调和OnInfoListener视频信息回调,但不能用在OnCompletionListener播放完毕的回调中,在播放完毕时再调用此方法并不会让视频循环播放。

还有,设置了视频循环播放后,下一轮的播放不会再触发OnPreparedListenerOnInfoListener,但一样会触发在OnCompletionListener和异常回调。

方式二:在播放完毕的回调中,再次开始播放
 vvMain.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.start();
                //也可调用videoview的start,效果是一样
                //vvMain.start();
                //调用resume方法可使视频重复播放
//                vvMain.resume();
            }
        });12345678910

在这里有三种方式可以实现再次播放

  • MediaPlayer.start()

  • VedioView.start()

  • VedioView.resume()

这三种方式当视频重复播放时都会触发信息回调,与mp.setLooping(true)不太一样。

   vvMain.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                return false;
            }
        });123456

VedioView.resume()方法还会触发加载状态回调OnPreparedListener,所以说resume()方法其实是再一次加载了这个视频内容,然后从头开始播放,与前二种方式是有所区别,前两种方式是再次播放已经加载好的视频,所以不会再触发OnPreparedListener这个回调。

4.3 去掉视频播放异常时的弹框

当视频加载或播放出现异常时,默认是会有一个弹框的,告诉用户播放出现异常,当点击了这个按钮后,会触发播放完毕的回调OnCompletionListener,弹框示意图如下。
在这里插入图片描述
如果想要去掉此异常弹框,那么只需在异常回调中OnErrorListener返回true即可。

   vvMain.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                return true;
            }
        });123456

当取消了异常弹框后,界面不会再有提示,也不会再触发完成回调OnCompletionListener


版权声明

1.本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行测试。
2.本站资源仅供学习和交流使用,版权归资源原作者所有,请在下载后24小时之内自觉删除。
3.若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与本站无关。
4.若内容涉及侵权或违法信息,请联系本站管理员进行下架处理,邮箱ganice520@163.com(本站不支持其他投诉反馈渠道,谢谢合作)

本文链接:http://apod.cc/index.php/post/489.html

发表评论

评论列表(0人评论 , 746人围观)
☹还没有评论,来说两句吧...