错误无法添加候选冰:[错误:远程描述为空]使用addIceCandidate

问题描述 投票:0回答:0

我正在开发一个具有视频通话功能的 React Native 应用程序,我在实现中遇到了一个问题,我收到了这个错误 ERROR Failed to add ice candidate: [Error: The remote description was null] 虽然电话还没有开始。 这段代码是用webrtc调用特定的人,这是我的代码,希望看到这篇的人能帮助我实现,我还是个初学者。 错误从 collectIceCandidates 的最后一行之后开始,它总是会捕获错误,就像我之前说的一样。

import React, {useState, useRef, useEffect} from 'react';
import {Text, StyleSheet, Button, View, TouchableOpacity} from 'react-native';
import GettingCall from './GettingCall';
import Video from './Video';
import Colors from '../../../Styles/Colors';
import AsyncStorage from '@react-native-async-storage/async-storage';
//import Sound from 'react-native-sound';
import {useSurfaceScale} from '@react-native-material/core/src/hooks/use-surface-scale';

import {
MediaStream,
RTCIceCandidate,
RTCPeerConnection,
RTCSessionDescription,
} from 'react-native-webrtc';
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import {getStream} from '../../../utils/VideoCallFunctions';
import {faVideo} from '@fortawesome/free-solid-svg-icons/index';
import firestore from '@react-native-firebase/firestore';
import {useRoute} from '@react-navigation/native';

const configuration = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]};

