(ΠŸΠΎΡ‡Ρ‚ΠΈ) бСсполСзный стриминг Π²Π΅Π±ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΈΠ· Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°. Π§Π°ΡΡ‚ΡŒ 2. WebRTC

Как-Ρ‚ΠΎ Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· старинных ΠΈ ΡƒΠΆΠ΅ Π·Π°Π±Ρ€ΠΎΡˆΠ΅Π½Π½Ρ‹Ρ… статСй я писал ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π»Π΅Π³ΠΊΠΎ ΠΈ Π½Π΅ΠΏΡ€ΠΈΠ½ΡƒΠΆΠ΄Π΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚Ρ€Π°Π½ΡΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ с canvas Ρ‡Π΅Ρ€Π΅Π· websockets. Π’ Ρ‚ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ повСрхностно рассказывал ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ с ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΈ Π·Π²ΡƒΠΊ с ΠΌΠΈΠΊΡ€ΠΎΡ„ΠΎΠ½Π° посрСдством MediaStream API, ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· websockets Π½Π° сСрвСр. Однако Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ‚Π°ΠΊ Π½Π΅ Π΄Π΅Π»Π°ΡŽΡ‚, для трансляций ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π»ΠΈΠ±ΠΎ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ софт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½ΡƒΠΆΠ½ΠΎ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ ΠΈ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ: навскидку это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Open Broadcast Software, Π»ΠΈΠ±ΠΎ Π·Π°Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ WebRTC, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ прямо ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ установки Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² аля flash player, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΡ‚ ΡƒΠΆΠ΅ Π² Π΄Π΅ΠΊΠ°Π±Ρ€Π΅ выпилят ΠΈΠ· Chromium Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°.

БСгодня ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ WebRTC.

Web Real-Time Communication (WebRTC) это Π½Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», это цСлая коллСкция стандартов, ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² ΠΈ JavaScript API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ всС вмСстС ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ peer-to-peer Π²ΠΈΠ΄Π΅ΠΎ-Π°ΡƒΠ΄ΠΈΠΎ ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π»ΡŽΠ±Ρ‹Ρ… Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠΈΡ€Π°ΠΌΠΈ Π²Ρ‹ΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρ‹, Π½ΠΎ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈ мобильноС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ p2p ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ трСбуСтся ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π²ΠΈΠ΄ΠΎΠ² кодирования Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡƒΠ΄ΠΈΠΎ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° мноТСства сСтСвых ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ², обСспСчСниС взаимодСйствия ΠΆΠ΅Π»Π΅Π·Π° с Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ (Ρ‡Π΅Ρ€Π΅Π· слои ОБ): Π²Π΅Π±ΠΊΠ°ΠΌΠ΅Ρ€, Π·Π²ΡƒΠΊΠΎΠ²Ρ‹Ρ… ΠΊΠ°Ρ€Ρ‚. Вся эта мСшанина Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ скрыта Π·Π° абстракциСй JavaScript API для удобства Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.

ВсС сводится Π² ΠΈΡ‚ΠΎΠ³Π΅ ΠΊ Ρ‚Ρ€Π΅ΠΌ API:

  • MediaStream API — Ρ€Π°Π·Π±ΠΈΡ€Π°Π»ΠΈ Π² ΠΏΡ€ΠΎΡˆΠ»Ρ‹ΠΉ Ρ€Π°Π·, сСгодня Π΅Ρ‰Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π½Π°ΠΏΠΈΡˆΡƒ ΠΏΡ€ΠΎ Π½Π΅Π³ΠΎ. Π‘Π»ΡƒΠΆΠΈΡ‚ для получСния Π²ΠΈΠ΄Π΅ΠΎ/Π°ΡƒΠ΄ΠΈΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΎΡ‚ «ΠΆΠ΅Π»Π΅Π·Π°»

  • RTCPeerConnection — обСспСчиваСт ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ двумя ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ (p2p)

  • RTCDataChannel — слуТит для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ двумя ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Π°ΡƒΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅

