I was trying to build a custom video chat app with socket.io ,react and express . But while getting the input of my own video camera I am facing a problem which showing an error with a message of "Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'srcObject')".
if you want to see the code of my app (I wrote almost all the functionality in a single page):
import React, { createContext, useEffect, useRef, useState } from "react";
import {io} from "socket.io-client";
import Peer from "simple-peer";
const SocketContext = createContext();
const socket = io('https://quiet-thicket-62197.herokuapp.com/');
const ContextProvider = ({ children }) =>{
const [stream,setStream] = useState();
const [me,setMe] = useState('');
const [call , setCall] = useState({});
const [callAccepted , setSetCallAccepted] = useState(false);
const [callEnded , setCallEnded] = useState(false);
const [name , setName] = useState('');
const [modalShow,setModalShow] = useState(false);
const myVideo = useRef();
const userVideo = useRef();
const connectionRef = useRef();
useEffect(()=>{
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then((currentStream)=>{
setStream(currentStream);
myVideo.current.srcObject = currentStream;
});
socket.on('me',(id)=> setMe(id));
socket.on('calluser',({ from , name : callerName , signal })=> {
setCall({ isReceivedCall : true , from , name : callerName , signal })
});
},[]);
const answerCall = () =>{
setSetCallAccepted(true);
const peer = new Peer({ initiator : false , trickle : false , stream });
peer.on('signal', (data)=>{
socket.emit("answercall", { signal : data , to : call.from })
});
peer.on('stream',(currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
}
const callUser = (id) =>{
const peer = new Peer({ initiator : true , trickle : false , stream });
peer.on('signal', (data)=>{
socket.emit("calluser", { userToCall : id , signalData : data , from : me , name })
});
peer.on('stream',(currentStream) => {
userVideo.current.srcObject = currentStream;
});
socket.on('callaccepted', (signal) =>{
setSetCallAccepted(true);
peer.signal(signal);
});
connectionRef.current = peer;
}
const leaveCall = () =>{
setCallEnded(true);
connectionRef.current.destroy();
window.location.reload();
}
return (
<SocketContext.Provider value={{ call,callAccepted,myVideo,userVideo,stream,name,setName,callEnded,me,callUser,leaveCall,answerCall,modalShow,setModalShow }}>
{children}
</SocketContext.Provider>
)
}
export { ContextProvider , SocketContext };