react-native-video實(shí)現(xiàn)視頻全屏播放的方法
react-native-video 是github上一個(gè)專用于React Native做視頻播放的組件。這個(gè)組件是React Native上功能最全最好用的視頻播放組件,還在持續(xù)開發(fā)之中,雖然還有些bug,但基本不影響使用,強(qiáng)力推薦。
本篇文章主要介紹下怎么使用react-native-video播放視頻,以及如何實(shí)現(xiàn)全屏播放,屏幕旋轉(zhuǎn)時(shí)視頻播放器大小隨之調(diào)整,顯示全屏或收起全屏。
首先來看看react-native-video有哪些功能。
基本功能
- 控制播放速率
- 控制音量大小
- 支持靜音功能
- 支持播放和暫停
- 支持后臺(tái)音頻播放
- 支持定制樣式,比如設(shè)置寬高
- 豐富的事件調(diào)用,如onLoad,onEnd,onProgress,onBuffer等等,可以通過對(duì)應(yīng)的事件進(jìn)行UI上的定制處理,如onBuffer時(shí)我們可以顯示一個(gè)進(jìn)度條提示用戶視頻正在緩沖。
- 支持全屏播放,使用presentFullscreenPlayer方法。這個(gè)方法在iOS上可行,在android上不起作用。參看 issue#534 ,#726也是同樣的問題。
- 支持跳轉(zhuǎn)進(jìn)度,使用seek方法跳轉(zhuǎn)到指定的地方進(jìn)行播放
- 可以加載遠(yuǎn)程視頻地址進(jìn)行播放,也可以加載RN本地存放的視頻。
注意事項(xiàng)
react-native-video通過source屬性設(shè)置視頻,播放遠(yuǎn)程視頻時(shí)使用uri來設(shè)置視頻地址,如下:
source={{uri: http://www.xxx.com/xxx/xxx/xxx.mp4}}
播放本地視頻時(shí),使用方式如下:
source={require('../assets/video/turntable.mp4')}
需要注意的是,source屬性不能為空,uri或本地資源是必須要設(shè)置的,否則會(huì)導(dǎo)致app閃退。uri不能設(shè)置為空字符串,必須是一個(gè)具體的地址。
安裝配置
使用 npm i -S react-native-video 或 yarn add react-native-video 安裝,完成之后使用 react-native link react-native-video 命令link這個(gè)庫。
Android端在執(zhí)行完link命令后,gradle中就已經(jīng)完成了配置。iOS端還需要手動(dòng)配置一下,這里簡單說一下,與官方說明不同的是,我們一般不使用tvOS的,選中你自己的target,在build phases中先移除掉自動(dòng)link進(jìn)來的 libRCTVideo.a 這個(gè)庫,然后點(diǎn)擊下方加號(hào)重新添加 libRCTVideo.a ,注意不要選錯(cuò)。

視頻播放
實(shí)現(xiàn)視頻播放其實(shí)很簡單,我們只需要給Video組件設(shè)置一下source資源,然后設(shè)置style調(diào)整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是我們用來設(shè)置視頻地址的變量,videoWidth和videoHeight是用來控制視頻寬高的。
全屏播放的實(shí)現(xiàn)
視頻全屏播放其實(shí)就是在橫屏情況下全屏播放,豎屏一般都是非全屏的。要實(shí)現(xiàn)設(shè)備橫屏?xí)r視頻全屏顯示,說起來很簡單,就是通過改變Video組件寬高來實(shí)現(xiàn)。
上面我們把videoWidth和videoHeight存放在state中,目的就是為了通過改變兩個(gè)變量的值來刷新UI,使視頻寬高能隨之改變。問題是,怎樣在設(shè)備的屏幕旋轉(zhuǎn)時(shí)及時(shí)獲取到改變后的寬高呢?
豎屏?xí)r我設(shè)置的視頻初始寬度為設(shè)備屏幕的寬度,高度為寬度的9/16,即按16:9的比例顯示。橫屏?xí)r視頻的寬度應(yīng)為屏幕的寬度,高度應(yīng)為當(dāng)前屏幕的高度。由于橫屏?xí)r設(shè)備寬高發(fā)生了變化,及時(shí)獲取到寬高就能及時(shí)刷新UI,視頻就能全屏展示了。
剛開始我想到的辦法是使用 react-native-orientation 監(jiān)聽設(shè)備轉(zhuǎn)屏的事件,在回調(diào)方法中判斷當(dāng)前是橫屏還是豎屏,這個(gè)在iOS上是可行的,但是在Android上橫屏和豎屏?xí)r獲取到寬高值總是不匹配的(比如,橫屏寬384高582,豎屏寬582高384,顯然不合理),這樣就無法做到統(tǒng)一處理。
所以,監(jiān)聽轉(zhuǎn)屏的方案是不行的,不僅費(fèi)時(shí)還得不到想要的結(jié)果。更好的方案是在render函數(shù)中使用View作為最底層容器,給它設(shè)置一個(gè)"flex:1"的樣式,使其充滿屏幕,在View的onLayout方法中獲取它的寬高。無論屏幕怎么旋轉(zhuǎn),onLayout都可以獲取到當(dāng)前View的寬高和x、y坐標(biāo)。
/// 屏幕旋轉(zhuǎn)時(shí)寬高會(huì)發(fā)生變化,可以在onLayout的方法中做處理,比監(jiān)聽屏幕旋轉(zhuǎn)更加及時(shí)獲取寬高變化
_onLayout = (event) => {
//獲取根View的寬高
let {width, height} = event.nativeEvent.layout;
console.log('通過onLayout得到的寬度:' + width);
console.log('通過onLayout得到的高度:' + height);
// 一般設(shè)備橫屏下都是寬大于高,這里可以用這個(gè)來判斷橫豎屏
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,
})
}
};
這樣就實(shí)現(xiàn)了屏幕在旋轉(zhuǎn)時(shí)視頻也隨之改變大小,橫屏?xí)r全屏播放,豎屏回歸正常播放。注意,Android和iOS需要配置轉(zhuǎn)屏功能才能使界面自動(dòng)旋轉(zhuǎn),請(qǐng)自行查閱相關(guān)配置方法。
播放控制
上面實(shí)現(xiàn)了全屏播放還不夠,我們還需要一個(gè)工具欄來控制視頻的播放,比如顯示進(jìn)度,播放暫停和全屏按鈕。具體思路如下:
- 使用一個(gè)View將Video組件包裹起來,View的寬高和Video一致,便于轉(zhuǎn)屏?xí)r改變大小
- 設(shè)置一個(gè)透明的遮罩層覆蓋在Video組件上,點(diǎn)擊遮罩層顯示或隱藏工具欄
- 工具欄中要顯示播放按鈕、進(jìn)度條、全屏按鈕、當(dāng)前播放時(shí)間、視頻總時(shí)長。工具欄以絕對(duì)位置布局,覆蓋在Video組件底部
- 使用react-native-orientation中的lockToPortrait和lockToLandscape方法強(qiáng)制旋轉(zhuǎn)屏幕,使用unlockAllOrientations在屏幕旋轉(zhuǎn)以后撤銷轉(zhuǎn)屏限制。
這樣才算是一個(gè)有模有樣的視頻播放器。下面是豎屏和橫屏的效果圖


