ΠΡΠΊΠ°ΠΊ Π²
ΠΠ½Π΅Ρ ΡΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠΌ Π·Π° WebRTC.
Π£Π΅Π± ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡΡΠ° Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅ (WebRTC) Π½Π΅ Π΅ Π΅Π΄ΠΈΠ½ΠΈΡΠ΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ», Π° ΡΡΠ»Π° ΠΊΠΎΠ»Π΅ΠΊΡΠΈΡ ΠΎΡ ΡΡΠ°Π½Π΄Π°ΡΡΠΈ, ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ ΠΈ JavaScript API, ΠΊΠΎΠΈΡΠΎ Π·Π°Π΅Π΄Π½ΠΎ ΠΎΡΠΈΠ³ΡΡΡΠ²Π°Ρ peer-to-peer Π²ΠΈΠ΄Π΅ΠΎ-Π°ΡΠ΄ΠΈΠΎ ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ Π² ΡΠ΅Π°Π»Π½ΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΈ ΠΌΠΎΠ³Π°Ρ ΡΡΡΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ Π·Π° ΠΏΡΠ΅Ρ Π²ΡΡΠ»ΡΠ½Π΅ Π½Π° Π²ΡΡΠΊΠ°ΠΊΠ²ΠΈ Π΄Π²ΠΎΠΈΡΠ½ΠΈ Π΄Π°Π½Π½ΠΈ. ΠΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ Π±ΡΠ°ΡΠ·ΡΡΠΈΡΠ΅ Π΄Π΅ΠΉΡΡΠ²Π°Ρ ΠΊΠ°ΡΠΎ ΠΏΠ°ΡΡΠ½ΡΠΎΡΠΈ, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΈ ΠΌΠΎΠ±ΠΈΠ»Π½ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ. ΠΠ° Π΄Π° ΡΠ΅ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΈΡΠ° p2p ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠΈ, Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ° ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° Π½Π° Π±ΡΠ°ΡΠ·ΡΡΠ° Π·Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²ΠΈΠ΄ΠΎΠ²Π΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡΠ΄ΠΈΠΎ ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅, ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ° Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΡΠ΅ΠΆΠΎΠ²ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ, ΠΎΡΠΈΠ³ΡΡΡΠ²Π°ΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Ρ Π°ΡΠ΄ΡΠ΅ΡΠ° ΠΈ Π±ΡΠ°ΡΠ·ΡΡΠ° (ΡΡΠ΅Π· ΡΠ»ΠΎΠ΅Π²Π΅ Π½Π° ΠΠ‘): ΡΠ΅Π± ΠΊΠ°ΠΌΠ΅ΡΠΈ, Π·Π²ΡΠΊΠΎΠ²ΠΈ ΠΊΠ°ΡΡΠΈ. Π¦ΡΠ»Π°ΡΠ° ΡΠ°Π·ΠΈ ΡΠΌΠ΅ΡΠΈΡΠ° ΠΎΡ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π΅ ΡΠΊΡΠΈΡΠ° Π·Π°Π΄ JavaScript API Π°Π±ΡΡΡΠ°ΠΊΡΠΈΡΡΠ° Π·Π° ΡΠ΄ΠΎΠ±ΡΡΠ²ΠΎ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΡΠ°.
ΠΡΠΈΡΠΊΠΎ ΡΠ΅ ΡΠ²Π΅ΠΆΠ΄Π° Π΄ΠΎ ΡΡΠΈ API:
-
API Π½Π° MediaStream β Π΄Π΅ΠΌΠΎΠ½ΡΠΈΡΠ°Π½ ΠΌΠΈΠ½Π°Π»ΠΈΡ ΠΏΡΡ, Π΄Π½Π΅Ρ ΡΠ΅ ΠΏΠΈΡΠ° ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° Π½Π΅Π³ΠΎ. Π‘Π»ΡΠΆΠΈ Π·Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° Π²ΠΈΠ΄Π΅ΠΎ/Π°ΡΠ΄ΠΈΠΎ ΠΏΠΎΡΠΎΡΠΈ ΠΎΡ Ρ Π°ΡΠ΄ΡΠ΅ΡΠ° -
RTCPeer Π²ΡΡΠ·ΠΊΠ° β ΠΎΡΠΈΠ³ΡΡΡΠ²Π° ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ° (p2p) -
RTCDataChannel - ΡΠ»ΡΠΆΠΈ Π·Π° ΠΏΡΠ΅Ρ Π²ΡΡΠ»ΡΠ½Π΅ Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ Π΄Π°Π½Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²Π° ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ° Π½Π° Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΡΠΈ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅
ΠΡΠΈΡΠΊΠΎ Π·Π°ΠΏΠΎΡΠ²Π° Ρ βΡΠ»Π°Π²ΡΠ½Π΅ΡΠΎβ Π½Π° ΠΌΠ΅Π΄ΠΈΠΉΠ½ΠΈΡΠ΅ ΠΏΠΎΡΠΎΡΠΈ Π½Π° ΡΠ΅Π± ΠΊΠ°ΠΌΠ΅ΡΠ°ΡΠ° ΠΈ ΠΌΠΈΠΊΡΠΎΡΠΎΠ½Π°. Π Π°Π·Π±ΠΈΡΠ° ΡΠ΅, Π½Π΅ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½ΠΈΡΠ΅ ΠΏΠΎΡΠΎΡΠΈ Π½Π΅ ΡΠ° ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈ Π·Π° ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ΅Π»Π΅ΠΊΠΎΠ½ΡΠ΅ΡΠ΅Π½ΡΠΈΡ, Π²ΡΠ΅ΠΊΠΈ ΠΏΠΎΡΠΎΠΊ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½: ΠΏΠΎΠ΄ΠΎΠ±ΡΠ΅ΡΠ΅ ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎΡΠΎ, ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠ°ΠΉΡΠ΅ Π°ΡΠ΄ΠΈΠΎ Ρ Π²ΠΈΠ΄Π΅ΠΎ, ΠΏΠΎΡΡΠ°Π²Π΅ΡΠ΅ ΠΌΠ°ΡΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π·Π° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π²ΡΠ² Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΈ ΠΎΡΠΈΠ³ΡΡΠ΅ΡΠ΅ Π±ΠΈΡΡΠ΅ΠΉΡ, ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²Π°Ρ Π½Π° ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ ΠΏΡΠΎΠΌΠ΅Π½ΡΡΠ°ΡΠ° ΡΠ΅ ΡΠ΅ΡΡΠΎΡΠ½Π° Π»Π΅Π½ΡΠ° Π½Π° ΠΊΠ°Π½Π°Π»Π° . ΠΡΠ°ΡΠ·ΡΡΡΡ ΡΠ΅ Π³ΡΠΈΠΆΠΈ Π·Π° Π²ΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π°, ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡΡ Π΄ΠΎΡΠΈ Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΏΡΠΈΡΠ΅ΡΠ½ΡΠ²Π° Π·Π° ΠΎΡΠΈΠ³ΡΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π·Π° ΠΌΠ΅Π΄ΠΈΠΉΠ½ΠΈ ΠΏΠΎΡΠΎΡΠΈ. Π ΠΌΠΎΠ΄Π΅ΡΠ½ΠΈΡ Π±ΡΠ°ΡΠ·ΡΡ Π²Π΅ΡΠ΅ ΠΈΠΌΠ° ΡΠΎΡΡΡΠ΅ΡΠ½ΠΈ ΡΠ»ΠΎΠ΅Π²Π΅ Π·Π° Π·Π°ΡΠ½Π΅ΠΌΠ°Π½Π΅, ΠΏΠΎΠ΄ΠΎΠ±ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎΡΠΎ (ΠΏΡΠ΅ΠΌΠ°Ρ Π²Π°Π½Π΅ Π½Π° Π΅Ρ ΠΎΡΠΎ ΠΈ ΡΡΠΌΠ° ΠΎΡ Π·Π²ΡΠΊΠ°, ΠΏΠΎΠ΄ΠΎΠ±ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ°ΡΡΠΈΠ½Π°ΡΠ°), Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡΠ΄ΠΈΠΎ ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅. Π‘Ρ Π΅ΠΌΠ°ΡΠ° Π½Π° ΡΠ»ΠΎΠ΅Π²Π΅ΡΠ΅ Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π½Π° ΡΠΈΠ³. 1:
ΠΡΠΈΠ·. 1. Π‘Π»ΠΎΠ΅Π²Π΅ Π½Π° Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π² Π±ΡΠ°ΡΠ·ΡΡΠ°
Π¦ΡΠ»Π°ΡΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π² ΡΠ°ΠΌΠΈΡ Π±ΡΠ°ΡΠ·ΡΡ, Π±Π΅Π· Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ. Π½Π΅ ΡΠ° Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈ Π΄ΠΎΠ±Π°Π²ΠΊΠΈ. ΠΠ΅ΡΠ°ΡΠ° ΠΎΠ±Π°ΡΠ΅ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΠ° ΡΠΎΠ»ΠΊΠΎΠ²Π° ΡΠΎΠ·ΠΎΠ²ΠΈ Π·Π° 2020 Π³. ΠΠΌΠ° Π±ΡΠ°ΡΠ·ΡΡΠΈ, ΠΊΠΎΠΈΡΠΎ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Ρ Π½Π°ΠΏΡΠ»Π½ΠΎ
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠ°Π²ΠΈΡΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈ Π½Π΅ΡΠ° Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡΠ΅ ΠΏΠΎΡΠΎΡΠΈ: ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΊΠ»ΠΎΠ½ΠΈΡΠ°ΡΠ΅, Π΄Π° ΠΏΡΠΎΠΌΠ΅Π½ΡΡΠ΅ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΠ΅Π»Π½Π°ΡΠ° ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΡΠΎ, Π΄Π° ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠ°ΡΠ΅ ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎΡΠΎ Π½Π° Π·Π²ΡΠΊΠ°, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²Π·Π΅ΠΌΠ΅ΡΠ΅ ΠΈ βΠΏΡΠΈΠΊΠ°ΡΠΈΡΠ΅β ΠΏΠΎΡΠΎΠΊΠ° Media Stream ΠΊΡΠΌ ΠΌΠ°ΡΠΊΠΈΡΠ°ΠΉΡΠ΅ ΠΈ Π²ΠΈΠΆΡΠ΅ ΡΠ΅Π±Π΅ ΡΠΈ Π½Π° html ΡΡΡΠ°Π½ΠΈΡΠ°ΡΠ°. ΠΠ»ΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΡΠΈΡΡΠ²Π°ΡΠ΅ ΠΏΠΎΡΠΎΠΊ Π²ΡΡΡ Ρ ΠΊΠ°Π½Π°Π²Π° ΠΈ Π΄Π° Π·Π°Π΄Π°Π΄Π΅ΡΠ΅ WebGL ΠΈΠ»ΠΈ CSS3 ΠΈ Π΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠΈΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΠΈΠ»ΡΡΠΈ ΠΊΡΠΌ Π²ΠΈΠ΄Π΅ΠΎΡΠΎ, Π΄Π° Π·Π°ΡΠ½Π΅ΠΌΠ΅ΡΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ΅Π½ΠΎΡΠΎ Π²ΠΈΠ΄Π΅ΠΎ ΠΎΡ ΠΊΠ°Π½Π°Π²Π° ΠΈ ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠΈΡΠ΅ ΠΏΠΎ ΠΌΡΠ΅ΠΆΠ°ΡΠ° Π΄ΠΎ ΡΡΡΠ²ΡΡΠ°, Π΄Π° ΠΏΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠ°ΡΠ΅ ΠΈ ΠΏΡΠ±Π»ΠΈΠΊΡΠ²Π°ΡΠ΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ (Π·Π΄ΡΠ°Π²Π΅ΠΉ bigo live, twitch ΠΈ Π΄ΡΡΠ³ΠΈ). Π’ΡΠΊ Π½ΡΠΌΠ° Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌ ΠΊΠ°ΠΊ ΡΠ΅ ΠΏΡΠ°Π²ΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ Π½Π΅ΡΠ°, ΡΠ΅ Π΄Π°ΠΌ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ°, Π½Π°ΠΌΠ΅ΡΠ΅Π½ΠΈ Π² ΠΌΡΠ΅ΠΆΠ°ΡΠ°:
RTCPeer Π²ΡΡΠ·ΠΊΠ°
Π ΡΠ°ΠΊΠ°, ΡΡΠΈΠ³Π½Π°Ρ
ΠΌΠ΅ Π΄ΠΎ Π²ΡΠΏΡΠΎΡΠ°, Π½ΠΎ ΠΊΠ°ΠΊ Π²ΡΡΡΠ½ΠΎΡΡ Π΄Π° ΠΏΡΠ΅Ρ
Π²ΡΡΠ»ΠΈΡΠ΅ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ»ΠΈΠΏΠ° Π½Π° Π΄ΡΡΠ³ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»? ΠΠ·Π»ΠΈΠ·Π° Π½Π° ΠΏΡΠ΅Π΄Π΅Π½ ΠΏΠ»Π°Π½
const peerConnection = new RTCPeerConnection({
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}]
});
ΠΠΎΡΠΎΡΠ²Π°ΠΌΠ΅ iceServers ΠΊΠ°ΡΠΎ Π΅Π΄Π½Π° ΠΎΡ ΠΎΠΏΡΠΈΠΈΡΠ΅ - ΡΠΎΠ²Π° Π΅ ΡΡΡΠ²ΡΡ, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΠΌΠ°Π³Π° Π΄Π° ΡΠ΅ ΠΎΡΠΈΠ³ΡΡΠΈ Π²ΡΡΠ·ΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²Π° Π±ΡΠ°ΡΠ·ΡΡΠ° Π·Π°Π΄ NAT'om. Π’ΠΎΠ΅ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡΡ Π΅ ΡΠ΅ΡΠ΅Π½ ΡΡΠΊ: ΠΊΠ°ΠΊ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅ ip-ΡΠΎ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°, Π°ΠΊΠΎ ΡΠΎΠΉ ΡΡΠΎΠΈ Π·Π°Π΄ NAT Π½Π° ΡΠ²ΠΎΡ Π΄ΠΎΡΡΠ°Π²ΡΠΈΠΊ? ΠΡΠΎΡΠΎΠΊΠΎΠ»ΡΡ ICE ΠΈΠ΄Π²Π° Π½Π° ΠΏΠΎΠΌΠΎΡ, Π²ΡΡΡΠ½ΠΎΡΡ ICE ΠΈΠ·ΠΎΠ±ΡΠΎ Π½Π΅ ΡΠ΅ ΠΎΡΠ½Π°ΡΡ Π·Π° WebRTC, Π½ΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ Π·Π° ΡΠΎΠ²Π° ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ.
ΠΡΠ΅Π΄ΠΈ ΡΠΎΠ²Π° ΠΈΠΌΠ°Ρ ΠΌΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ ΠΌΠ΅Π΄ΠΈΠΉΠ½ΠΈ ΠΏΠΎΡΠΎΡΠΈ:
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);
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΡΠ±ΠΈΡΠΈΠ΅ΡΠΎ onnegotiationneeded ΡΠ΅ Π·Π°Π΄Π΅ΠΉΡΡΠ²Π° Π½Π° peerConnection, Π² ΡΠΈΠΉΡΠΎ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡ ΡΡΡΠ±Π²Π° Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΠΌ ΠΎΡΠ΅ΡΡΠ° (ΠΎΡ Π³Π»Π΅Π΄Π½Π° ΡΠΎΡΠΊΠ° Π½Π° SDP - ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π·Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ΅ΡΠΈΡ) ΠΈ Π΄Π° Ρ ΠΏΡΠΈΡΠ²ΠΎΠΈΠΌ Π½Π° peerConnection ΡΡΠ΅Π· ΠΌΠ΅ΡΠΎΠ΄Π° setLocalDescription. ΠΠ° SDP - ΠΊΠ°ΠΊΠ²ΠΎ Π΅ ΡΠΎΠ²Π° ΠΈ Π·Π° ΡΠΎΡΠΌΠ°ΡΠΈΡΠ΅ Π½Π° ΠΎΡΠ΅ΡΡΠΈΡΠ΅ ΠΈ ΠΎΡΠ³ΠΎΠ²ΠΎΡΠΈΡΠ΅ - ΡΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠΌ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΎ.
Π‘Π»Π΅Π΄ ΠΏΡΠΈΡΠ²ΠΎΡΠ²Π°Π½Π΅ Π½Π° LocalDescription peerConnection, Π±ΡΠ°ΡΠ·ΡΡΡΡ "ΡΠ³Π»ΠΎΠ±ΡΠ²Π°" ΠΊΠ°Π½Π΄ΠΈΠ΄Π°ΡΠΈ Π·Π° Π»Π΅Π΄, ΡΠΎΠ΅ΡΡ Π½Π°ΠΌΠΈΡΠ° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π½Π°ΡΠΈΠ½ΠΈ Π·Π° ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ ΡΡΠ΅Π· NAT. Π‘ΡΠ±ΠΈΡΠΈΠ΅ΡΠΎ onicegatheringstatechange ΡΠ΅ Π·Π°Π΄Π΅ΠΉΡΡΠ²Π°. Π ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠ° Π½Π° onicegatheringstatechange ΡΠ°Π·ΡΠ΅ΡΠ°Π²Π°ΠΌΠ΅ Π²ΡΡΠ·ΠΊΠ° ΠΊΡΠΌ ΠΏΠΎΡΠΎΠΊΠ° Π½Π° webrtc-signaling-ΡΡΡΠ²ΡΡΠ° Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠ΅ΡΠΈΡΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠ°ΡΡΠ½ΡΠΎΡΠΈ:
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-ΡΡΡΠ²ΡΡΡΡ Π΅ ΡΡΡΠ²ΡΡΡΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌ Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠ΅ΡΠΈΡΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²Π°ΠΌΠ° ΠΏΠ°ΡΡΠ½ΡΠΎΡΠΈ, ΡΠΎΠΉ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ Π½Π°ΠΉ-ΠΏΡΠΎΡΡΠΈΡΡ websocket ΠΈΠ»ΠΈ xhr-ΡΡΡΠ²ΡΡ Π½Π° Π²ΡΠ΅ΠΊΠΈ PL. ΠΠ°Π΄Π°ΡΠ°ΡΠ° ΠΌΡ Π΅ ΠΏΡΠΎΡΡΠ°: Π΄Π° ΠΏΡΠΈΠ΅ΠΌΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ΅ΡΠΈΡ ΠΎΡ Π΅Π΄ΠΈΠ½ ΠΏΠ°ΡΡΠ½ΡΠΎΡ ΠΈ Π΄Π° Π³ΠΎ ΠΏΡΠ΅Ρ Π²ΡΡΠ»ΠΈ Π½Π° Π΄ΡΡΠ³.
Π‘Π»Π΅Π΄ ΠΎΠ±ΠΌΠ΅Π½Π° Π½Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ Π½Π° ΡΠ΅ΡΠΈΡΡΠ° ΠΈ Π΄Π²Π΅ΡΠ΅ ΡΡΡΠ°Π½ΠΈ ΡΠ° Π³ΠΎΡΠΎΠ²ΠΈ Π·Π° ΠΈΠ·Π»ΡΡΠ²Π°Π½Π΅ ΠΈ ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΡΠΈ, ΠΎΡ ΡΡΡΠ°Π½Π°ΡΠ°, ΠΊΠΎΡΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π° Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡΠΎΠΊΠ°, ΡΡΠ±ΠΈΡΠΈΠ΅ΡΠΎ ontrack ΡΠ΅ Π·Π°Π΄Π΅ΠΉΡΡΠ²Π° Π½Π° peerConnection, Π² ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠ° Π½Π° ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡΠ΅ ΠΏΠ΅ΡΠ½ΠΈ ΠΌΠΎΠ³Π°Ρ Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΡΠΈΡΠ²ΠΎΠ΅Π½ΠΈ Π½Π° ΠΈ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π»ΡΠ±ΠΈΠΌΠΈΡ ΡΠΈ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ. ΠΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½Π° ΡΠ΅ΠΎΡΠΈΡ ΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ.
ΠΠΈΠ½ΠΊΠΎΠ²Π΅ ΠΈ Π»ΠΈΡΠ΅ΡΠ°ΡΡΡΠ°:
Π ΡΠ»Π΅Π΄Π²Π°ΡΠ°ΡΠ° ΡΠ°ΡΡ ΠΈΡΠΊΠ°ΠΌ Π΄Π° Π΄Π°ΠΌ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ ΡΠ°ΡΡ ΠΎΡ ΡΠ΅ΠΎΡΠΈΡΡΠ° ΠΈ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ° Π΄Π° Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌ ΠΏΡΠΈΠ΅ΠΌΠ°Π½Π΅ΡΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ° Π½Π° Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡΠΎΠΊ Π½Π° ΡΡΡΠ²ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° pion, ΠΏΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π² HLS ΡΡΠ΅Π· ffmpeg Π·Π° ΠΏΠΎΡΠ»Π΅Π΄Π²Π°ΡΠΎ ΠΈΠ·Π»ΡΡΠ²Π°Π½Π΅ ΠΊΡΠΌ Π·ΡΠΈΡΠ΅Π»ΠΈΡΠ΅ Π² Π±ΡΠ°ΡΠ·ΡΡΠ°.
ΠΠ° Π½Π΅ΡΡΡΠΏΠ΅Π»ΠΈΠ²ΠΈΡΠ΅:
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com