-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
176 lines (142 loc) · 5.2 KB
/
main.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//Alojamiento del servidor
const firebaseConfig = {
apiKey: "AIzaSyBb88F6ViZawLmOiOGdy20l9JM25annP5M",
authDomain: "webrtc---js.firebaseapp.com",
projectId: "webrtc---js",
storageBucket: "webrtc---js.appspot.com",
messagingSenderId: "1065536759484",
appId: "1:1065536759484:web:d08055c6aef1d6b7d992b9",
measurementId: "G-3K9F5FT88T"
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
const firestore = firebase.firestore();
const servers = {
iceServers: [
{
urls: ['stun:stun1.l.google.com:19302', 'stun:stun2.l.google.com:19302'],
},
],
iceCandidatePoolSize: 10,
};
// Estado Global
const pc = new RTCPeerConnection(servers);
let localStream = null;
let remoteStream = null;
// Elementos HTML
const webcamButton = document.getElementById('webcamButton');
const webcamVideo = document.getElementById('webcamVideo');
const callButton = document.getElementById('callButton');
const callInput = document.getElementById('callInput');
const answerButton = document.getElementById('answerButton');
const remoteVideo = document.getElementById('remoteVideo');
const hangupButton = document.getElementById('hangupButton');
// 1. Establece video y audio
webcamButton.onclick = async () => {
localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
remoteStream = new MediaStream();
// Agregar las pistas de la transmisión local a la conexión peer-to-peer (PC)
localStream.getTracks().forEach((track) => {
pc.addTrack(track, localStream);
});
// Manejar el video recibidas de la transmisión remota y agregarlas a la transmisión remota
pc.ontrack = (event) => {
event.streams[0].getTracks().forEach((track) => {
remoteStream.addTrack(track);
});
};
// Establecer la fuente del video de la webcam al stream local
webcamVideo.srcObject = localStream;
// Establecer la fuente del video remoto al stream remoto
remoteVideo.srcObject = remoteStream;
// Habilitar los botones de llamada, respuesta y cuelgue
callButton.disabled = false;
answerButton.disabled = false;
webcamButton.disabled = true;
hangupButton.disabled = false;
};
// 2.
callButton.onclick = async () => {
//Referencias para Firestore
const callDoc = firestore.collection('calls').doc();
const offerCandidates = callDoc.collection('offerCandidates');
const answerCandidates = callDoc.collection('answerCandidates');
callInput.value = callDoc.id;
// Obtiene datos para el que llama, se guarda en la BD
pc.onicecandidate = (event) => {
event.candidate && offerCandidates.add(event.candidate.toJSON());
};
// Crear oferta
const offerDescription = await pc.createOffer();
await pc.setLocalDescription(offerDescription);
const offer = {
sdp: offerDescription.sdp,
type: offerDescription.type,
};
await callDoc.set({ offer });
// Escuchar por la respuesta remota
callDoc.onSnapshot((snapshot) => {
const data = snapshot.data();
if (!pc.currentRemoteDescription && data?.answer) {
const answerDescription = new RTCSessionDescription(data.answer);
pc.setRemoteDescription(answerDescription);
}
});
// Cuando se responda, agregar el candidato a la conexión entre pares
answerCandidates.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === 'added') {
const candidate = new RTCIceCandidate(change.doc.data());
pc.addIceCandidate(candidate);
}
});
});
};
// 3. Responder llamada con un ID unico
answerButton.onclick = async () => {
const callId = callInput.value;
const callDoc = firestore.collection('calls').doc(callId);
const answerCandidates = callDoc.collection('answerCandidates');
const offerCandidates = callDoc.collection('offerCandidates');
pc.onicecandidate = (event) => {
event.candidate && answerCandidates.add(event.candidate.toJSON());
};
const callData = (await callDoc.get()).data();
const offerDescription = callData.offer;
await pc.setRemoteDescription(new RTCSessionDescription(offerDescription));
const answerDescription = await pc.createAnswer();
await pc.setLocalDescription(answerDescription);
const answer = {
type: answerDescription.type,
sdp: answerDescription.sdp,
};
await callDoc.update({ answer });
offerCandidates.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
console.log(change);
if (change.type === 'added') {
let data = change.doc.data();
pc.addIceCandidate(new RTCIceCandidate(data));
}
});
});
};
// 4. Finalizar llamada
hangupButton.onclick = () => {
// Cierra peer conection
pc.close();
// Resetea streams
localStream.getTracks().forEach(track => track.stop());
localStream = null;
remoteStream.getTracks().forEach(track => track.stop());
remoteStream = null;
// Resetea elementos de video
webcamVideo.srcObject = null;
remoteVideo.srcObject = null;
// Activa/Desactiva videos
webcamButton.disabled = false;
callButton.disabled = true;
answerButton.disabled = true;
hangupButton.disabled = true;
};