ReactNative——react-native-video實現視訊全屏播放

不變旋律發表於2018-03-07

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-videoyarn add react-native-video安裝,完成之後使用react-native link react-native-video命令link這個庫。

Android端在執行完link命令後,gradle中就已經完成了配置。iOS端還需要手動配置一下,這裡簡單說一下,與官方說明不同的是,我們一般不使用tvOS的,選中你自己的target,在build phases中先移除掉自動link進來的libRCTVideo.a這個庫,然後點選下方加號重新新增libRCTVideo.a,注意不要選錯。

ReactNative——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在螢幕旋轉以後撤銷轉屏限制。

這樣才算是一個有模有樣的視訊播放器。下面是豎屏和橫屏的效果圖

ReactNative——react-native-video實現視訊全屏播放

ReactNative——react-native-video實現視訊全屏播放

再也不必為presentFullscreenPlayer方法不起作用而煩惱了,全屏播放實現起來其實很簡單。具體程式碼請看demo:github.com/mrarronz/re…

總結

  1. react-native-orientation和react-native-video都還有缺陷,但是已經可以運用到專案中了
  2. 有時候解決問題要換種思路,不能一棵樹上吊死。坐下來喝杯茶,換種心態、換個搜尋關鍵詞說不定就得到了你想要的答案。

相關文章