再也不必為presentFullscreenPlayer方法不起作用而煩惱了,全屏播放實(shí)現(xiàn)起來其實(shí)很簡單。具體代碼請(qǐng)看demo: https://github.com/mrarronz/react-native-blog-examples/tree/master/Chapter7-VideoPlayer/VideoExample 。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
深入理解react-router 路由的實(shí)現(xiàn)原理
這篇文章主要介紹了深入理解react-router 路由的實(shí)現(xiàn)原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
react實(shí)現(xiàn)動(dòng)態(tài)增減表單項(xiàng)的示例代碼
在做項(xiàng)目的時(shí)候,甲方給的信息有限,網(wǎng)頁的備案信息寫成固定的,之后驗(yàn)收的時(shí)候,甲方要求把這個(gè)備案信息寫成動(dòng)態(tài)的,可以自增減,下面通過實(shí)例代碼給大家介紹react實(shí)現(xiàn)動(dòng)態(tài)增減表單項(xiàng)的示例,感興趣的朋友跟隨小編一起看看吧2024-05-05
React實(shí)現(xiàn)控制減少useContext導(dǎo)致非必要的渲染詳解
這篇文章主要介紹了React如何有效減少使用useContext導(dǎo)致的不必要渲染,使用useContext在改變一個(gè)數(shù)據(jù)時(shí),是通過自己逐級(jí)查找對(duì)比改變的數(shù)據(jù)然后渲染,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
react+typescript中使用echarts的實(shí)現(xiàn)步驟
本文主要介紹了react+typescript中使用echarts的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
React中super()和super(props)的區(qū)別小結(jié)
本文主要介紹了React中super()和super(props)的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03
react native 原生模塊橋接的簡單說明小結(jié)
這篇文章主要介紹了react native 原生模塊橋接的簡單說明小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
React項(xiàng)目中應(yīng)用TypeScript的實(shí)現(xiàn)
TypeScript通常都會(huì)依賴于框架,例如和vue、react 這些框架結(jié)合,本文就主要介紹了React項(xiàng)目中應(yīng)用TypeScript的實(shí)現(xiàn),分享給大家,具體如下:2021-09-09
基于React實(shí)現(xiàn)調(diào)用式Modal組件的全流程
本文基于 nextUI 和 tailwindCSS 實(shí)現(xiàn)調(diào)用式 Modal 組件的封裝,文中通過圖文結(jié)合的方式和代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-12-12
React路由規(guī)則定義與聲明式導(dǎo)航及編程式導(dǎo)航分別介紹
這篇文章主要介紹了React路由規(guī)則的定義、聲明式導(dǎo)航、編程式導(dǎo)航,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09

