I am making a video calling app using socket.io. But it gives an error.The error is Unhandled Rejection (TypeError): Cannot set properties of undefined (setting ‘srcObject’) though camera is allowed to use.What i have done wrong and how i can fix it any advice.Thanks in advance.
Here is my code which gives error
import React, { useState, useEffect, useRef } from "react";
import VideoContext from "./VideoContext";
import { io } from "socket.io-client";
import Peer from "simple-peer";
import { message } from "antd";
import firebase from 'firebase';
import {db,auth} from "../firebases"
import {useCollection} from 'react-firebase-hooks/firestore'
import {useAuthState} from 'react-firebase-hooks/auth'
const URL = "https://fathomless-tundra-67025.herokuapp.com/";
export const socket = io(URL);
const VideoState = ({ children }) => {
const [callAccepted, setCallAccepted] = useState(false);
const [callEnded, setCallEnded] = useState(false);
const [stream, setStream] = useState();
const [chat, setChat] = useState([]);
const [name, setName] = useState("");
const [call, setCall] = useState({});
const [me, setMe] = useState("");
const [userName, setUserName] = useState("");
const [otherUser, setOtherUser] = useState("");
const [myVdoStatus, setMyVdoStatus] = useState(true);
const [userVdoStatus, setUserVdoStatus] = useState();
const [myMicStatus, setMyMicStatus] = useState(true);
const [userMicStatus, setUserMicStatus] = useState();
const [msgRcv, setMsgRcv] = useState("");
const [screenShare, setScreenShare] = useState(false)
const myVideo = useRef();
const userVideo = useRef();
const connectionRef = useRef();
const screenTrackRef = useRef();
const[dbId,setDbId]=useState(null)
const[user,laoding,error]=useAuthState(auth)
const[userId,setUserId]=useState(null)
useEffect(() => {
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((currentStream) => {
setStream(currentStream);
myVideo.current.srcObject = currentStream;
});
if (localStorage.getItem("name")) {
setName(localStorage.getItem("name"));
}
socket.on("me", (id) => setMe(id));
socket.on("endCall", () => {
window.location.reload();
});
socket.on("updateUserMedia", ({ type, currentMediaStatus }) => {
if (currentMediaStatus !== null || currentMediaStatus !== []) {
switch (type) {
case "video":
setUserVdoStatus(currentMediaStatus);
break;
case "mic":
setUserMicStatus(currentMediaStatus);
break;
default:
setUserMicStatus(currentMediaStatus[0]);
setUserVdoStatus(currentMediaStatus[1]);
break;
}
}
});
socket.on("callUser", ({ from, name: callerName, signal }) => {
setCall({ isReceivingCall: true, from, name: callerName, signal });
});
socket.on("msgRcv", ({ name, msg: value, sender }) => {
setMsgRcv({ value, sender });
setTimeout(() => {
setMsgRcv({});
}, 2000);
});
}, []);
// useEffect(() => {
// console.log(chat);
// }, [chat]);
const answerCall = () => {
setCallAccepted(true);
setOtherUser(call.from);
const peer = new Peer({ initiator: false, trickle: false, stream });
peer.on("signal", (data) => {
socket.emit("answerCall", {
signal: data,
to: call.from,
userName: name,
type: "both",
myMediaStatus: [myMicStatus, myVdoStatus],
});
});
peer.on("stream", (currentStream) => {
userVideo.current.srcObject = currentStream;
});
peer.signal(call.signal);
connectionRef.current = peer;
console.log(connectionRef.current);
};
const callUser = (id) => {
const peer = new Peer({ initiator: true, trickle: false, stream });
setOtherUser(id);
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, userName }) => {
setCallAccepted(true);
setUserName(userName);
peer.signal(signal);
socket.emit("updateMyMedia", {
type: "both",
currentMediaStatus: [myMicStatus, myVdoStatus],
});
});
connectionRef.current = peer;
console.log(connectionRef.current);
};
const updateVideo = () => {
setMyVdoStatus((currentStatus) => {
socket.emit("updateMyMedia", {
type: "video",
currentMediaStatus: !currentStatus,
});
stream.getVideoTracks()[0].enabled = !currentStatus;
return !currentStatus;
});
};
const updateMic = () => {
setMyMicStatus((currentStatus) => {
socket.emit("updateMyMedia", {
type: "mic",
currentMediaStatus: !currentStatus,
});
stream.getAudioTracks()[0].enabled = !currentStatus;
return !currentStatus;
});
};
//SCREEN SHARING
const handleScreenSharing = () => {
if(!myVdoStatus){
message.error("Turn on your video to share the content", 2);
return;
}
if (!screenShare) {
navigator.mediaDevices
.getDisplayMedia({ cursor: true })
.then((currentStream) => {
const screenTrack = currentStream.getTracks()[0];
// replaceTrack (oldTrack, newTrack, oldStream);
connectionRef.current.replaceTrack(
connectionRef.current.streams[0]
.getTracks()
.find((track) => track.kind === 'video'),
screenTrack,
stream
);
// Listen click end
screenTrack.onended = () => {
connectionRef.current.replaceTrack(
screenTrack,
connectionRef.current.streams[0]
.getTracks()
.find((track) => track.kind === 'video'),
stream
);
myVideo.current.srcObject = stream;
setScreenShare(false);
};
myVideo.current.srcObject = currentStream;
screenTrackRef.current = screenTrack;
setScreenShare(true);
}).catch((error) => {
console.log("No stream for sharing")
});
} else {
screenTrackRef.current.onended();
}
};
//full screen
const fullScreen = (e) => {
const elem = e.target;
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) {
/* Firefox */
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
/* Chrome, Safari & Opera */
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) {
/* IE/Edge */
elem.msRequestFullscreen();
}
};
const leaveCall = () => {
setCallEnded(true);
connectionRef.current.destroy();
socket.emit("endCall", { id: otherUser });
window.location.reload();
};
const leaveCall1 = () => {
socket.emit("endCall", { id: otherUser });
};
const sendMsg = (value) => {
socket.emit("msgUser", { name, to: otherUser, msg: value, sender: name });
let msg = {};
msg.msg = value;
msg.type = "sent";
msg.timestamp = Date.now();
msg.sender = name;
setChat([...chat, msg]);
};
// console.log("user email",user.email)
const[users,loadse,e]=useCollection(db.collection('users').where('email','==',user.email))
users?.docs?.map((doc)=>{
// alert(doc.id)
// console.log("dbge",doc.data().email)
setUserId(doc.id)
db.collection('users').doc(doc.id).set({
socketId:me
},{merge:true})
})
// console.log("userid",userId)
return (
<VideoContext.Provider
value={{
dbId,
call,
callAccepted,
myVideo,
userVideo,
stream,
name,
setName,
callEnded,
me,
callUser,
leaveCall,
answerCall,
sendMsg,
msgRcv,
chat,
setChat,
setMsgRcv,
setOtherUser,
leaveCall1,
userName,
myVdoStatus,
setMyVdoStatus,
userVdoStatus,
setUserVdoStatus,
updateVideo,
myMicStatus,
userMicStatus,
updateMic,
screenShare,
handleScreenSharing,
fullScreen
}}
>
{children}
</VideoContext.Provider>
);
};
export default VideoState;