react-native-video实现视频全屏播放的方法


Posted in Javascript onMarch 19, 2018

react-native-video 是github上一个专用于React Native做视频播放的组件。这个组件是React Native上功能最全最好用的视频播放组件,还在持续开发之中,虽然还有些bug,但基本不影响使用,强力推荐。

本篇文章主要介绍下怎么使用react-native-video播放视频,以及如何实现全屏播放,屏幕旋转时视频播放器大小随之调整,显示全屏或收起全屏。

首先来看看react-native-video有哪些功能。

基本功能

  1. 控制播放速率
  2. 控制音量大小
  3. 支持静音功能
  4. 支持播放和暂停
  5. 支持后台音频播放
  6. 支持定制样式,比如设置宽高
  7. 丰富的事件调用,如onLoad,onEnd,onProgress,onBuffer等等,可以通过对应的事件进行UI上的定制处理,如onBuffer时我们可以显示一个进度条提示用户视频正在缓冲。
  8. 支持全屏播放,使用presentFullscreenPlayer方法。这个方法在iOS上可行,在android上不起作用。参看 issue#534 ,#726也是同样的问题。
  9. 支持跳转进度,使用seek方法跳转到指定的地方进行播放
  10. 可以加载远程视频地址进行播放,也可以加载RN本地存放的视频。

注意事项

react-native-video通过source属性设置视频,播放远程视频时使用uri来设置视频地址,如下:

