visit
To play YouTube videos in React Native, we will be making use of the npm dependency named . We will use this library by fully integrating it into an app.
You need to install react-native-webview first. Simply run:
yarn add react-native-webview
or
npm install react-native-webview
then install react-native-youtube-iframe:
yarn add react-native-youtube-iframe
or
npm install react-native-youtube-iframe
Usage
/**
* Sample React Native App
* //github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React from 'react';
import {View} from 'react-native';
import YoutubePlayer from 'react-native-youtube-iframe';
const App = () => {
return (
<View>
<YoutubePlayer
height={300}
play={true}
videoId={'84WIaK3bl_s'}
/>
</View>
);
};
The required props here are height and the videoId of the YouTube video you intend to play in the React Native app. As seen in the app below, we have a Casey Neistat travel vlog on display:
The play prop is set to true, so let us take it a step further and control play and pause actions:
/**
* Sample React Native App
* //github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {useState, useCallback} from 'react';
import {Button, View, Alert} from 'react-native';
import YoutubePlayer from 'react-native-youtube-iframe';
const App = () => {
const [playing, setPlaying] = useState(false);
const togglePlaying = () => {
setPlaying((prev) => !prev);
}
return (
<View>
<YoutubePlayer
height={300}
play={playing}
videoId={'84WIaK3bl_s'}
/>
<Button title={playing ? 'pause' : 'play'} onPress={togglePlaying} />
</View>
);
};
Now we have a control to play and pause the YouTube video. It would be nice to add a feature to tell the user that the video is done playing by passing a callback such as the onChangeState prop provided by the dependency:
/**
* Sample React Native App
* //github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {useState} from 'react';
import {Button, View, Alert} from 'react-native';
import YoutubePlayer from 'react-native-youtube-iframe';
const App = () => {
const [playing, setPlaying] = useState(false);
const onStateChange = (state) => {
if (state === 'ended') {
setPlaying(false);
Alert.alert('video has finished playing!');
}
}
const togglePlaying = () => {
setPlaying((prev) => !prev);
}
return (
<View>
<YoutubePlayer
height={300}
play={playing}
videoId={'84WIaK3bl_s'}
onChangeState={onStateChange}
/>
<Button title={playing ? 'pause' : 'play'} onPress={togglePlaying} />
</View>
);
};
import React, {useState, useRef} from 'react';
import {View, Alert, StyleSheet} from 'react-native';
import YoutubePlayer from 'react-native-youtube-iframe';
import {Icon} from 'react-native-elements';
const App = () => {
const [playing, setPlaying] = useState(false);
const [isMute, setMute] = useState(false);
const controlRef = useRef();
const onStateChange = (state) => {
if (state === 'ended') {
setPlaying(false);
Alert.alert('video has finished playing!');
}
if (state !== 'playing') {
setPlaying(false);
}
};
const togglePlaying = () => {
setPlaying((prev) => !prev);
};
const seekBackAndForth = (control) => {
console.log('currentTime');
controlRef.current?.getCurrentTime().then((currentTime) => {
control === 'forward'
? controlRef.current?.seekTo(currentTime + 15, true)
: controlRef.current?.seekTo(currentTime - 15, true);
});
};
const muteVideo = () => setMute(!isMute);
const ControlIcon = ({name, onPress}) => (
<Icon onPress={onPress} name={name} size={40} color="#fff" />
);
return (
<View style={styles.container}>
<YoutubePlayer
height={300}
ref={controlRef}
play={playing}
mute={isMute}
videoId={'84WIaK3bl_s'}
onChangeState={onStateChange}
/>
<View style={styles.controlContainer}>
<ControlIcon
onPress={() => seekBackAndForth('rewind')}
name="skip-previous"
/>
<ControlIcon
onPress={togglePlaying}
name={playing ? 'pause' : 'play-arrow'}
/>
<ControlIcon
onPress={() => seekBackAndForth('forward')}
name="skip-next"
/>
</View>
<ControlIcon
onPress={muteVideo}
name={isMute ? 'volume-up' : 'volume-off'}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'darkblue',
},
controlContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
},
});
We have added more custom controls to the original component we already had before and added callbacks to seek forward and backward using the playerRef ref.
The mute control is basically managed by the isMute state but it is worthy of note that the dependency provides a method isMuted (returns a promise that resolves to true if the video is muted, false if not) to determine if the video is muted or not.
Previously published at