2021年10月2日 星期六

[react native, video] How to play network and assets video using react-native-video

How to play network and assets video using react-native-video

井民全, Jing, mqjing@gmail.com

[hybrid, cross] Ionic, React Native, Cordova, Electron

GitHub: Download

Mr.Joaquin Viera wrote a good tutorial on how to use react-native-video to play an mp4 video. This document just follows his work with noting some detailed procedures and troubleshooting.





Table of contents

1. Quick 1

2. Detail 2

2.1. Setup Project 2

2.1.1. iOS 2

2.1.2. Install dependencies 4

2.2. Code 5

2.2.1. Step 1: Create a component for video play 5

2.2.2. Step 2: Usage the component 7

2.2.3. Step 3: Setup the video asset 8

2.3. Build & Run 8

2.4. Result 8

3. Troubleshooting 9

3.1. Build failure: error: no member named 'react' in namespace 'facebook' ... 9

3.2. Build failure: TypeError: undefined is not an object (evaluating 'RCTVideoInstance.Constants') 10

4. References 11



Enjoy!
by Jing.

1. Quick

npx react-native init VideoPlayer

cd VideoPlayer


yarn add react-native-video react-native-media-controls react-native-slider


# Download and Install Pods for project, again

cd ios

npx pod-install

cd ..


# Coding

mkdir components

vi VideoPlayer.js       # Create video play component


cd ..

vi app.js                     # Usage


# Create video assets

mkdir assets            wget https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4 video.mp4 


# build & run

launch the simulator

cd ..

npx react-native run-ios


2. Detail

2.1. Setup Project

Step 1: Cerate a template project

npx react-native init VideoPlayer


2.1.1. iOS

Step 2: Download and Install Pods for project

cd VideoPlayer

cd ios

npx pod-install

Test

Step 1: Manually launch the simulator


Step 2: Trail Run

cd ..  # back to the project folder VideoPlayer

npx react-native run-ios

Result

2.1.2. Install dependencies

yarn add react-native-video react-native-media-controls react-native-slider


# Download and Install Pods for project, again

cd ios

npx pod-install

2.2. Code

2.2.1. Step 1: Create a component for video play

Commands

cd $ProjectRoot   #in this demo, this is the folder VideoPlayer

mkdir components

touch VideoPlayer.js


File: components/VideoPlayer.js    (this code was copied from here)

import React, { useState, useRef } from 'react';

import { StyleSheet, View, Platform } from 'react-native';

import MediaControls, { PLAYER_STATES } from 'react-native-media-controls';

import Video from 'react-native-video';


const VideoPlayer = () => {

    

    // The video we will play on the player.

    //  const video = require('../assets/video.mp4'); // work

   const video = {uri: 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4' }


    

    const videoPlayer = useRef(null);

    const [duration, setDuration] = useState(0);

    const [paused, setPaused] = useState(true);


    const [currentTime, setCurrentTime] = useState(0);

    const [playerState, setPlayerState] = useState(PLAYER_STATES.PAUSED);

    const [isLoading, setIsLoading] = useState(true);


    const onSeek = (seek) => {

        videoPlayer?.current.seek(seek);

    };


    const onSeeking = (currentVideoTime) => setCurrentTime(currentVideoTime);


    const onPaused = (newState) => {

        setPaused(!paused);

        setPlayerState(newState);

    };


    const onReplay = () => {

        videoPlayer?.current.seek(0);

        setCurrentTime(0);

        if (Platform.OS === 'android') {

            setPlayerState(PLAYER_STATES.PAUSED);

            setPaused(true);

        } else {

            setPlayerState(PLAYER_STATES.PLAYING);

            setPaused(false);

        }

    };


    const onProgress = (data) => {

        if (!isLoading) {

            setCurrentTime(data.currentTime);

        }

    };


    const onLoad = (data) => {

        setDuration(Math.round(data.duration));

        setIsLoading(false);

    };


    const onLoadStart = () => setIsLoading(true);


    const onEnd = () => {

        setPlayerState(PLAYER_STATES.ENDED);

        setCurrentTime(duration);

    };


    return (

        <View>

            <Video

                onEnd={onEnd}

                onLoad={onLoad}

                onLoadStart={onLoadStart}

                posterResizeMode={'cover'}

                onProgress={onProgress}

                paused={paused}

                ref={(ref) => (videoPlayer.current = ref)}

                resizeMode={'cover'}

                source={video}

                style={styles.backgroundVideo}

            />

            <MediaControls

                isFullScreen={false}

                duration={duration}

                isLoading={isLoading}

                progress={currentTime}

                onPaused={onPaused}

                onReplay={onReplay}

                onSeek={onSeek}

                onSeeking={onSeeking}

                mainColor={"red"}

                playerState={playerState}

                sliderStyle={{ containerStyle: {}, thumbStyle: {}, trackStyle: {} }}

            />

        </View>


    );

};


const styles = StyleSheet.create({

    backgroundVideo: {

        height: 250,

        width: '100%',

    },

    mediaControls: {

        height: '100%',

        flex: 1,

        alignSelf: 'center',

    },

});


export default VideoPlayer;



2.2.2. Step 2: Usage the component

File: app.js

import React from 'react';

import { StyleSheet, View } from 'react-native';

import VideoPlayer from './components/VideoPlayer';


const App = () => {

  return (

    <View style={styles.container}>

      <VideoPlayer />

    </View>

  );

};


const styles = StyleSheet.create({

  container: {

    flex: 1,

    justifyContent: 'center',

    backgroundColor: 'black',

  },

});


export default App;


2.2.3. Step 3: Setup the video asset

cd $ProjectRoot   #in this demo, this is the folder VideoPlayer

mkdir assets

wget https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4 video.mp4


2.3. Build & Run

iOS

npx react-native run-ios


2.4. Result


3. Troubleshooting

iOS

3.1. Build failure: error: no member named 'react' in namespace 'facebook' ...

Error Message

...

/Users/Jing/Desktop/work/lab-react/lab/native/01-rn-videoplayer/VideoPlayer/node_modules/react-native/Libraries/Image/RCTImageStoreManager.mm:199:82: error: no member named 'react' in namespace 'facebook'

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params

                                                                       ~~~~~~~~~~^

/Users/Jing/Desktop/work/lab-react/lab/native/01-rn-videoplayer/VideoPlayer/node_modules/react-native/Libraries/Image/RCTImageStoreManager.mm:201:37: error: no member named 'react' in namespace 'facebook'

  return std::make_shared<facebook::react::NativeImageStoreIOSSpecJSI>(params);

                          ~~~~~~~~~~^

4 errors generated.



** BUILD FAILED **


Solution

Clean the XCode Cache

Step 1: cd ~/Library/Developer/Xcode/DerivedData

Step 2: remove all folders

Step 3: Rebuild

npx react-native run-ios


3.2. Build failure: TypeError: undefined is not an object (evaluating 'RCTVideoInstance.Constants')

Error Message

TypeError: undefined is not an object (evaluating 'RCTVideoInstance.Constants')


This error is located at:

    in Video (at VideoPlayer.jsx:62)

    in RCTView (at View.js:34)

    in View (at VideoPlayer.jsx:61)

    in VideoPlayer (at App.jsx:8)

    in RCTView (at View.js:34)

    in View (at App.jsx:7)

    in App (created by ExpoRoot)

    in ExpoRoot (at renderApplication.js:45)

    in RCTView (at View.js:34)

    in View (at AppContainer.js:106)

    in DevAppContainer (at AppContainer.js:121)

    in RCTView (at View.js:34)

    in View (at AppContainer.js:132)

    in AppContainer (at renderApplication.js:39)


Solution

Make sure the XCode project including librect-native-video.a

Step 1: Open open ios/$YourProjectName.xcworkspace using XCode

Step 2: make sure librect-native-video.a

Click $YourProjectName.xcodeproj

=> [General] [Frameworks, Libraries, and Embedded Contnet]

+ librect-native-video.a


Step 3: Rebuild

npx react-native run-ios



4. References

  1. https://github.com/react-native-video/react-native-video

  2. https://www.asapdevelopers.com/react-native-video-media-controls-example/