React with PeerJS自动应答Peer呼叫



我正在尝试构建一个应用程序,其中用户呼叫用户,然后其他用户自动接受呼叫。

目前我有它作为一个按钮说"答案"(当电话被接收时),然后用户点击这个按钮,它将开始视频通话,但我如何使它自动接听,而不需要用户点击这个按钮?

export default function Board() {
const [me, setMe] = useState("")
const [stream, setStream] = useState()
const [receivingCall, setReceivingCall] = useState(false)
const [caller, setCaller] = useState("")
const [callerSignal, setCallerSignal] = useState()
const [callAccepted, setCallAccepted] = useState(false)
const [idToCall, setIdToCall] = useState("")
const [callEnded, setCallEnded] = useState(false)
const [name, setName] = useState("")
const [randomId, setRandomId] = useState(null)
const myVideo = useRef()
const userVideo = useRef()
const connectionRef = useRef()
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((stream) => {
setStream(stream)
myVideo.current.srcObject = stream
})
socket.on("me", (id) => {
setMe(id)
axios.post("http://localhost:5000/ex", {
displayName: firebase.auth().currentUser.displayName,
me: id
})
.then(resp => console.log("Me =", resp.data))
})
socket.on("callUser", (data) => {
setReceivingCall(true)
setCaller(data.from)
setName(data.name)
setCallerSignal(data.signal)
})
}, [])
const getRandomId = () => {
}
const callUser = async (id) => {
axios.post("http://localhost:5000/ex2", {
me
}).then(resp => {
setRandomId(resp.data)
})
const peer = new Peer({
initiator: true,
trickle: false,
stream: stream
})
peer.on("signal", (data) => {
socket.emit("callUser", {
userToCall: randomId,
signalData: data,
from: me,
name: firebase.auth().currentUser.displayName
})
})
peer.on("stream", (stream) => {
userVideo.current.srcObject = stream
})

socket.on("callAccepted", (signal) => {
setCallAccepted(true)
peer.signal(signal)
})
connectionRef.current = peer
}
const changeCall = () => {
}
const answerCall = () => {
setCallAccepted(true)
const peer = new Peer({
initiator: false,
trickle: false,
stream: stream
})
peer.on("signal", (data) => {
socket.emit("answerCall", { signal: data, to: caller })
})
peer.on("stream", (stream) => {
userVideo.current.srcObject = stream
})
peer.signal(callerSignal)
connectionRef.current = peer
}
const leaveCall = () => {
setCallEnded(true)
connectionRef.current.destroy()
}
const videoDimensions = {
objectFit: "cover"
}
return (
<div className="">
<div className="video-container">
<div className="video">
{stream && <video playsInline muted ref={myVideo} autoPlay style={videoDimensions} />}
</div>
<div className="video">
{callAccepted && !callEnded ?
<video playsInline muted ref={userVideo} autoPlay style={videoDimensions} /> :
null}
</div>
</div>
<div className="myId">
<input placeholder="name" onChange={(e) => setName(e.target.value)}></input>
<p>{me}</p>
<input placeholder="to call" onChange={(e) => setIdToCall(e.target.value)}></input>
<div className="call-button">
{callAccepted && !callEnded ? (
<button onClick={leaveCall}>
End Call
</button>
) : (
<button color="primary" aria-label="call" onClick={() => callUser(idToCall)}>
call
</button>
)}
{idToCall}
</div>
</div>
<div>
{receivingCall && !callAccepted ? (
<div className="caller">
<h1 >{name} is calling...</h1>
<button id="answerButton" variant="contained" color="primary" onClick={answerCall}>
Answer
</button>
</div>
) : null}
</div>

</div>
)
}

我试着把"answerCall"函数在callUser"正文,但会给出以下错误:

Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'renegotiate')

我只是想呼叫一个用户,然后另一个用户自动接受,而不需要手动点击"应答"。按钮。

你看过一个叫Livekit.io的开源项目吗?

它的自我描述是"一个开源项目,通过WebRTC提供可扩展的多用户会议。"它旨在为您提供在应用程序中构建实时音频和/或视频体验所需的一切。">

他们的文档在这里:https://docs.livekit.io/