首页 > 解决方案 > 使用 simple-peer 构建视频通话应用程序时出错并做出反应

问题描述

最近我用 simple-peer、react.js 和 socket.io 做了一个视频通话网站。它在笔记本电脑网络浏览器之间工作正常,但我在从移动网络浏览器到笔记本电脑网络浏览器的视频通话中遇到错误。有人可以告知导致此错误的原因以及如何纠正它。

代码-

function VideoComponent(props) {

  //const [yourID, setYourID] = useState("");
  //const [users, setUsers] = useState({});
  const [stream, setStream] = useState();
  const [receivingCall, setReceivingCall] = useState(props.receivingCall);
  const [caller, setCaller] = useState(props.caller);
  const [callerSignal, setCallerSignal] = useState(props.callerSignal);
  const [callAccepted, setCallAccepted] = useState(props.callAccepted);
  const [open, setOpen] = useState(false)
  const [calling, setCalling] = useState(false)

  const userVideo = useRef();
  const partnerVideo = useRef();
  const socket = props.socket
  //const ENDPOINT = '/'

  useEffect(() => {
    if(props.useAudio && props.useVideo){
    navigator.mediaDevices.getUserMedia({ video: props.useVideo, audio: props.useAudio }).then(stream => {
      setStream(stream);
      if (userVideo.current && props.useAudio && props.useVideo) {
        userVideo.current.srcObject = stream;
      }
    })
  }
    //socket = io(ENDPOINT);
    /*socket.on("hey", (data) => {
      setReceivingCall(true);
      setCaller(data.from);
      setCallerSignal(data.signal);
    })*/
  }, []);

  const callPeer=()=> {
    setCalling(true)
    if(props.selectedUser[0]['status'] !== 'online'){
      setOpen(true)
    }
    if(props.useAudio && props.useVideo){
    const peer = new Peer({
      initiator: true,
      trickle: false,
      stream: stream,
    });

    peer.on("signal", data => {
      socket.emit("callUser", { userToCall: props.selectedUser[0]['_id'], 
        signalData: data, from:  props.userDetail[0]['_id']})
    })

    peer.on("stream", stream => {
      if (partnerVideo.current) {
        console.log('receiving stream from partner')
        partnerVideo.current.srcObject = stream;
      }
    });

    socket.on("callAccepted", signal => {
      setCallAccepted(true);
      peer.signal(signal);
    })
}
  }

  function acceptCall() {
    setCallAccepted(true);
    if(props.useAudio && props.useVideo){
    const peer = new Peer({
      initiator: false,
      trickle: false,
      stream: stream,
    });
    peer.on("signal", data => {
      socket.emit("acceptCall", { signal: data, receiverID: caller })
    })

    peer.on("stream", stream => {
      partnerVideo.current.srcObject = stream;
    });

    peer.signal(callerSignal);
  }
  }

  let UserVideo;
  if (stream) {
    UserVideo = (
      <video className='newVideo1' playsInline muted ref={userVideo} autoPlay />
    );
  }

  let PartnerVideo;
  if (callAccepted) {
    PartnerVideo = (
      <video className='newVideo' playsInline  ref={partnerVideo} autoPlay />
    );
  }

  let incomingCall;
  if (receivingCall && !callAccepted) {
    incomingCall = (
      <div className='incomingCall'>
        <h1>{caller} is calling you</h1>
        <Button
        variant="contained"
        color="secondary"
        onClick={acceptCall}
        className='acceptButton'
      >
        Accept call
        </Button>
      </div>
    )
  }

从移动网络浏览器 (Chrome) 调用笔记本电脑网络浏览器 (Chrome) 时出错

index.js:17 Uncaught Error: Connection failed.
    at h (index.js:17)
    at f.value (index.js:654)
    at RTCPeerConnection.t._pc.onconnectionstatechange (index.js:119)

标签: node.jsreactjssocket.iosimple-peer

解决方案


它可能与 TURN 服务器有关。如果您打算部署此应用程序,则需要设置一个。

根据您的代码,它看起来受到https://github.com/coding-with-chaim/react-video-chat/blob/master/client/src/App.js的启发

使用他的代码中给出的相同 TURN 设置,看看它是否有效。它对我有用。


推荐阅读