简体   繁体   English

WebRTC:onicecandidate function 未被调用,因此未显示远程视频

[英]WebRTC: onicecandidate function not been called, hence remote video is not showing

I am trying to create web RTC peer connection on react native.我正在尝试在本机反应上创建 web RTC 对等连接。 I am using the react-native-webrtc module.我正在使用 react-native-webrtc 模块。 When using two emulators and passing the same room id the video connection is not been created.当使用两个模拟器并传递相同的房间 ID 时,不会创建视频连接。 While debugging I found the onIceCandidate funciton is not been called.在调试时我发现没有调用 onIceCandidate 函数。 I am using socket.io to create the room.我正在使用 socket.io 创建房间。 Please help me with this.请帮我解决一下这个。

Git: https://github.com/developerajendra/react-native-webrtc-demo Git: https://github.com/developerajendra/react-native-webrtc-demo

import React, {useState, useEffect} from 'react';
import {View, SafeAreaView, Button, StyleSheet, Text} from 'react-native';
import {RTCPeerConnection, RTCView, mediaDevices} from 'react-native-webrtc';
import io from "socket.io-client";

export default function WEBRtc({roomNumber}) {
  const [localStream, setLocalStream] = useState();
  const [remoteStream, setRemoteStream] = useState();


  let isCaller, localST, peerConnection;
  const socket = io("http://192.168.0.102:3000", {transports: ['websocket']});

  const constraints = {
    audio: true,
    video:false
  };


/**
 * Getting ready for local stream 
 */
  const startLocalStream = () => {
      socket.emit('joinTheRoom', roomNumber);
  };

  socket.on('roomCreated', room=>{
    console.log('room created');

    mediaDevices.getUserMedia(constraints)
      .then(stream=>{
        setLocalStream(stream);
        localST = stream;
        isCaller = true;
      })
  });

  socket.on('roomJoined', room=>{
    console.log('room joined');
    mediaDevices.getUserMedia(constraints)
      .then(stream=>{
        setLocalStream(stream);
        socket.emit('ready', roomNumber)
      });
  });




  const configuration = {iceServers: [
    {'urls':'stun:stun.services.mozilla.com'},
    {'urls':'stun:stun.l.google.com:19302'}
  ]};


  // const localPC = new RTCPeerConnection(configuration);
  // const remotePC = new RTCPeerConnection(configuration);

  // const peerConnection = new RTCPeerConnection(configuration);

    socket.on('ready', room=>{
      if(isCaller){
        console.log('ready');
        peerConnection = new RTCPeerConnection(configuration);
        peerConnection.onicecandidate = onIceCandidate;
        peerConnection.onaddstream = onAddStream;
        peerConnection.createOffer()
        .then(offer=>{
          return peerConnection.setLocalDescription(offer)
          .then(()=>{
            console.log('emit offer');
              socket.emit('offer',{
                type:'offer',
                sdp:offer,
                room: roomNumber
              });
            })
          })
      }
    });

    socket.on("offer",e=>{

      if(!isCaller){
        peerConnection = new RTCPeerConnection(configuration);
        console.log('offer');
        peerConnection.onicecandidate = onIceCandidate;
        peerConnection.onaddstream = onAddStream;

        console.log('about to create answer', e);

        //accept offer from here(ready)
        peerConnection.setRemoteDescription(e)
        .then(()=>{
          return peerConnection.createAnswer()
          .then(answer=>{
            return peerConnection.setLocalDescription(answer)
            .then(()=>{
              console.log('emit answer');
                socket.emit('answer',{
                  type:'answer',
                  sdp: answer,
                  room: roomNumber
              }); 
            })
          })
        });
      }

    });



    function onAddStream(e){
      console.log('remote stream', e);
      if (e.stream && remoteStream !== e.stream) {
        console.log('remote stream', e.stream);

        setRemoteStream(e.stream);
      }
  };


    function onIceCandidate(event){
      console.log('ice candidate');

      if(event.candidate){
          console.log('sending ice candidate', event.candidate);

          socket.emit('candidate',{
              type: 'candidate',
              label: event.candidate.sdpMLineIndex,
              id: event.candidate.sdpMid,
              candidate: event.candidate.candidate,
              room: roomNumber
          });
      }
  }


    socket.on('candidate', e=>{
      console.log('candidate', isCaller);
      peerConnection.addIceCandidate(e);
      peerConnection.addStream(localStream);
    });

    socket.on('answer', e=>{
      console.log('answer');
      peerConnection.setRemoteDescription(e);
    });




  return (
    <SafeAreaView style={styles.container}>
    <View style={styles.streamContainer}>
      <View style={styles.streamWrapper}>
          <View style={styles.localStream}>
            {localStream && <RTCView style={styles.rtc} streamURL={localStream.toURL()} />}
            {!localStream && <Button title="Tap to start" onPress={startLocalStream} />}
          </View>
          <View style={styles.rtcview}>
            {remoteStream && <RTCView style={styles.rtc} streamURL={remoteStream.toURL()} />}
          </View>
        </View>
        {/* {!!remoteStream ? <Button style={styles.toggleButtons} title="Click to stop call" onPress={closeStreams} disabled={!remoteStream} /> : localStream && <Button title="Click to start call" onPress={startCall}  />} */}
    </View>
</SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#313131',
    justifyContent: 'space-between',
    alignItems: 'center',
    height: '100%',
    width:'100%'
  },
  streamContainer:{
    backgroundColor: 'grey',
    // justifyContent: 'space-around',
    alignItems: 'center',
    height: '50%',
    width: '100%',
    flexDirection:'column'
  },
  streamWrapper:{
    backgroundColor: 'grey',
    justifyContent: 'space-around',
    alignItems: 'center',
    height: '100%',
    width: '100%',
    flexDirection:'row'
  },
  roomTitle:{
    fontSize:20,
    paddingTop:20
  },
  rtcview: {
    width: '45%',
    height: '60%',
    borderColor:'#ccc',
    borderWidth:3,

  },
  rtc: {
    width: '100%',
    height: '100%',
  },
  localStream:{
    width: '45%',
    height: '60%',
    borderColor:'#ccc',
    borderWidth:3,
    display:'flex',
    alignItems:'center',
    flexDirection:'row',
    justifyContent:'space-around',

  }
});

