我正在使用 webRtc 和 socket.io 创建一个视频通话 React 应用程序
报价和答案在同行之间完美共享,但我无法发送视频轨道。
ontrack 事件列表器没有被解雇,我不知道我在这里做错了什么,我尝试搜索它,但我找不到任何有效的解决方案..
import { useState,useEffect,useCallback } from "react";
import io from 'socket.io-client'
import ReactPlayer from "react-player";
function App() {
var peer;
const socket=io('http://localhost:4080/')
const [email, setEmail] = useState("");
const [room, setRoom] = useState("");
const [recivingcall,setrecivingcall]=useState(false)
const [makingcall,setmakingcall]=useState(false)
const[mystream,setmystream]=useState('')
const [connected,setconnected]=useState(false)
const[remotestream,setremotestream]=useState('')
const makecall=()=>{
console.log("email ",email," room ",room)
socket.emit('join-room',{email,room})
}
const joincall=()=>{
}
const opencamera=()=>{
navigator.mediaDevices.getUserMedia({audio:false,video:true}).then(
async (stream)=>{
setmystream(stream)
const configuration={'iceServers':[{'urls':'stun:stun.l.google.com:19302'}]}
peer=new RTCPeerConnection(configuration)
if (peer) {
const offer = await peer.createOffer();
await peer.setLocalDescription(new RTCSessionDescription(offer));
socket.emit('sending-offer',offer)
stream.getTracks().forEach(track => {
peer.addTrack(track, stream);
});
}
}
)
}
const creatanswer =async(offer)=>{
if(offer){
const configuration={'iceServers':[{'urls':'stun:stun.l.google.com:19302'}]}
peer=new RTCPeerConnection(configuration)
if (peer) {
await peer.setRemoteDescription(new RTCSessionDescription(offer));
const ans = await peer.createAnswer();
await peer.setLocalDescription(new RTCSessionDescription(ans));
socket.emit('sending-answer',ans)
}
navigator.mediaDevices.getUserMedia({audio:false,video:true}).then((stream)=>{
setmystream(stream)
if(peer){ stream.getTracks().forEach(track => {
peer.addTrack(track, stream);
});}
})
}
}
const hendelanswer_recived=async(ans)=>{
if(ans){console.log(ans)
const remotedes=new RTCSessionDescription(ans)
await peer.setRemoteDescription(remotedes)
console.log('peer',peer)
socket.emit('connection-complete','ok')
}
}
const hendelconnection=()=>{
peer.addEventListener('track', async (event) => {
const [remoteStream] = event.streams;
setremotestream(remoteStream)})
console.log(peer.connetionState)
}
useEffect(()=>{
socket.on('room-created',(ev)=>{
setconnected(true)
opencamera()
})
socket.on('offer-recived',(offer)=>{
console.log(offer)
creatanswer(offer)
})
socket.on('answer-recived',hendelanswer_recived)
if(peer){
peer.addEventListener('icecandidate',event=>{
if(event.candidate){
console.log('candidate ',event.candidate)
}
else{
console.log('candidate-notfound')
}
})
}
socket.on('connection-complete',hendelconnection)
})
return (
<>
<input id="email" onChange={(e)=>setEmail(e.target.value)}></input>
<input id="room" onChange={(e)=>setRoom(e.target.value)}></input>
{connected?<h1>Connecting...</h1>:<></>}
{mystream &&( <ReactPlayer playing
muted
height="100px"
width="200px"
url={mystream}
></ReactPlayer>)}
<button onClick={()=>{makecall()}}>makecall</button>
{remotestream && (
<>
<h1>Remote Stream</h1>
<ReactPlayer
playing
muted
height="100px"
width="200px"
url={remotestream}
/>
</>
)}
{recivingcall?<button id="joincall" onClick={()=>joincall()}>joincall</button>:<></>}
</>
)
}
export default App;
这是我的应用程序的代码。
WebRTC 中的会话描述还描述了对等点之间共享的数据。这意味着您必须在创建报价或答案之前添加曲目。
localstream = await navigator.mediaDevices.getUserMedia({audio: true, video: true})
localstream.getTracks().forEach(track => peer.addTrack(track, localstream));
const offer = await peer.createOffer();
await peer.setLocalDescription(new RTCSessionDescription(offer));
此外,如果有时您想要更改或添加新的流到连接,您将需要重新协商。这意味着添加新曲目后只需再次执行报价应答流程。 RTCPeerConnections 上还有一个事件,如果需要重新协商,则会触发该事件:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/negotiationneeded_event