forked from robertbunch/webrtc-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscripts.js
156 lines (135 loc) · 5.46 KB
/
scripts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const userName = "Rob-"+Math.floor(Math.random() * 100000)
const password = "x";
document.querySelector('#user-name').innerHTML = userName;
//if trying it on a phone, use this instead...
// const socket = io.connect('https://LOCAL-DEV-IP-HERE:8181/',{
const socket = io.connect('https://localhost:8181/',{
auth: {
userName,password
}
})
const localVideoEl = document.querySelector('#local-video');
const remoteVideoEl = document.querySelector('#remote-video');
let localStream; //a var to hold the local video stream
let remoteStream; //a var to hold the remote video stream
let peerConnection; //the peerConnection that the two clients use to talk
let didIOffer = false;
let peerConfiguration = {
iceServers:[
{
urls:[
'stun:stun.l.google.com:19302',
'stun:stun1.l.google.com:19302'
]
}
]
}
//when a client initiates a call
const call = async e=>{
await fetchUserMedia();
//peerConnection is all set with our STUN servers sent over
await createPeerConnection();
//create offer time!
try{
console.log("Creating offer...")
const offer = await peerConnection.createOffer();
console.log(offer);
peerConnection.setLocalDescription(offer);
didIOffer = true;
socket.emit('newOffer',offer); //send offer to signalingServer
}catch(err){
console.log(err)
}
}
const answerOffer = async(offerObj)=>{
await fetchUserMedia()
await createPeerConnection(offerObj);
const answer = await peerConnection.createAnswer({}); //just to make the docs happy
await peerConnection.setLocalDescription(answer); //this is CLIENT2, and CLIENT2 uses the answer as the localDesc
console.log(offerObj)
console.log(answer)
// console.log(peerConnection.signalingState) //should be have-local-pranswer because CLIENT2 has set its local desc to it's answer (but it won't be)
//add the answer to the offerObj so the server knows which offer this is related to
offerObj.answer = answer
//emit the answer to the signaling server, so it can emit to CLIENT1
//expect a response from the server with the already existing ICE candidates
const offerIceCandidates = await socket.emitWithAck('newAnswer',offerObj)
offerIceCandidates.forEach(c=>{
peerConnection.addIceCandidate(c);
console.log("======Added Ice Candidate======")
})
console.log(offerIceCandidates)
}
const addAnswer = async(offerObj)=>{
//addAnswer is called in socketListeners when an answerResponse is emitted.
//at this point, the offer and answer have been exchanged!
//now CLIENT1 needs to set the remote
await peerConnection.setRemoteDescription(offerObj.answer)
// console.log(peerConnection.signalingState)
}
const fetchUserMedia = ()=>{
return new Promise(async(resolve, reject)=>{
try{
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
// audio: true,
});
localVideoEl.srcObject = stream;
localStream = stream;
resolve();
}catch(err){
console.log(err);
reject()
}
})
}
const createPeerConnection = (offerObj)=>{
return new Promise(async(resolve, reject)=>{
//RTCPeerConnection is the thing that creates the connection
//we can pass a config object, and that config object can contain stun servers
//which will fetch us ICE candidates
peerConnection = await new RTCPeerConnection(peerConfiguration)
remoteStream = new MediaStream()
remoteVideoEl.srcObject = remoteStream;
localStream.getTracks().forEach(track=>{
//add localtracks so that they can be sent once the connection is established
peerConnection.addTrack(track,localStream);
})
peerConnection.addEventListener("signalingstatechange", (event) => {
console.log(event);
console.log(peerConnection.signalingState)
});
peerConnection.addEventListener('icecandidate',e=>{
console.log('........Ice candidate found!......')
console.log(e)
if(e.candidate){
socket.emit('sendIceCandidateToSignalingServer',{
iceCandidate: e.candidate,
iceUserName: userName,
didIOffer,
})
}
})
peerConnection.addEventListener('track',e=>{
console.log("Got a track from the other peer!! How excting")
console.log(e)
e.streams[0].getTracks().forEach(track=>{
remoteStream.addTrack(track,remoteStream);
console.log("Here's an exciting moment... fingers cross")
})
})
if(offerObj){
//this won't be set when called from call();
//will be set when we call from answerOffer()
// console.log(peerConnection.signalingState) //should be stable because no setDesc has been run yet
await peerConnection.setRemoteDescription(offerObj.offer)
// console.log(peerConnection.signalingState) //should be have-remote-offer, because client2 has setRemoteDesc on the offer
}
resolve();
})
}
const addNewIceCandidate = iceCandidate=>{
peerConnection.addIceCandidate(iceCandidate)
console.log("======Added Ice Candidate======")
}
document.querySelector('#call').addEventListener('click',call)