Transmetimi (Pothuajse) i padobishëm i kamerës së internetit nga një shfletues. Pjesa 2. WebRTC

Disi brenda одной nga artikujt e vjetër dhe tashmë të braktisur, kam shkruar se sa lehtë dhe natyrshëm mund të transmetoni video nga kanavacë përmes prizave në internet. Në atë artikull, unë fola shkurtimisht se si të kapni video nga një aparat fotografik dhe zë nga një mikrofon duke përdorur MediaStream API, si të kodoni transmetimin e marrë dhe ta dërgoni atë përmes prizave të internetit në server. Sidoqoftë, në realitet ata nuk e bëjnë këtë, për transmetime ata përdorin ose softuer special që duhet të instalohet dhe konfigurohet: në mënyrë të padobishme, kjo mund të jetë Software i hapur i transmetimit, ose përdorin WebRTC, i cili funksionon menjëherë, domethënë nuk kërkon instalimin e ndonjë shtojce a la flash player, i cili do të shkëputet nga shfletuesi Chromium tashmë në dhjetor.

Sot do të flasim për WebRTC.

Komunikimi në kohë reale në ueb (WebRTC) nuk është një protokoll i vetëm, ai është një koleksion i tërë standardesh, protokolesh dhe API-të JavaScript që së bashku ofrojnë komunikim video-audio në kohë reale peer-to-peer, dhe gjithashtu mund të përdoren për të transferuar ndonjë të dhëna binare. Zakonisht shfletuesit veprojnë si kolegë, por mund të jetë edhe një aplikacion celular, për shembull. Për të organizuar komunikimin p2p midis klientëve, kërkohet mbështetje e shfletuesit për lloje të ndryshme të kodimit video dhe audio, mbështetje për një sërë protokollesh të rrjetit, duke siguruar ndërveprimin e harduerit me shfletuesin (përmes shtresave të OS): kamerat e internetit, kartat e zërit. E gjithë kjo grumbull teknologjish fshihet pas abstraksionit të JavaScript API për lehtësinë e zhvilluesit.

Gjithçka zbret në tre API:

  • MediaStream API — i çmontuar herën e kaluar, sot do të shkruaj pak më shumë për të. Shërben për të marrë transmetime video / audio nga hardueri

  • Lidhja RTCPeer — siguron komunikim ndërmjet dy klientëve (p2p)

  • RTCDataChannel - shërben për transferimin e të dhënave arbitrare ndërmjet dy klientëve

Përgatitja e transmetimeve audio dhe video për transmetim

Gjithçka fillon me "kapjen" e transmetimeve të mediave të kamerës së internetit dhe mikrofonit. Sigurisht, transmetimet e papërpunuara nuk janë të përshtatshme për të organizuar një telekonferencë, çdo transmetim duhet të përpunohet: përmirësoni cilësinë, sinkronizoni audion me videon, vendosni shenjat e sinkronizimit në transmetimin e videos dhe siguroni shpejtësinë e biteve që korrespondon me gjerësinë e brezit të kanalit që ndryshon vazhdimisht. . Shfletuesi kujdeset për të gjitha këto, zhvilluesi as nuk duhet të shqetësohet për sigurimin e kodimit për transmetimet e mediave. Brenda një shfletuesi modern, tashmë ka shtresa softuerësh për kapjen, përmirësimin e cilësisë (heqja e jehonës dhe zhurmës nga zëri, përmirësimi i figurës), kodimi i videos dhe audios. Skema e shtresave është paraqitur në fig. 1:

Transmetimi (Pothuajse) i padobishëm i kamerës së internetit nga një shfletues. Pjesa 2. WebRTCOriz. 1. Shtresat e përpunimit audio dhe video në shfletues

I gjithë përpunimi kryhet drejtpërdrejt në vetë shfletuesin, pa shtesë. nuk kërkohen shtojca. Megjithatë, gjërat nuk janë ende aq rozë për vitin 2020. Ka shfletues që ende nuk mbështesin plotësisht MediaStream API, mund të ndiqni lidhjen dhe të shihni tabelën e përputhshmërisë në fund. IE në veçanti është përsëri zhgënjyese.

Mund të bëni gjëra shumë interesante me transmetimet e marra: mund të klononi, ndryshoni rezolucionin e videos, manipuloni cilësinë e audios, mund të merrni dhe "lidhni" transmetimin e Media Stream në etiketoni dhe shikoni veten në faqen html. Ose mund të vizatoni një transmetim në kanavacë, dhe të vendosni WebGL ose CSS3, dhe të aplikoni filtra të ndryshëm në video, të kapni videon e përpunuar nga kanavacë dhe më pas ta dërgoni përmes rrjetit në server, të transkodoni dhe publikoni për të gjithë (përshëndetje bigo live, twitch dhe të tjerët). Këtu nuk do të analizoj se si bëhen gjëra të tilla, do të jap disa shembuj që gjenden në ueb:

https://jeeliz.com/ - djemtë po bëjnë CV në kohë reale në Javascript. Ata kanë një tërësi arsenalin biblioteka të ndryshme js për të punuar me një transmetim video në kanavacë: zbulimi i fytyrave, objekteve, aplikimi i filtrave (maska, si në Instagram), etj. Një shembull i shkëlqyer se si mund të përpunoni video në kohë reale direkt në shfletues pa shtojca shtesë.

Canvas captureStream API - Dokumentacioni API për kapjen e një transmetimi video nga kanavacë. Mbështetet tashmë në Chrome, Opera dhe Firefox

Lidhja RTCPeer

Pra, arritëm në pikën, por si ta transferojmë videon te një përdorues tjetër? Vjen në pah Lidhja RTCPeer. Me pak fjalë, pothuajse në këtë hap ju duhet të krijoni një objekt RTCPeerConnection:

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

Ne specifikojmë iceServers si një nga opsionet - ky është një server që ndihmon për të siguruar një lidhje midis dy shfletuesve pas NAT'om. Kjo do të thotë, problemi zgjidhet këtu: si ta zbuloni ip-në e bashkëbiseduesit nëse ai qëndron prapa NAT-së së ofruesit të tij? Protokolli ICE vjen në shpëtim, në fakt, ICE nuk zbatohet fare për WebRTC, por më shumë për këtë më vonë.

Më parë, ne morëm transmetime të 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);

Më pas, ngjarja onnegotiationneeded ndizet në peerConnection, në mbajtësin e së cilës duhet të krijojmë një ofertë (për sa i përket SDP - Protokollit të Përshkrimit të Sesionit) dhe t'ia caktojmë atë peerConnection nëpërmjet metodës setLocalDescription. Rreth SDP - çfarë është dhe për formatet e ofertës dhe përgjigjeve - do të flasim më tej.

Pas caktimit të një LocalDescription peerConnection, shfletuesi "mbledh" kandidatët e akullit, domethënë gjen mënyra të ndryshme për të komunikuar përmes NAT. Ngjarja onicegatheringstatechange ndez. Në mbajtësin onicegatheringstatechange, ne lejojmë një lidhje me rrjedhën webrtc-signaling-server për të shkëmbyer Përshkrimin e sesionit midis kolegëve:

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 është serveri që kërkohet për të shkëmbyer përshkrimin e sesionit midis dy kolegëve, ai mund të jetë websocket ose xhr-server më i thjeshtë në çdo PL. Detyra e tij është e thjeshtë: të pranojë një përshkrim sesioni nga një koleg dhe ta transferojë atë në një tjetër.

Pas shkëmbimit të përshkrimeve të Sesionit, të dyja palët janë gati të transmetojnë dhe të marrin transmetime video, në anën që merr transmetimin e videos, ngjarja ontrack aktivizohet në lidhjen peerConnection, në mbajtësin e të cilit, pjesët e marra mund t'i caktohen dhe shikoni bashkëbiseduesin tuaj të preferuar. Teori dhe detaje të mëtejshme.

Lidhjet dhe literatura:

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection - dokumentacion Lidhja RTCPeer

https://github.com/pion/webrtc - implementimi i protokolleve WebRTC në lëvizje

https://webrtcforthecurious.com/ - një libër nga krijuesit e pion

https://hpbn.co/ - Rezervoni Rrjetin e Shfletuesit me Performancë të Lartë. Çështjet e sigurimit të performancës së lartë të aplikacioneve në internet diskutohen në detaje. Në fund, përshkruhet WebRTC. Libri është sigurisht i vjetër (2013), por nuk e humbet rëndësinë e tij.

Në pjesën tjetër, dua të jap pak më shumë pjesë të teorisë dhe në praktikë të analizoj marrjen dhe përpunimin e një transmetimi video në server duke përdorur pion, duke transkoduar në HLS përmes ffmpeg për transmetim të mëvonshëm për shikuesit në shfletues.

Për të paduruarit: prototipi im shumë i papërpunuar i transmetimit të videos nga një kamerë në internet për të reaguar përmes një serveri të bazuar në pion në twitch (ky është vetëm një eksperiment).

Burimi: www.habr.com

Shto një koment