ВсС начинаСтся с «Π·Π°Ρ…Π²Π°Ρ‚Π°» ΠΌΠ΅Π΄ΠΈΠ°ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π²Π΅Π±ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΈ ΠΌΠΈΠΊΡ€ΠΎΡ„ΠΎΠ½Π°. Π‘Ρ‹Ρ€Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅ Π½Π΅ подходят для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‚Π΅Π»Π΅ΠΊΠΎΠ½Ρ„Π΅Ρ€Π΅Π½Ρ†ΠΈΠΈ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ: ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ качСство, ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°ΡƒΠ΄ΠΈΠΎ с Π²ΠΈΠ΄Π΅ΠΎ, Ρ€Π°ΡΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΊΠΈ синхронизации Π² Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊΠ΅, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ постоянно ΠΌΠ΅Π½ΡΡŽΡ‰Π΅ΠΉΡΡ ΡˆΠΈΡ€ΠΎΡ‚Π΅ пропускания ΠΊΠ°Π½Π°Π»Π° Π±ΠΈΡ‚Ρ€Π΅ΠΉΡ‚. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ всС это Π±Π΅Ρ€Π΅Ρ‚ Π½Π° сСбя, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ Π΄Π°ΠΆΠ΅ Π½Π΅ Π½Π°Π΄ΠΎ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡ‚ΡŒΡΡ ΠΎΠ± обСспСчСнии кодирования ΠΌΠ΅Π΄ΠΈΠ°-ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’Π½ΡƒΡ‚Ρ€ΠΈ соврСмСнного Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ΡƒΠΆΠ΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ слои Π·Π°Ρ…Π²Π°Ρ‚Π°, ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ качСства (ΡƒΠ±Ρ€Π°Ρ‚ΡŒ эхо ΠΈ ΡˆΡƒΠΌ ΠΈΠ· Π·Π²ΡƒΠΊΠ°, ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ), кодирования Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡƒΠ΄ΠΈΠΎ. Π‘Ρ…Π΅ΠΌΠ° слоСв ΠΏΠΎΠΊΠ°Π·Π°Π½Π° рис. 1:

(ΠŸΠΎΡ‡Ρ‚ΠΈ) бСсполСзный стриминг Π²Π΅Π±ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹ ΠΈΠ· Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°. Π§Π°ΡΡ‚ΡŒ 2. WebRTCРис. 1. Π‘Π»ΠΎΠΈ Π°ΡƒΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅

Вся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° происходит прямо Π² самом Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅, Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄ΠΎΠΏ. ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Π½Π΅ трСбуСтся. Однако всС Π΅Ρ‰Π΅ Π½Π΅ ΡΡ‚ΠΎΠ»ΡŒ Ρ€Π°Π΄ΡƒΠΆΠ½ΠΎ Π½Π° 2020 Π³ΠΎΠ΄. ΠžΡΡ‚Π°Π»ΠΈΡΡŒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΊΠ° Π΅Ρ‰Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ MediaStream API, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΏΠΎ ссылкС ΠΈ Π² самом Π½ΠΈΠ·Ρƒ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ совмСстимости. Π’ частности IE снова Ρ€Π°Π·ΠΎΡ‡Π°Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚.

Π‘ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ интСрСсныС Π²Π΅Ρ‰ΠΈ: ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π²ΠΈΠ΄Π΅ΠΎ, ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ качСством Π°ΡƒΠ΄ΠΈΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡ‚ΡŒ ΠΈ «ΠΏΡ€ΠΈΡ†Π΅ΠΏΠΈΡ‚ΡŒ» Media Stream ΠΏΠΎΡ‚ΠΎΠΊ ΠΊ <video> Ρ‚Π΅Π³Ρƒ ΠΈ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° сСбя любимого Π½Π° страничкС html. А ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ Π½Π° canvas ΠΎΡ‚Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ, ΠΈ Π½Π°Ρ‚Ρ€Π°Π²ΠΈΡ‚ΡŒ WebGL ΠΈΠ»ΠΈ CSS3, ΠΈ Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ Π½Π° Π²ΠΈΠ΄Π΅ΠΎ, Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎ с canvas ΠΈ Π΄Π°Π»Π΅Π΅ ΡƒΠΆΠ΅ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠΎ сСти Π½Π° сСрвСр, Ρ‚Ρ€Π°Π½ΡΠΊΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Ρ‚ΡŒ всСм ΠΆΠ΅Π»Π°ΡŽΡ‰ΠΈΠΌ (ΠΏΡ€ΠΈΠ²Π΅Ρ‚ bigo live, twitch ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠ΅). Π—Π΄Π΅ΡΡŒ я Π½Π΅ Π±ΡƒΠ΄Ρƒ Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π΄Π΅Π»Π°ΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΈΠ΅ Π²Π΅Ρ‰ΠΈ, ΠΏΡ€ΠΈΠ²Π΅Π΄Ρƒ ΠΏΠ°Ρ€Ρƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ², Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹Ρ… Π½Π° просторах сСти:

https://jeeliz.com/ — рСбята Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ realtime CV Π½Π° Javascript. Π£ Π½ΠΈΡ… Π΅ΡΡ‚ΡŒ Ρ†Π΅Π»Ρ‹ΠΉ арсСнал Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… js-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π½Π° canvas: Π΄Π΅Ρ‚Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π»ΠΈΡ†, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π½Π°Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² (масок, ΠΊΠ°ΠΊ Π² инстС) ΠΈ ΠΏΡ€. ΠžΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ прямо Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

Canvas captureStream API — докумСнтация API ΠΏΠΎ Π·Π°Ρ…Π²Π°Ρ‚Ρƒ Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊΠ° с canvas. Π£ΠΆΠ΅ поддСрТиваСтся Π² Chrome, Opera ΠΈ Firefox

