WebRT C: функция onicecandidate не была вызвана, поэтому удаленное видео не отображается - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь создать одноранговое соединение web RT C при реагировании. Я использую модуль react-native-webrt c. При использовании двух эмуляторов и передаче одного и того же идентификатора комнаты видеосвязь не создается. Во время отладки я обнаружил, что функция onIceCandidate не вызывается. Я использую socket.io для создания комнаты. Пожалуйста, помогите мне с этим.

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',

  }
});

Ответы [ 3 ]

0 голосов
/ 30 мая 2020

Может быть хорошей идеей использовать simple-peer , поскольку это упрощает сценарий webrt c. Это npm пакеты, поэтому вы можете напрямую реализовать его в React. Вот пример проекта для многопользовательского вызова PROJECT DEMO

0 голосов
/ 31 мая 2020

В WebRT C вам нужно настроить SSL или вы можете просто использовать его в локальной среде. В противном случае объект MediaStream не может быть захвачен. Кроме того, вы не подключаетесь к same-origin в клиенте сокета. Убедитесь, что соединение сокета не столкнулось с проблемой CORS и ваша процедура передачи сигналов работает правильно.

0 голосов
/ 30 мая 2020

В вашем коде много фундаментальных проблем, и я уверен, что это не просто проблема с ледяным кандидатом. Например, вы создаете новый сокет каждый раз, когда компонент перерисовывает (поскольку вы используете a). Я бы рекомендовал вам использовать вместо этого класс Component и правильно обрабатывать события. Кроме того, вы звоните addStream каждый раз, когда получаете нового ледового кандидата. Его следует добавить только один раз (т.е. желательно перед тем, как вы создадите предложение или ответ). Я думаю, вам стоит проверить основы WebRT C. Воспользуйтесь ссылкой ниже.

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

...