Play Youtube on React Native

2020-06-27 hit count image

To play Youtube video on React Native, let's see how to use react-native-youtube!

Outline

when I made a toy-project with React Native, I needed to play Youtube on it.

In this blog post, I will show you how to use react-native-youtube to show and play Youtube video.

You can see the example source code on GitHub.

Install and prepare react-native-youtube

Execute the command below to install react-native-youtube.

npm install --save react-native-youtube

Execute the command below to use it on iOS.

cd ios
pod install

You need Youtube developer API key to play Youtube on Android. See the link below to make Youtube developer API key.

How to use react-native-youtube

Play video

Use the source code below to play Youtube via react-native-youtube.


import YouTube from 'react-native-youtube';
...
const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <YouTube
        videoId="KVZ-P-ZI6W4"
        apiKey="YOUR_YOUTUBE_DEVELOPER_API_KEY_FOR_ANDROID"
        play={true}
        fullscreen={false}
        loop={false}
        onReady={(e) => console.log('onReady')}
        onChangeState={(e) => console.log('onChangeState:', e.state)}
        onChangeQuality={(e) => console.log('onChangeQuality: ', e.quality)}
        onError={(e) => console.log('onError: ', e.error)}
        style={{width: '100%', height: 300}}
      />
    </SafeAreaView>
  );
};

Play Video with FlatList

We can not show and play many Youtube videos via react-native-youtube on Android. See the link below about the details of this issue.

So, to show and auto-play with FlatList, we should use FlatList’s viewabilityConfig and onViewableItemsChanged.


...
import YouTube from 'react-native-youtube';

...

const Placeholder = () => {
  return (
    <View style={styles.item}>
      <ActivityIndicator size="large" color="white" />
    </View>
  );
};

const ListVideo = () => {
  const [visablePostIndex, setVisablePostIndex] = useState(0);

  const onViewRef = useRef(({viewableItems}) => {
    if (viewableItems && viewableItems[0]) {
      const index = viewableItems[0].index;
      if (typeof index === 'number') {
        setVisablePostIndex(index);
      }
    } else {
      setVisablePostIndex(-1);
    }
  });
  const viewConfigRef = useRef({viewAreaCoveragePercentThreshold: 80});

  return (
    <View style={styles.container}>
      <FlatList
        data={VIDEO_LIST}
        viewabilityConfig={viewConfigRef.current}
        onViewableItemsChanged={onViewRef.current}
        keyExtractor={(item, index) => `${index}`}
        renderItem={({item, index}) =>
          index === visablePostIndex ? (
            <YouTube
              videoId={item}
              apiKey="YOUR_YOUTUBE_DEVELOPER_API_KEY_FOR_ANDROID"
              play={true}
              fullscreen={false}
              loop={false}
              onReady={(e) => console.log('onReady')}
              onChangeState={(e) => console.log('onChangeState:', e.state)}
              onChangeQuality={(e) =>
                console.log('onChangeQuality: ', e.quality)
              }
              onError={(e) => console.log('onError: ', e.error)}
              style={{width: '100%', height: 300}}
            />
          ) : (
            <Placeholder />
          )
        }
      />
    </View>
  );
};
...

Let’s see the details.


...
const viewConfigRef = useRef({viewAreaCoveragePercentThreshold: 80});
...
<FlatList
  viewabilityConfig={viewConfigRef.current}
...

By using viewabilityConfig, we can set the criterion for which items displayed or not.


...
const onViewRef = useRef(({viewableItems}) => {
    if (viewableItems && viewableItems[0]) {
      const index = viewableItems[0].index;
      if (typeof index === 'number') {
        setVisablePostIndex(index);
      }
    } else {
      setVisablePostIndex(-1);
    }
  });
...
<FlatList
  onViewableItemsChanged={onViewRef.current}
...

And, by using onViewableItemsChanged called when the displayed items are changed, set the Index of items by using useState.


<FlatList
  ...
 renderItem={({item, index}) =>
    index === visablePostIndex ? (
      <YouTube
        videoId={item}
        apiKey="YOUR_YOUTUBE_DEVELOPER_API_KEY_FOR_ANDROID"
        play={true}
        fullscreen={false}
        loop={false}
        onReady={(e) => console.log('onReady')}
        onChangeState={(e) => console.log('onChangeState:', e.state)}
        onChangeQuality={(e) =>
          console.log('onChangeQuality: ', e.quality)
        }
        onError={(e) => console.log('onError: ', e.error)}
        style={{width: '100%', height: 300}}
      />
    ) : (
      <Placeholder />
    )
  }
...

by using and comparing this Index, we can show and play first video of the displayed items. If you use this structure, you can play videos automatically on Android.

Completed

We’ve seen how to play Youtube video on React Native. You can see the full example source code on GitHub.

Posts