I am setting up a project where the youtube videos will be auto-played and the user will pause/play the video by only using the keyboard hence I have implemented keyup event handler to listen to the keystrokes and its working but I am unable to stop the video by pressing the space bar.
I am using youtube-Iframe-API
Parent Component
import React, { useState, useEffect, useRef } from 'react';
import './style.css';
import ChildCOmp from './ChildCOmp';
export default function App() {
const [iframeSrc, setIframeCont] = useState(false);
const [spaceBtnClicked, setSpaceBtnClick] = useState(false);
useEffect(() => {
setIframeCont('M7lc1UVf-VE');
document.addEventListener('keyup', function(e) {
if (e.code === 'Space') {
debugger;
setSpaceBtnClick(prevState => ({
...prevState,
spaceBtnClicked: !prevState
}));
}
});
}, []);
return (
<div>
<h1>Hello StackBlitz!</h1>
<ChildCOmp iframeSrc={iframeSrc} spaceBtnClicked={spaceBtnClicked} />
</div>
);
}
On this parent, I am sending youtube id(here it's static but in reality it could be dynamic) and the space bar indication state.
Child Component - where youtube API referred and video would be auto-played
import React, { useState, useEffect, useRef } from 'react';
let player = '';
export default function ChildCOmp({ iframeSrc, spaceBtnClicked }) {
useEffect(() => {
//I need to pause/play the video by pressing space button which is coming form parent spaceBtnClicked
if (iframeSrc) {
if (!window.YT) {
// If not, load the script asynchronously
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
// onYouTubeIframeAPIReady will load the video after the script is loaded
window.onYouTubeIframeAPIReady = loadVideo;
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
} else {
// If script is already there, load the video directly
loadVideo();
}
}
});
const loadVideo = () => {
//const { iframeSrc } = props;
// the Player object is created uniquely based on the id in props
player = new window.YT.Player(`youtube-player-${iframeSrc}`, {
videoId: iframeSrc,
height: '600',
width: '870',
playerVars: {
autoplay: 1
},
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange
}
});
};
const onPlayerReady = event => {
event.target.setVolume(100);
event.target.playVideo();
if (spaceBtnClicked) console.log(event); // want to stop the video if space bar clicked
};
const onPlayerStateChange = e => {
if (iframeSrc.id && iframeCont) {
if (spaceBtnClicked) stopVideo();
else {
startVideo();
}
}
console.log(e.target);
};
function stopVideo() {
player.stopVideo();
}
function startVideo() {
player.startVideo();
}
return (
<div>
<div id={`youtube-player-${iframeSrc}`} className="iframeYtExternal" />
</div>
);
}
My requirement is, pause and play the video again by pressing the space bar and I have to send that space bar state from parent to child. I did it with the physical play/pause buttons but I am unable to do if the user press the space bar since its a requirement
I tried to stop it but it shows the player is not defined when the space bar state updates.
DEMO code available here