首页 > 解决方案 > WebRTC:未调用 onececandidate 函数,因此未显示远程视频

问题描述

我正在尝试在本机反应上创建 Web RTC 对等连接。我正在使用 react-native-webrtc 模块。当使用两个模拟器并传递相同的房间 ID 时,不会创建视频连接。在调试时我发现没有调用 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',

  }
});

标签: javascriptreact-nativevideosocket.iowebrtc

解决方案


在 WebRTC 中,您必须配置 SSL,或者您可以在本地环境中使用它。否则MediaStream无法捕获对象。此外,您没有连接到same-origin套接字客户端。确保套接字连接没有遇到CORS问题,并且您的信令程序正常工作。


推荐阅读