source={{uri: http://www.xxx.com/xxx/xxx/xxx.mp4}}

播放本地视频时,使用方式如下:

source={require('../assets/video/turntable.mp4')}

需要注意的是,source属性不能为空,uri或本地资源是必须要设置的,否则会导致app闪退。uri不能设置为空字符串,必须是一个具体的地址。

安装配置

使用 npm i -S react-native-video 或 yarn add react-native-video 安装,完成之后使用 react-native link react-native-video 命令link这个库。

Android端在执行完link命令后,gradle中就已经完成了配置。iOS端还需要手动配置一下,这里简单说一下,与官方说明不同的是,我们一般不使用tvOS的,选中你自己的target,在build phases中先移除掉自动link进来的 libRCTVideo.a 这个库,然后点击下方加号重新添加 libRCTVideo.a ,注意不要选错。

react-native-video实现视频全屏播放的方法

视频播放

实现视频播放其实很简单,我们只需要给Video组件设置一下source资源,然后设置style调整Video组件宽高就行了。

<Video
 ref={(ref) => this.videoPlayer = ref}
 source={{uri: this.state.videoUrl}}
 rate={1.0}
 volume={1.0}
 muted={false}
 resizeMode={'cover'}
 playWhenInactive={false}
 playInBackground={false}
 ignoreSilentSwitch={'ignore'}
 progressUpdateInterval={250.0}
 style={{width: this.state.videoWidth, height: this.state.videoHeight}}
/>

其中videoUrl是我们用来设置视频地址的变量,videoWidth和videoHeight是用来控制视频宽高的。

全屏播放的实现

视频全屏播放其实就是在横屏情况下全屏播放,竖屏一般都是非全屏的。要实现设备横屏时视频全屏显示,说起来很简单,就是通过改变Video组件宽高来实现。

上面我们把videoWidth和videoHeight存放在state中,目的就是为了通过改变两个变量的值来刷新UI,使视频宽高能随之改变。问题是,怎样在设备的屏幕旋转时及时获取到改变后的宽高呢?

竖屏时我设置的视频初始宽度为设备屏幕的宽度,高度为宽度的9/16,即按16:9的比例显示。横屏时视频的宽度应为屏幕的宽度,高度应为当前屏幕的高度。由于横屏时设备宽高发生了变化,及时获取到宽高就能及时刷新UI,视频就能全屏展示了。

刚开始我想到的办法是使用 react-native-orientation 监听设备转屏的事件,在回调方法中判断当前是横屏还是竖屏,这个在iOS上是可行的,但是在Android上横屏和竖屏时获取到宽高值总是不匹配的(比如,横屏宽384高582,竖屏宽582高384,显然不合理),这样就无法做到统一处理。

所以,监听转屏的方案是不行的,不仅费时还得不到想要的结果。更好的方案是在render函数中使用View作为最底层容器,给它设置一个"flex:1"的样式,使其充满屏幕,在View的onLayout方法中获取它的宽高。无论屏幕怎么旋转,onLayout都可以获取到当前View的宽高和x、y坐标。

/// 屏幕旋转时宽高会发生变化,可以在onLayout的方法中做处理,比监听屏幕旋转更加及时获取宽高变化
 _onLayout = (event) => {
 //获取根View的宽高
 let {width, height} = event.nativeEvent.layout;
 console.log('通过onLayout得到的宽度:' + width);
 console.log('通过onLayout得到的高度:' + height);
 
 // 一般设备横屏下都是宽大于高,这里可以用这个来判断横竖屏
 let isLandscape = (width > height);
 if (isLandscape){
  this.setState({
  videoWidth: width,
  videoHeight: height,
  isFullScreen: true,
  })
 } else {
  this.setState({
  videoWidth: width,
  videoHeight: width * 9/16,
  isFullScreen: false,
  })
 }
 };

这样就实现了屏幕在旋转时视频也随之改变大小,横屏时全屏播放,竖屏回归正常播放。注意,Android和iOS需要配置转屏功能才能使界面自动旋转,请自行查阅相关配置方法。

播放控制

上面实现了全屏播放还不够,我们还需要一个工具栏来控制视频的播放,比如显示进度,播放暂停和全屏按钮。具体思路如下:

  1. 使用一个View将Video组件包裹起来,View的宽高和Video一致,便于转屏时改变大小
  2. 设置一个透明的遮罩层覆盖在Video组件上,点击遮罩层显示或隐藏工具栏
  3. 工具栏中要显示播放按钮、进度条、全屏按钮、当前播放时间、视频总时长。工具栏以绝对位置布局,覆盖在Video组件底部
  4. 使用react-native-orientation中的lockToPortrait和lockToLandscape方法强制旋转屏幕,使用unlockAllOrientations在屏幕旋转以后撤销转屏限制。

这样才算是一个有模有样的视频播放器。下面是竖屏和横屏的效果图

react-native-video实现视频全屏播放的方法

react-native-video实现视频全屏播放的方法

再也不必为presentFullscreenPlayer方法不起作用而烦恼了,全屏播放实现起来其实很简单。具体代码请看demo: https://github.com/mrarronz/react-native-blog-examples/tree/master/Chapter7-VideoPlayer/VideoExample 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
编写自己的jQuery插件简单实现代码
Apr 19 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
Oct 11 Javascript
node.js中的fs.read方法使用说明
Dec 17 Javascript
javascript面向对象之对象的深入理解
Jan 13 Javascript
ECMAScript6中Set/WeakSet详解
Jun 12 Javascript
jQuery Easyui datagrid/treegrid 清空数据
Jul 09 Javascript
JavaScript DOM节点操作方法总结
Aug 23 Javascript
jQuery中Find选择器用法示例
Sep 21 Javascript
jquery实现input框获取焦点的方法
Feb 06 Javascript
深入理解react-router 路由的实现原理
Sep 26 Javascript
vue指令做滚动加载和监听等
May 26 Javascript
Nuxt页面级缓存的实现
Mar 09 Javascript
vue实现树形菜单效果
Mar 19 #Javascript
VUE重点问题总结
Mar 19 #Javascript
p5.js入门教程之键盘交互
Mar 19 #Javascript
vue 实现的树形菜的实例代码
Mar 19 #Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
Mar 18 #Javascript
jQuery替换节点元素的操作方法
Mar 18 #jQuery
使用Angular CLI生成 Angular 5项目教程详解
Mar 18 #Javascript
You might like
防止MySQL注入或HTML表单滥用的PHP程序
2009/01/21 PHP
php allow_url_include的应用和解释
2010/04/22 PHP
PHP计算2点经纬度之间的距离代码
2013/08/12 PHP
PHP构造函数与析构函数用法示例
2016/09/28 PHP
PHP实现 APP端微信支付功能
2018/06/22 PHP
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
基于Unit PNG Fix.js有时候在ie6下不正常的解决办法
2013/06/26 Javascript
JS中数组重排序方法
2016/11/11 Javascript
浅谈Node.js:fs文件系统模块
2016/12/08 Javascript
利用JavaScript对中文(汉字)进行排序实例详解
2017/06/18 Javascript
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
2019/01/09 jQuery
javascriptvoid(0)含义以及与&quot;#&quot;的区别讲解
2019/01/19 Javascript
vue.js实现图书管理功能
2019/09/24 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
解决vue bus.$emit触发第一次$on监听不到问题
2020/07/28 Javascript
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
Python入门_浅谈数据结构的4种基本类型
2017/05/16 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
使用PyOpenGL绘制三维坐标系实例
2019/12/24 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
Pytorch 使用不同版本的cuda的方法步骤
2020/04/02 Python
浅谈numpy中np.array()与np.asarray的区别以及.tolist
2020/06/03 Python
python openCV实现摄像头获取人脸图片
2020/08/20 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
python 两种方法删除空文件夹
2020/09/29 Python
eDreams澳大利亚:预订机票、酒店和度假产品
2017/04/19 全球购物
用缩写的指针比较"if(p)" 检查空指针是否可靠?如果空指针的内部表达不是0会怎么样?
2014/01/05 面试题
将"引用"作为函数返回值类型的格式、好处和需要遵守的规则
2016/02/09 面试题
2014学雷锋活动总结
2014/03/09 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
大学生自我推荐信范文
2015/03/24 职场文书
迎国庆主题班会
2015/08/17 职场文书
python编程项目中线上问题排查与解决
2021/11/01 Python
Vue的列表之渲染,排序,过滤详解
2022/02/24 Vue.js