Created
August 28, 2020 16:26
-
-
Save DipanshKhandelwal/0fda05af19ce1f8d03d8e37913c40457 to your computer and use it in GitHub Desktop.
WebRTC Tutorial : JoinScreen.js :: https://github.com/DipanshKhandelwal/react-native-webrtc-firebase/blob/master/src/screens/JoinScreen.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from 'react'; | |
import { Text, StyleSheet, Button, View } from 'react-native'; | |
import { RTCPeerConnection, RTCView, mediaDevices, RTCIceCandidate, RTCSessionDescription } from 'react-native-webrtc'; | |
import { db } from '../utilities/firebase'; | |
const configuration = { | |
iceServers: [ | |
{ | |
urls: ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'], | |
}, | |
], | |
iceCandidatePoolSize: 10, | |
}; | |
export default function JoinScreen({ setScreen, screens, roomId }) { | |
function onBackPress() { | |
if (cachedLocalPC) { | |
cachedLocalPC.removeStream(localStream); | |
cachedLocalPC.close(); | |
} | |
setLocalStream(); | |
setRemoteStream(); | |
setCachedLocalPC(); | |
// cleanup | |
setScreen(screens.ROOM); | |
} | |
const [localStream, setLocalStream] = useState(); | |
const [remoteStream, setRemoteStream] = useState(); | |
const [cachedLocalPC, setCachedLocalPC] = useState(); | |
const [isMuted, setIsMuted] = useState(false); | |
useEffect(() => { | |
// startLocalStream(); | |
}, []); | |
const startLocalStream = async () => { | |
// isFront will determine if the initial camera should face user or environment | |
const isFront = true; | |
const devices = await mediaDevices.enumerateDevices(); | |
const facing = isFront ? 'front' : 'environment'; | |
const videoSourceId = devices.find(device => device.kind === 'videoinput' && device.facing === facing); | |
const facingMode = isFront ? 'user' : 'environment'; | |
const constraints = { | |
audio: true, | |
video: { | |
mandatory: { | |
minWidth: 500, // Provide your own width, height and frame rate here | |
minHeight: 300, | |
minFrameRate: 30, | |
}, | |
facingMode, | |
optional: videoSourceId ? [{ sourceId: videoSourceId }] : [], | |
}, | |
}; | |
const newStream = await mediaDevices.getUserMedia(constraints); | |
setLocalStream(newStream); | |
}; | |
const joinCall = async id => { | |
const roomRef = await db.collection('rooms').doc(id); | |
const roomSnapshot = await roomRef.get(); | |
if (!roomSnapshot.exists) return | |
const localPC = new RTCPeerConnection(configuration); | |
localPC.addStream(localStream); | |
const calleeCandidatesCollection = roomRef.collection('calleeCandidates'); | |
localPC.onicecandidate = e => { | |
if (!e.candidate) { | |
console.log('Got final candidate!'); | |
return; | |
} | |
calleeCandidatesCollection.add(e.candidate.toJSON()); | |
}; | |
localPC.onaddstream = e => { | |
if (e.stream && remoteStream !== e.stream) { | |
console.log('RemotePC received the stream join', e.stream); | |
setRemoteStream(e.stream); | |
} | |
}; | |
const offer = roomSnapshot.data().offer; | |
await localPC.setRemoteDescription(new RTCSessionDescription(offer)); | |
const answer = await localPC.createAnswer(); | |
await localPC.setLocalDescription(answer); | |
const roomWithAnswer = { answer }; | |
await roomRef.update(roomWithAnswer); | |
roomRef.collection('callerCandidates').onSnapshot(snapshot => { | |
snapshot.docChanges().forEach(async change => { | |
if (change.type === 'added') { | |
let data = change.doc.data(); | |
await localPC.addIceCandidate(new RTCIceCandidate(data)); | |
} | |
}); | |
}); | |
setCachedLocalPC(localPC); | |
}; | |
const switchCamera = () => { | |
localStream.getVideoTracks().forEach(track => track._switchCamera()); | |
}; | |
// Mutes the local's outgoing audio | |
const toggleMute = () => { | |
if (!remoteStream) { | |
return; | |
} | |
localStream.getAudioTracks().forEach(track => { | |
// console.log(track.enabled ? 'muting' : 'unmuting', ' local track', track); | |
track.enabled = !track.enabled; | |
setIsMuted(!track.enabled); | |
}); | |
}; | |
return ( | |
<> | |
<Text style={styles.heading} >Join Screen</Text> | |
<Text style={styles.heading} >Room : {roomId}</Text> | |
<View style={styles.callButtons} > | |
<View styles={styles.buttonContainer} > | |
<Button title="Click to stop call" onPress={onBackPress} /> | |
</View> | |
<View styles={styles.buttonContainer} > | |
{!localStream && <Button title='Click to start stream' onPress={startLocalStream} />} | |
{localStream && <Button title='Click to join call' onPress={() => joinCall(roomId)} disabled={!!remoteStream} />} | |
</View> | |
</View> | |
{localStream && ( | |
<View style={styles.toggleButtons}> | |
<Button title='Switch camera' onPress={switchCamera} /> | |
<Button title={`${isMuted ? 'Unmute' : 'Mute'} stream`} onPress={toggleMute} disabled={!remoteStream} /> | |
</View> | |
)} | |
<View style={{ display: 'flex', flex: 1, padding: 10 }} > | |
<View style={styles.rtcview}> | |
{localStream && <RTCView style={styles.rtc} streamURL={localStream && localStream.toURL()} />} | |
</View> | |
<View style={styles.rtcview}> | |
{remoteStream && <RTCView style={styles.rtc} streamURL={remoteStream && remoteStream.toURL()} />} | |
</View> | |
</View> | |
</> | |
) | |
} | |
const styles = StyleSheet.create({ | |
heading: { | |
alignSelf: 'center', | |
fontSize: 30, | |
}, | |
rtcview: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center', | |
backgroundColor: 'black', | |
margin: 5, | |
}, | |
rtc: { | |
flex: 1, | |
width: '100%', | |
height: '100%', | |
}, | |
toggleButtons: { | |
width: '100%', | |
flexDirection: 'row', | |
justifyContent: 'space-around', | |
}, | |
callButtons: { | |
padding: 10, | |
width: '100%', | |
flexDirection: 'row', | |
justifyContent: 'space-around', | |
}, | |
buttonContainer: { | |
margin: 5, | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment