I am making a MERN stack application that allows users to watch youtube videos together synchronously. I use socket.io for real-time event handling and react-youtube to use Youtube's iframe API. In my video component, I have a player
state that updates to event.target
when the onReady
event is fired. But it looks like the player state is not updating. When I try to do player.pauseVideo() or player.playVideo() I get the error Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'pauseVideo')
Here is my Youtube Player component
import YouTube from "react-youtube";import { SocketContext } from "../contexts/socket";import { useEffect, useState, useContext } from "react";const YoutubePlayer = ({ roomId }) => { const socket = useContext(SocketContext); const [player, setPlayer] = useState(); useEffect(() => { socket.on("play_video", () => { console.log("player: ", player); // Gives undefined player.playVideo(); }); socket.on("pause_video", () => { console.log("player: ", player); // Gives undefined player.pauseVideo(); }); }, [socket]); const onPlayerReady = (event) => { console.log("event.target: ", event.target); //this works & prints the player object in console. setPlayer(event.target); // this is where the problem is }; const onPlayerStateChange = (event) => { if (event.data === 1) { socket.emit("play_video", { roomId: roomId }); } else if (event.data === 2) { socket.emit("pause_video", { roomId: roomId }); } }; const options = { height: "390", width: "640", playerVars: { autoplay: 0, }, }; return (<YouTube videoId="AaGK-fj-BAM" opts={options} onReady={onPlayerReady} onStateChange={onPlayerStateChange} /> );};export default YoutubePlayer;
Here is my backend socket code for player events
const playVideo = (socket, io) => { socket.on("play_video", ({roomId}) => { console.log("played"); io.to(roomId).emit("play_video", {}); });};const pauseVideo = (socket, io) => { socket.on("pause_video", ({roomId}) => { console.log("paused"); io.to(roomId).emit("pause_video", {}); });};const socketHandler = (io) => { return io.on('connection', (socket) => { console.log('testing'); console.log(`User connected ${socket.id}`); joinRoom(socket); createRoom(socket); sendMessage(socket, io); playVideo(socket, io); pauseVideo(socket, io); })} module.exports = { socketHandler };