RTCPeerConnection

Π’ΠΎΡ‚ ΠΌΡ‹ ΠΈ подошли ΠΊ Ρ‚ΠΎΠΌΡƒ, Π° ΠΊΠ°ΠΊ собствСнно ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ? На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠ»Π°Π½ выступаСт RTCPeerConnection. Если Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ ΠΊΡ€Π°Ρ‚ΠΊΠΎ, практичСски Π½Π° этом шагС Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ RTCPeerConnection:

const peerConnection = new RTCPeerConnection({
  iceServers: [{
    urls: 'stun:stun.l.google.com:19302'
  }]
});

Одной ΠΈΠ· ΠΎΠΏΡ†ΠΈΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ iceServers — это сСрвСр, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ соСдинСниС ΠΌΠ΅ΠΆΠ΄Ρƒ двумя Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌΠΈ, находящимися Π·Π° NAT’ΠΎΠΌ. Π’ΠΎ Π΅ΡΡ‚ΡŒ здСсь Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: ΠΊΠ°ΠΊ ΡƒΠ·Π½Π°Ρ‚ΡŒ ip собСсСдника, Ссли ΠΎΠ½ находится Π·Π° 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 срабатываСт событиС onnegotiationneeded, Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ offer (Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ… SDP — Session Description Protocol) ΠΈ Π½Π°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ Π² peerConnection Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ setLocalDescription. Об SDP — Ρ‡Ρ‚ΠΎ это Ρ‚Π°ΠΊΠΎΠ΅ ΠΈ ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°Ρ… offer ΠΈ answer — ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π΄Π°Π»Π΅Π΅.

ПослС назначСния LocalDescription peerConnection, Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ «ΡΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚» ice-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ², Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ для ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‡Π΅Ρ€Π΅Π· NAT. Π‘Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ событиС onicegatheringstatechange. Π’ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ onicegatheringstatechange Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅ΠΌ соСдинСниС с webrtc-signaling-сСрвСром 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-сСрвСр — это сСрвСр, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ для обСспСчСния ΠΎΠ±ΠΌΠ΅Π½Π° session description ΠΌΠ΅ΠΆΠ΄Ρƒ двумя ΠΏΠΈΡ€Π°ΠΌΠΈ, это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ websocket ΠΈΠ»ΠΈ xhr-сСрвСр Π½Π° любом ЯП. Π•Π³ΠΎ Π·Π°Π΄Π°Ρ‡Π° проста: ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ session description ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΈΡ€Π° ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ.

ПослС ΠΎΠ±ΠΌΠ΅Π½Π° Session descriptions ΠΎΠ±Π΅ стороны Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Ρ‚Ρ€Π°Π½ΡΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π½Π° сторонС, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊ срабатываСт событиС ontrack Π½Π° peerConnection, Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΡ‹Π΅ Ρ‚Ρ€Π΅ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ Π½Π° <video> ΠΈ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° любимого собСсСдника. Π”Π°Π»Π΅Π΅ тСория ΠΈ подробности.

Бсылки ΠΈ Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Π°:

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection — докумСнтация RTCPeerConnection

https://github.com/pion/webrtc — рСализация ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ² WebRTC Π½Π° go

https://webrtcforthecurious.com/ — ΠΊΠ½ΠΈΠΆΠ΅Ρ‡ΠΊΠ° ΠΎΡ‚ создатСлСй pion

https://hpbn.co/ — ΠΊΠ½ΠΈΠ³Π° High Perfomance Browser Networking. Π’ подробностях Ρ€Π°Π·Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ вопросы обСспСчСния высокой ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ web-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’ ΠΊΠΎΠ½Ρ†Π΅ описываСтся WebRTC. КниТка ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ старая (2013), Π½ΠΎ Π½Π΅ тСряСт своСй Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ части Ρ…ΠΎΡ‡Ρƒ Π΄Π°Ρ‚ΡŒ Π΅Ρ‰Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Ρ†ΠΈΠΈ Ρ‚Π΅ΠΎΡ€ΠΈΠΈ ΠΈ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ΅ΠΌ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡ‚ΠΎΠΊΠ° Π½Π° сСрвСрС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ pion, транскодинг Π² HLS Ρ‡Π΅Ρ€Π΅Π· ffmpeg для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ трансляции зритСлям Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅.

Для Π½Π΅Ρ‚Π΅Ρ€ΠΏΠ΅Π»ΠΈΠ²Ρ‹Ρ…: ΠΌΠΎΠΉ ΠΎΡ‡Π΅Π½ΡŒ сырой ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ трансляции Π²ΠΈΠ΄Π΅ΠΎ с Π²Π΅Π±ΠΊΠΈ Π½Π° react Ρ‡Π΅Ρ€Π΅Π· сСрвСр Π½Π° основС pion Π² twitch (это просто экспСримСнт).

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com