ααΌα
ααααα
αααααααααΎαααΉααα·ααΆαα’αααΈ WebRTC α
Web Real-Time Communication (WebRTC) αα·ααααααΆαα·ααΈααΆααααα½ααα ααΆααΊααΆααααα»αααΆααααΌααααααααααΆα αα·ααΈααΆα αα·α JavaScript APIs ααααα½αααααΆαααααααΌαααΆαααααΆααααααααΆαααΈααα’αΌ-α’αΌααΈαααΌααΆααααααααΆααΆαααααααααΈααααΆαα αα·ααα αα α αΎαααα’αΆα ααααΎααΎααααΈαααααααΆαα½ααααααα αα·αααααααααααΈαα ααΆααααααΆαααααα·ααΈαα»αααααΎααα½ααΆααΈααΆαα·ααααααααα· ααα»ααααααΆααα’αΆα ααΆαααααα·ααΈααΌαααααααααααα ααΎααααΈαααα αααααΆαααααα p2p αααΆαα’αα·αα·αα ααΆαααΆαααααααααα·ααΈαα»αααααΆαα’ααΈαααΊαα·ααααααΆααααααααααααααααααΆαα’αα·αααΌαααΈααα’αΌ αα·αα’αΌααΈαααΌααΊααααΌαααΆαααΆαααΆα ααΆαααΆαααααααααΆαααα·ααΈααΆααααααΆααααααα ααΆααΆααΌαα’αααααααααααααααααΉαααΆαα½ααααααα·ααΈαα»αααααΆαα’ααΈαααΊαα·α (ααΆαααααααααΆαα OS)α ααΆαααααΆαααααΆα ααΆαααα‘ααα αα αα αααα·ααααΆ hodgepodge ααΆααα’αααααααααΌαααΆαααΆαααα ααΈααααα JavaScript API abstraction αααααΆααααΆαααΆααααα½αααααα’αααα’αα·ααααααα
ααΆααΆααα’ααααααΆααα α»αααα APIs ααΈ:
-
MediaStream API - αα»αααΎααΎααα»α ααααααααααα»αααΉαααααααααααααααα’αααΈααΆααα αααααΎααΎααααΈααα½αααααααΈαααΈααα’αΌ / α’αΌααΈαααΌααΈαααααααΉα -
RTCPeerConnection - αααααααΆαααααΆαααααααααΆαα’αα·αα·ααααΈαααΆαα (p2p) -
ααΆααα RTCData - αααααΎααΎααααΈααααααα·ααααααααααΆααααΆαα’αα·αα·ααααΈαααΆαα
αααα»ααααα αααααααΈαα’αΌααΈαααΌ αα·αααΈααα’αΌαααααΆααααΆααααααΌα
ααΆααΆααα’ααα αΆααααααΎαααΆαα½α "α αΆαααα" αααααΆαααΆαααααΆ αα·αααΈααααΌα αααΌαααααααΈαααααα ααΆααΆααα·αααΆαα ααΆαααααααΈααα αα·ααααααα·αααααααΆααααΆααααα αααααα·ααΈαααΌαααααΆαααααα ααααααΈαααΈαα½ααααααΌαααααΎαααΆαα ααααΎα’αααααααΎαα‘αΎαααΌααα»αααΆα ααααΎααααΆαααααα’αΌααΈαααΌααΆαα½αααΈααα’αΌ ααΆαααααααΆαααααΆααααΆαααααΎααααΆααααααα αααα»αααααααΈαααΈααα’αΌ αα·αααΆααΆααΆαααΌαα’ααααΆαααΈααααααααΌαααααΆαα ααΉαααααα·ααααααΌααααααααΆααααααΌαα₯ααααααααααααα»αααα·αα . αααααα·ααΈαα»αααααα α·ααααα»αααΆααααΎα’αααΈαααΆααα’ααααα α’αααα’αα·αααααααα·αα αΆαααΆα ααααα½αααΆααααα’αααΈααΆααααααααΆαα’αα·αααΌααααααΆααααααααΈαααααααα αα ααΆααααα»ααααααα·ααΈαα»αααααΆαα’ααΈαααΊαα·αααααΎα ααΆααααααΆαααααααα·ααΈαα½α α αΎααααααΆααααΆαα αΆαααα ααΆααααααα’αα»αααΆα (αα»αααα‘αα αα·αααα‘ααα ααααΈααα‘αα αααααα’ααΌαααΆα) ααΆαα’αα·αααΌαααΈααα’αΌ αα·αααα‘ααα αααααααΆααααααααΆααααααΌαααΆααααα αΆααα αααα»αααΌαααα 1:
α’ααααα 1. αααααΆααααααααΎαααΆαα’αΌααΈαααΌ αα·αααΈααα’αΌαα αααα»ααααααα·ααΈαα»ααα
ααααΎαααΆαααΆααα’ααααΎαα‘αΎααααααααΆαααα
αααα»ααααααα·ααΈαα»αααααααααα½αα―α αα·αααΆαααααααααα αα·αααααΌαααΆααααααα·ααΈαααα½αααα ααααααΆαααΆααααα α’αααΈααα
αααα·αααΆαααΆαααααααΎααααααΆααααααΆα α’α α’α α ααΆααααααα·ααΈαα»αααααααα·αααΆααααΆαααααααααα
α’αααα’αΆα ααααΎα’αααΈααααα½αα±ααα αΆααα’αΆααααααααΆαα½αααΉαααααααΈααααααα½αααΆαα α’αααα’αΆα ααααΌα ααααΆααααααΌααα»αααΆααααα αΆαααΈααα’αΌ αααα ααα»αααΆαααα‘αα α’αααα’αΆα αα αα·α "ααααΆαα" ααααααΈααααααα tag α αΎαααΎααααα½αα―ααα ααΎααααα html α α¬α’αααα’αΆα ααΌαααααααΈααα ααΎααααΆαααααααΆαα α αΎαααααα WebGL α¬ CSS3 α αΎαα’αα»ααααααααααααααααα ααΈααα’αΌ α αΆααααααΈααα’αΌαααααΆαααααΎαααΆαααΈααααΆαααααααΆαα α αΎααααααΆααααααααΎααΆααΆααααααΆααα αααΆαααΈααα ααααααααΌα αα·αααααααααααΆααααα’ααααααααααααΆ (ααααΆααα½α bigo live, twitch α αΎαβαααααααα)α αα ααΈααααααα»αααΉααα·ααα·ααΆαααΈαααααααααΏααααααααΌαααΆαααααΎααααα αααα»αααΉααααααα§ααΆα ααααα½αα ααα½ααααααΆααα ααΎααα αααααα
RTCPeerConnection
ααΌα
ααααβααΎαβααΆαβααΆαβαααβα
ααα»α
ααα»ααααβααΎβααααΎβααΌα
ααααα
βααΎααααΈβαααααβααΈααα’αΌβαα
βα’αααβααααΎβαααααβαααβ? αααααααΆααα»α
const peerConnection = new RTCPeerConnection({
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}]
});
ααΎααααααΆαα iceServers ααΆαααααΎααα½ααααα»αα αααααααααΎα - αααααΊααΆ server ααααα½ααααααααΆααααααΆαααααΆα browsers ααΈααα ααΈααααα NAT'omα αααααΊαααα αΆααααΌαααΆααααααααΆααα ααΈαααα ααααααααααα ip αα interlocutor ααααα·αααΎααΆαααα ααΈααααα NAT ααααα’ααααααααααααΆααααααΆαα? αα·ααΈααΆα ICE αααα½ααααααααα ααΆααα·α ICE αα·αα’αα»ααααα αααα WebRTC ααΆααααααα ααα»ααααααΆαα αααΎαααααα ααααααααα
ααΆαααΈαα»α ααΎαααα½αααΆαααααααΈα Usermediaα
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => {
// Usermedia-ΠΏΠΎΡΠΎΠΊΠΈ, ΠΎΠ±ΡΡΠ½ΠΎ ΡΡΠΎ Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡΠ΄ΠΈΠΎ
const tracks = stream.getTracks();
for (const track of tracks) {
// ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΡΠ΅ΠΊ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅ΠΌ ΠΊ peerConnection
peerConnection.addTrack(track);
}
}).catch(console.error);
αααααΆαααα ααααΉαααα·ααΆααααααααααΌαα αα αΆααΉαα αΆααααααΎααα ααΎ peerConnection αα αααα»αα§ααααααααααααΆααααααΎαααααΌααααααΎαααΆααααααααΌα (αα αααα»ααααααααααα SDP - Session Description Protocol) α αΎαααααααααΆαα peerConnection ααΆαααααα·ααΈ setLocalDescription α α’αααΈ SDP - ααΎααΆααΆα’αααΈ αα·αα’αααΈααΆααααααααΌα αα·αααααααα ααααΎα - ααΎαααΉααα·ααΆααααααααααα
αααααΆααααΈααααα LocalDescription peerConnection αααααα·ααΈαα»ααα "αααααΌααααα»α" αααααααααΉααα αααααΊααααααααα·ααΈααααααααΎααααΈααααΆααααααααΆαααα NAT α ααααΉαααα·ααΆαααβααααΆααααααΌαβααααβααΆαβααΆααααα αα αααα»α onicegatheringstatechange handler ααΎαα’αα»ααααΆαα±ααααααΆαααα αααααΆα webrtc-signaling-server stream ααΎααααΈααααΆααααααΌα Session Description αααΆααα·αααααααα·α
peerConnection.oniceconnectionstatechange = (event) => {
console.log('Connection state: ', peerConnection.iceConnectionState);
if (peerConnection.iceConnectionState === 'connected') {
// ΠΠΎΠΆΠ΅ΠΌ Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠ½ΠΎΠΏΠΊΡ Start broadcast
setBroadcasting(true);
setBroadcastingBtnActive(true);
}
};
// Π‘ΠΎΠ±ΡΡΠΈΠ΅ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΡΡΠ°Π·Ρ, ΠΊΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΡΡ ΠΌΠ΅Π΄Π°ΠΈΠ°ΠΏΠΎΡΠΎΠΊ Π² peerConnection
peerConnection.onnegotiationneeded = (event) => {
// Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΈ Π½Π°Π·Π½Π°ΡΠ°Π΅ΠΌ SDP offer
peerConnection.createOffer().
then((offer) => peerConnection.setLocalDescription(offer)).
catch(console.error);
};
// Π‘ΠΎΠ±ΡΡΠΈΠ΅ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠ°ΠΊ ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ ICE ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ
peerConnection.onicegatheringstatechange = (ev) => {
let connection = ev.target;
// Now we can activate broadcast button
if (connection.iceGatheringState === 'complete') {
let delay = 50;
let tries = 0;
let maxTries = 3;
let timerId = setTimeout(function allowStreaming() {
if (isOnline) {
setBroadcastingBtnActive(true);
return;
}
if (tries < maxTries) {
tries += 1;
delay *= 2;
timerId = setTimeout(allowStreaming, delay);
} else {
// TODO: show user notification
console.error("Can't connect to server");
alert("Can't connect to server");
}
}, delay);
}
};
webrtc-signaling-server ααΊααΆαααΆαααΈααααααααααΌαααΆαααΎααααΈααααΆααααααΌαααΆααααααΆαααααααΆααα·αααααααα·ααΈαααΆαα ααΆα’αΆα ααΆ websocket α¬ xhr-server ααΆαααααααα»ααα ααΎ PL ααΆαα½αα ααΆααα·α αα ααααααΆααΊααΆααααα ααΎααααΈααα½αααααΆααα·αααααΆααααααΈαα·ααααααααα·αα½α α αΎααααααααΆαα αα½ααααα
αααααΆααααΈααΆαααααΆααααααΌαααΆααα·αααααΆαααα ααΆααΈααΆααααααΆαααααααααα½αααΆααααα ααΎααααΈα αΆααααααΆα αα·αααα½αααΆαααααΆαααΈααα’αΌ αα ααααααααααα½αααΆαααααΆαααΈααα’αΌ ααααΉαααα·ααΆααααα ααΎααααΌαααααΌαααΆαααααα ααΎ peerConnection αα αααα»αα§ααααααααααααΆαααααααααααα½αααΆαα’αΆα ααααΌαααΆαααααααα α αΎαααΎαα’αααααααΆαααααααΆαααααααα’αααα αΌαα α·αααα ααααΉααααΈ αα·αααααααΆααααα’α·αααααααα
αααααααΆαα αα·αα’αααααα·ααααα
αα ααααααααααΆαα αααα»αα αααααααααααααα½ααααααααααααααααΉααααΈ αα·ααααα»αααΆαα’αα»αααα ααΎααααΈαα·ααΆαααΆαααα½α αα·αααααΎαααΆαααΆαααααΆαααΈααα’αΌαα ααΎαααΆαααΈααααααααααΎ pion ααααααααα ααΆ HLS ααΆαααα ffmpeg αααααΆααααΆαααααΆαααΆαααααααααΆαααα ααΆααα’αααααΎααα αααα»ααααααα·ααΈαα»αααα
αααααΆααα’ααααα·αα
ααα’αααααααα
ααααα: www.habr.com