ReactNative——react-native-video实现视频全屏播放

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

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

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

基本功能

  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来设置视频地址,以下:github

source={{uri: "http://www.xxx.com/xxx/xxx/xxx.mp4"}}
复制代码

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

source={require('../assets/video/turntable.mp4')}
复制代码

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

安装配置

使用npm i -S react-native-videoyarn add react-native-video安装,完成以后使用react-native link react-native-video命令link这个库。bash

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

视频播放

实现视频播放其实很简单,咱们只须要给Video组件设置一下source资源,而后设置style调整Video组件宽高就好了。ide

<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在屏幕旋转之后撤销转屏限制。

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

不再必为presentFullscreenPlayer方法不起做用而烦恼了,全屏播放实现起来其实很简单。具体代码请看demo:github.com/mrarronz/re…

总结

  1. react-native-orientation和react-native-video都还有缺陷,可是已经能够运用到项目中了
  2. 有时候解决问题要换种思路,不能一棵树上吊死。坐下来喝杯茶,换种心态、换个搜索关键词说不定就获得了你想要的答案。
相关文章
相关标签/搜索