(Bron) gwe-gamera diwerth yn ffrydio o borwr. Rhan 2. WebRTC

Rhywsut i mewn un o hen erthyglau sydd eisoes wedi'u gadael, ysgrifennais am ba mor hawdd a naturiol y gallwch chi ddarlledu fideo o gynfas trwy socedi gwe. Yn yr erthygl honno, siaradais yn fyr am sut i ddal fideo o gamera a sain o feicroffon gan ddefnyddio MediaStream API, sut i amgodio'r ffrwd a dderbyniwyd a'i hanfon trwy websocedi i'r gweinydd. Fodd bynnag, mewn gwirionedd nid ydynt yn gwneud hyn, ar gyfer darllediadau maent yn defnyddio naill ai meddalwedd arbennig y mae angen ei osod a'i ffurfweddu: oddi ar y llaw arall, gall hyn fod Meddalwedd Darlledu Agored, neu maen nhw'n defnyddio WebRTC, sy'n gweithio'n iawn allan o'r bocs, hynny yw, nid oes angen gosod unrhyw ategion a la flash player, a fydd yn cael ei dorri allan o'r porwr Chromium eisoes ym mis Rhagfyr.

Heddiw byddwn yn siarad am WebRTC.

Nid yw Web Real-Time Communication (WebRTC) yn brotocol sengl, mae'n gasgliad cyfan o safonau, protocolau ac APIs JavaScript sydd gyda'i gilydd yn darparu cyfathrebu fideo-sain amser real rhwng cymheiriaid, a gellir ei ddefnyddio hefyd i drosglwyddo unrhyw data deuaidd. Fel arfer mae porwyr yn gweithredu fel cyfoedion, ond gall hefyd fod yn gymhwysiad symudol, er enghraifft. Er mwyn trefnu cyfathrebu p2p rhwng cleientiaid, mae angen cefnogaeth porwr ar gyfer gwahanol fathau o amgodio fideo a sain, cefnogaeth ar gyfer amrywiaeth o brotocolau rhwydwaith, gan sicrhau rhyngweithio caledwedd Γ’'r porwr (trwy haenau OS): gwe-gamerΓ’u, cardiau sain. Mae'r holl hodgepodge hwn o dechnolegau wedi'i guddio y tu Γ΄l i dyniad API JavaScript er hwylustod y datblygwr.

Mae'r cyfan yn cwympo i dri API:

  • MediaStream API β€” datgymalwyd y tro diwethaf, heddiw byddaf yn ysgrifennu ychydig mwy amdano. Yn gwasanaethu i dderbyn ffrydiau fideo / sain o'r caledwedd

  • RTCPeerCysylltiad β€” yn darparu cyfathrebu rhwng dau gleient (t2p)

  • Sianel RTCData - yn gwasanaethu i drosglwyddo data mympwyol rhwng dau gleient

Paratoi ffrydiau sain a fideo i'w darlledu

Mae'r cyfan yn dechrau gyda "chipio" y gwe-gamera a meicroffon ffrydiau cyfryngau. Wrth gwrs, nid yw ffrydiau crai yn addas ar gyfer trefnu telegynhadledd, mae angen prosesu pob ffrwd: gwella ansawdd, cydamseru sain Γ’ fideo, gosod marciau cydamseru yn y ffrwd fideo, a sicrhau'r gyfradd bit sy'n cyfateb i led band y sianel sy'n newid yn gyson. . Mae'r porwr yn gofalu am hyn i gyd, nid oes rhaid i'r datblygwr hyd yn oed boeni am ddarparu amgodio ar gyfer ffrydiau cyfryngau. Y tu mewn i borwr modern, mae yna haenau meddalwedd eisoes ar gyfer dal, gwella ansawdd (tynnu adlais a sΕ΅n o sain, gwella'r llun), amgodio fideo a sain. Dangosir y cynllun haenau yn ffig. 1:

(Bron) gwe-gamera diwerth yn ffrydio o borwr. Rhan 2. WebRTCReis. 1. Haenau prosesu sain a fideo yn y porwr

Mae'r holl brosesu yn digwydd yn uniongyrchol yn y porwr ei hun, dim ychwanegol. dim angen ategion. Fodd bynnag, nid yw pethau mor roslyd o hyd ar gyfer 2020. Mae yna borwyr nad ydynt yn cefnogi'n llawn eto MediaStream API, gallwch ddilyn y ddolen a gweld y tabl cydnawsedd ar y gwaelod iawn. Mae IE yn arbennig yn siomedig eto.

Gallwch chi wneud pethau diddorol iawn gyda'r ffrydiau a dderbynnir: gallwch glonio, newid y datrysiad fideo, trin ansawdd y sain, gallwch chi gymryd a β€œbachu” ffrwd y Media Stream i tagiwch ac edrychwch ar eich hun ar y dudalen html. Neu gallwch dynnu ffrwd ar gynfas, a gosod WebGL neu CSS3, a chymhwyso hidlwyr amrywiol i fideo, dal y fideo wedi'i brosesu o gynfas ac yna ei anfon dros y rhwydwaith i'r gweinydd, ei drawsgodio a'i gyhoeddi i bawb (helo bigo yn fyw, twitch ac eraill). Yma ni fyddaf yn dadansoddi sut mae pethau o'r fath yn cael eu gwneud, byddaf yn rhoi cwpl o enghreifftiau a geir ar y we:

https://jeeliz.com/ - mae'r bechgyn yn gwneud CV amser real yn Javascript. Mae ganddyn nhw gyfan arsenal amrywiol lyfrgelloedd js ar gyfer gweithio gyda ffrwd fideo ar gynfas: canfod wynebau, gwrthrychau, gosod hidlwyr (masgiau, fel yn Instagram), ac ati Enghraifft wych o sut y gallwch chi brosesu fideo amser real yn uniongyrchol yn y porwr heb ategion ychwanegol.

API captureStream Canvas - Dogfennaeth API ar gyfer dal ffrwd fideo o gynfas. Eisoes wedi'i gefnogi yn Chrome, Opera a Firefox

RTCPeerCysylltiad

Felly daethom at y pwynt, ond sut i drosglwyddo'r fideo i ddefnyddiwr arall mewn gwirionedd? Yn dod i'r amlwg RTCPeerCysylltiad. Yn fyr, ar bron y cam hwn mae angen i chi greu gwrthrych RTCPeerConnection:

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

Rydym yn nodi iceServers fel un o'r opsiynau - mae hwn yn weinydd sy'n helpu i ddarparu cysylltiad rhwng dau borwr y tu Γ΄l i NAT'om. Hynny yw, mae'r broblem yn cael ei datrys yma: sut i ddarganfod cyfeiriad ip yr interlocutor a yw ef y tu Γ΄l i NAT ei ddarparwr? Daw'r protocol ICE i'r adwy, mewn gwirionedd, nid yw ICE yn berthnasol i WebRTC o gwbl, ond yn fwy ar hynny yn ddiweddarach.

Yn flaenorol, cawsom ffrydiau 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);

