我正在尝试在react native上创建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',
}
});
您的代码有很多基本问题,我相信这不仅是候选问题。例如,每次组件重新渲染时,您都将创建一个新的套接字(因为使用)。我建议您改用Component类,并正确处理事件。另外,每次获得新的候选冰块时,您都在呼叫addStream
。只能添加一次(即最好在创建要约或答案之前)。我认为您应该检查WebRTC基础知识。请尝试以下链接。
https://webrtc.github.io/samples/src/content/peerconnection/pc1/
使用simple-peer可能是一个好主意,因为它简化了webrtc脚本。这是一个npm软件包,因此您可以在react中直接实现它。这是一个多用户调用PROJECT DEMO
的示例项目