I'm currently working with react-native-webrtc in our project, and I'm facing an issue where the remote user's stream is not showing on the screen. scenario -
- I’m able to successfully access and display my local stream.
- However, when a remote user joins the room and sends their stream, it’s not appearing on the screen.
This is my code -
import { RTCPeerConnection, RTCView, mediaDevices } from 'react-native-webrtc';
const socket = io('http://MyIpAddress:3000');
export default function MeetingApp() {
const [isHost, setIsHost] = useState(false);
const [remoteStreams, setRemoteStreams] = useState([]);
const [peerConnections, setPeerConnections] = useState({});
const ROOM_ID = '8888';
const localStream = useRef(null);
const peerConnectionsRef = useRef({});
useEffect(() => {
const getLocalStream = async () => {
try {
const stream = await mediaDevices.getUserMedia({
audio: true,
video: { facingMode: 'user' },
});
localStream.current = stream;
} catch (error) {
console.error('Error getting local media:', error);
Alert.alert('Error', 'Unable to access camera or microphone');
}
};
getLocalStream();
return () => {
if (localStream.current) {
localStream.current.getTracks().forEach((track) => track.stop());
}
};
}, []);
const initPeerConnection = (socketId) => {
console.log("Initializing peer connection for socket ID:", socketId);
const peer = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
});
console.log("Created new RTCPeerConnection:", peer);
peer.onicecandidate = (event) => {
console.log("ICE candidate event:", event);
if (event.candidate) {
socket.emit('sendIceCandidate', { roomId: ROOM_ID, candidate: event.candidate, socketId });
}
};
peer.ontrack = (event) => {
console.log("Received remote track:", event);
setRemoteStreams((prevStreams) => {
const newStreams = [
...prevStreams.filter((stream) => stream.id !== event.streams[0].id),
event.streams[0],
];
console.log("Updated remote streams:", newStreams);
return newStreams;
});
};
peer.addEventListener( 'connectionstatechange', e => {
console.log( 'Peer Connection : Connection State Change ->', pc.connectionState );
} );
if (localStream.current) {
console.log("Adding local tracks to peer connection");
localStream.current.getTracks().forEach((track) => peer.addTrack(track, localStream.current));
} else {
console.log("Local stream not available yet");
}
console.log("Storing peer connection in ref object");
peerConnectionsRef.current[socketId] = peer;
setPeerConnections((prevConnections) => {
console.log("Updating peerConnections state");
const updatedConnections = {
...prevConnections,
[socketId]: peer,
};
console.log("Updated peer connections:", updatedConnections);
return updatedConnections;
});
};
const createRoom = () => {
socket.emit('joinRoom', { roomId: ROOM_ID }, (response) => {
if (response.error) {
Alert.alert('Error', response.error);
} else {
setIsHost(true);
initPeerConnection(socket.id);
Alert.alert('Room Created', `You are the host of room ID: ${ROOM_ID}`);
}
});
};
const joinRoom = () => {
socket.emit('joinRoom', { roomId: ROOM_ID }, (response) => {
if (response.error) {
Alert.alert('Error', response.error);
} else {
setIsHost(false);
initPeerConnection(socket.id);
Alert.alert('Joined Room', `You have successfully joined room: ${ROOM_ID}`);
}
});
};
const sendOffer = async () => {
const peer = peerConnectionsRef.current[socket.id];
if (!peer) return;
const offer = await peer.createOffer();
await peer.setLocalDescription(offer);
socket.emit('sendOffer', { roomId: ROOM_ID, offer, socketId: socket.id });
};
const sendAnswer = async (socketId, offer) => {
const peer = peerConnectionsRef.current[socketId];
if (!peer) return;
await peer.setRemoteDescription(new RTCSessionDescription(offer));
const answer = await peer.createAnswer();
await peer.setLocalDescription(answer);
socket.emit('sendAnswer', { roomId: ROOM_ID, answer, socketId });
};
useEffect(() => {
socket.on('receiveOffer', async ({ offer, socketId }) => {
sendAnswer(socketId, offer);
});
socket.on('receiveAnswer', async ({ answer, socketId }) => {
const peer = peerConnectionsRef.current[socketId];
if (peer) {
await peer.setRemoteDescription(new RTCSessionDescription(answer));
}
});
socket.on('receiveIceCandidate', ({ candidate, socketId }) => {
const peer = peerConnectionsRef.current[socketId];
if (peer) {
peer.addIceCandidate(new RTCIceCandidate(candidate));
}
});
return () => {
socket.off('receiveOffer');
socket.off('receiveAnswer');
socket.off('receiveIceCandidate');
};
}, []);