export default function Cscreen() {
const scale = useSurfaceScale();
const [localStream, setLocalStream] = useState();
const [remoteStream, setRemoteStream] = useState();
const [gettingCall, setGettingCall] = useState(false);
const [isMuted, setIsMuted] = useState(false);
const [myKey, setMyKey] = useState('');
const pc = useRef();
const route = useRoute();
const {peerKey} = route.params || {};
const connecting = useRef(false);

useEffect(() => {
getData();
console.log('myKeys f el useEffect ', myKey);
const cRef = firestore()
.collection('signaling')
.doc('peers')
.collection('keys')
.doc(myKey);
console.log('myKey fel subscribe', myKey);
const subscribe = cRef.onSnapshot(snapshot => {
const data = snapshot.data();
// on answer start call
if (pc.current && !pc.current.remoteDescription && data && data.answer) {
pc.current.setRemoteDescription(new RTCSessionDescription(data.answer));
}

  // If there is offer for chatId set the getting call flag

  if (data && data.offer && !connecting.current) {
    console.log('te7t el connecting');
    setGettingCall(true);
  }
  //if one of the users hangs up without entering the call, the calls is terminated
  if (!data) {
    hangup();
  }
});
// On delete of collection call hangup

// The other side has clicked on hangup
const subscribeDelete = cRef.onSnapshot(snapshot => {
  if (!snapshot.exists) {
    console.log('document does not exist, hangup normally');
    hangup();
  }
});

return () => {
  subscribe();
  subscribeDelete();
};

}, []);

const getData = async () => {
try {
const value = await AsyncStorage.getItem('myKey');
if (value !== null) {
console.log('myKey from storage:', value);
setMyKey(value);
}
} catch (e) {
console.log('Failed to fetch the data from storage:', e);
}
};

const switchCamera = () => {
localStream.getVideoTracks().forEach(track => track._switchCamera());
console.log('localStream.getVideoTracks()', localStream.getVideoTracks());
};
const switchAudio = () => {
localStream.getAudioTracks().forEach(track => {
track.enabled = !isMuted;
});
setIsMuted(!isMuted);
console.log('ismuted', isMuted);
console.log('localStream.audio()', localStream.getAudioTracks());
};
const setupWebrtc = async () => {
pc.current = new RTCPeerConnection(configuration);
console.log(' origin current: ', pc.current);

// Get the audio and video stream for the call
const stream = await getStream();
console.log('stream in setup', stream);
if (stream) {
  setLocalStream(stream);
  console.log(' t3addet el localstream ');
  stream.getTracks().forEach(track => {
    pc.current.addTrack(track, stream);
  });
}
// Get the remote stream once it is available
console.log(' pc.current.ontrack ', pc.current.ontrack);

pc.current.ontrack = event => {
  console.log('event.stream', event.streams);
  setRemoteStream(event.streams[0]);
  console.log('event.streams[0]', event.streams[0]);
};

};
const create = async () => {
connecting.current = true;
console.log('create');
// setup webrtc

await setupWebrtc();

// Document for the call
const cRef = firestore()
  .collection('signaling')
  .doc('peers')
  .collection('keys');
collectIceCandidates(cRef, myKey, peerKey);
// Exchange the ICE candidates between the caller and callee
if (pc.current) {
  console.log('pc.current', pc.current);
  // Create the offer for the call
  // Store the offer under the document
  const offer = await pc.current.createOffer();

  // Store the offer under the document
  await cRef.doc(myKey).set({offer});

  // Set the offer as the local description
  await pc.current.setLocalDescription(offer);

  console.log('Local description set:', pc.current.localDescription);

  console.log('cRef setted ');
}

};
const join = async () => {
console.log('Joining call');
connecting.current = true;
setGettingCall(false);

const cRef = firestore()
  .collection('signaling')
  .doc('peers')
  .collection('keys')
  .doc(myKey);

const offerSnapshot = await cRef.get();
const offer = offerSnapshot.data().offer;
//console.log('offer ', offer);
if (offer) {
  // setup webrtc
  await setupWebrtc();

  // Exchange the ICE candidate
  // check the parameters, it's reversed. since joining part is callee
  collectIceCandidates(cRef, peerKey, myKey);
  if (pc.current) {
    pc.current.setRemoteDescription(new RTCSessionDescription(offer));

    // Create the answer for the call
    // Update the document with answer
    const cRef = firestore()
      .collection('signaling')
      .doc('peers')
      .collection('keys')
      .doc(peerKey);

    const answer = await pc.current.createAnswer();
    console.log('answer answer answer', answer);
    pc.current.setLocalDescription(answer);
    const cWithAnswer = {
      answer: {
        type: answer.type,
        sdp: answer.sdp,
      },
    };
    cRef.update(cWithAnswer);
  }
}

};
/**

    For disconnecting the call close the connection, release the stream
    And delete the document for the call
    */

const hangup = async () => {
setGettingCall(false);
connecting.current = false;
streamCleanUp();
//firestoreCleanUp();
if (pc.current) {
pc.current.close();
}
};

// Helper function
const streamCleanUp = async () => {
if (localStream) {
localStream.getTracks().forEach(t => t.stop());
localStream.release();
}
setLocalStream(null);
setRemoteStream(null);
};

const firestoreCleanUp = async () => {
const cRef = firestore()
.collection('signaling')
.doc('peers')
.collection('keys');

if (cRef) {
  const myDocRef = cRef.doc(myKey);
  const myDocSnapshot = await myDocRef.get();
  if (myDocSnapshot.exists && myDocSnapshot.get(peerKey)) {
    await myDocRef.update({
      [peerKey]: firestore.FieldValue.delete(),
      offer: firestore.FieldValue.delete(),
    });
  }
}

const peerDocRef = cRef.doc(peerKey);
const peerDocSnapshot = await peerDocRef.get();
if (
  peerDocSnapshot.exists
  // && peerDocSnapshot.get(answer)
) {
  await peerDocRef.update({
    answer: firestore.FieldValue.delete(),
  });
}

};
const collectIceCandidates = async (cRef, localName, remoteName) => {
const candidateDocRef = cRef.doc(localName);
console.log('candidateDocRef', candidateDocRef);
if (pc.current) {
// on new ICE candidate add it to firestore
console.log('pc.current candidateDocRef', pc.current.onicecandidate);
pc.current.onicecandidate = async event => {
if (event.candidate) {
console.log('event.candidate', event.candidate);
await candidateDocRef.update({
[remoteName]: firestore.FieldValue.arrayUnion(
event.candidate.toJSON(),
),
});
}
console.log('base donne updated');
};
}

// Get the ICE candidates added to firestore and update the local pc
const candidateCollectionRef = cRef.doc(localName);
console.log('second fct collectIce');
candidateCollectionRef.onSnapshot(snapshot => {
  console.log('second fct collectIce snapshot');

  const candidates = snapshot.data();
  console.log('candidates', candidates);
  if (candidates && candidates[remoteName]) {
    candidates[remoteName].forEach(candidateData => {
      console.log('te7t candidates remote');
      const candidate = new RTCIceCandidate(candidateData);
      console.log('candidate candidate', candidate);
      pc.current
        .addIceCandidate(candidate)
        .then(() => console.log('Ice candidate added successfully!'))
        .catch(error =>
          console.error('Failed to add ice candidate:', error),
        );
    });
  }
});

};

在这里输入




Thanks in advance

Any help would be appreciated
react-native webrtc react-native-webrtc
© www.soinside.com 2019 - 2024. All rights reserved.