Nesaf, mae'r digwyddiad sydd ei angen ar negotiation yn tanio ar y peerConnection, ac yn y triniwr mae'n rhaid i ni greu cynnig (yn nhermau SDP - Protocol Disgrifiad o'r Sesiwn) a'i aseinio i'r peerConnection trwy'r dull setLocalDescription. Am CDY - beth ydyw ac am y fformatau cynnig ac ateb - byddwn yn siarad ymhellach.

Ar Γ΄l aseinio peerConnection LocalDescription, mae'r porwr yn "cydosod" ymgeiswyr iΓ’, hynny yw, yn dod o hyd i wahanol ffyrdd o gyfathrebu trwy NAT. Mae'r digwyddiad cyfnewid cyflwr casglu ar danau. Yn y triniwr cyfnewid cyfnewid onicegathering, rydym yn caniatΓ‘u cysylltiad Γ’'r ffrwd webrtc-signaling-server i gyfnewid Disgrifiad o'r Sesiwn rhwng cyfoedion:

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);
      }
    };

Y webrtc-signaling-server yw'r gweinydd sydd ei angen i gyfnewid disgrifiad y sesiwn rhwng dau gymar, gall fod y websocket neu'r gweinydd xhr symlaf ar unrhyw PL. Mae ei dasg yn syml: derbyn disgrifiad sesiwn gan un cymar a'i drosglwyddo i un arall.

Ar Γ΄l cyfnewid disgrifiadau Sesiwn, mae'r ddwy ochr yn barod i ddarlledu a derbyn ffrydiau fideo, ar yr ochr sy'n derbyn y ffrwd fideo, mae'r digwyddiad ontrack yn cael ei sbarduno ar y peerConnection, yn y triniwr, gellir neilltuo'r traciau a dderbyniwyd i ac edrych ar eich hoff interlocutor. Theori a manylion pellach.

Dolenni a llenyddiaeth:

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection - dogfennaeth RTCPeerCysylltiad

https://github.com/pion/webrtc - gweithredu protocolau WebRTC ar waith

https://webrtcforthecurious.com/ β€” llyfr gan grewyr pion

https://hpbn.co/ - Archebu Rhwydweithio Porwr Perfformiad Uchel. Mae materion sicrhau perfformiad uchel rhaglenni gwe yn cael eu trafod yn fanwl. Ar y diwedd, disgrifir WebRTC. Mae'r llyfr yn sicr yn hen (2013), ond nid yw'n colli ei berthnasedd.

Yn y rhan nesaf, rwyf am roi ychydig mwy o ddogn o theori ac yn ymarferol dadansoddi derbyniad a phrosesu llif fideo ar y gweinydd gan ddefnyddio pion, gan drawsgodio i HLS trwy ffmpeg i'w ddarlledu wedyn i wylwyr yn y porwr.

Ar gyfer y diamynedd: fy mhrototeip amrwd iawn o ddarlledu fideo o we-gamera i ymateb trwy weinydd sy'n seiliedig ar pion mewn plwc (dim ond arbrawf yw hwn).

Ffynhonnell: hab.com

Ychwanegu sylw