Your code has a lot of fundamental issues and I am sure that it isn't just ice candidate issue.您的代码有很多基本问题,我相信这不仅仅是冰候选问题。 For instance, you are creating a new socket every time the Components rerenders(since you're using a ).例如,每次组件重新呈现时,您都在创建一个新套接字(因为您使用的是 )。 I'd recommend you using a class Component instead and handling events properly.我建议您改用 class 组件并正确处理事件。 Also, you're calling addStream every time you get a new ice candidate.此外,每次获得新的候选冰时,您都会调用addStream It should be added only once(ie preferably before you create an offer or answer).它应该只添加一次(即最好在您创建报价或答案之前)。 I think you should check WebRTC basics.我认为您应该检查 WebRTC 基础知识。 Please try the below link.请尝试以下链接。

https://webrtc.github.io/samples/src/content/peerconnection/pc1/ https://webrtc.github.io/samples/src/content/peerconnection/pc1/

It may be a good idea to use simple-peer as it simplifies the webrtc script.使用simple-peer可能是个好主意,因为它简化了 webrtc 脚本。 It's an npm packages so you can directly implement it in react.这是一个 npm 包,因此您可以直接在反应中实现它。 Here an example project for multi-user calling PROJECT DEMO这里是一个多用户调用PROJECT DEMO的示例项目

In WebRTC you have to configure SSL or you can just use it in a local environment.在 WebRTC 中,您必须配置 SSL 或者您可以在本地环境中使用它。 Otherwise MediaStream object can not be captured.否则无法捕获MediaStream object。 Also, you are not connecting to same-origin in the socket client.此外,您没有连接到套接字客户端中same-origin Make sure that the socket connection has not faced a CORS problem and your signaling procedure is working properly.确保套接字连接没有遇到CORS问题并且您的信令程序正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM