(Næstum) gagnslaus vefmyndavél sem streymir úr vafra. Part 2. WebRTC

Einhvern veginn inn одной úr gömlum og þegar yfirgefnum greinum skrifaði ég um hversu auðveldlega og eðlilegt þú getur útvarpað myndbandi af striga í gegnum nettengi. Í þeirri grein talaði ég stuttlega um hvernig á að taka myndband úr myndavél og hljóð úr hljóðnema með því að nota MediaStream API, hvernig á að umrita móttekna strauminn og senda hann í gegnum nettengi á netþjóninn. Hins vegar, í raun og veru gera þeir þetta ekki, fyrir útsendingar nota þeir annað hvort sérstakan hugbúnað sem þarf að setja upp og stilla: strax, þetta getur verið Open Broadcast Software, eða þeir nota WebRTC, sem virkar beint úr kassanum, það er, það krefst ekki uppsetningar á neinum viðbótum a la flash spilara, sem verður klippt úr Chromium vafranum þegar í desember.

Í dag munum við tala um WebRTC.

Web Real-Time Communication (WebRTC) er ekki ein samskiptaregla, það er heilt safn af stöðlum, samskiptareglum og JavaScript API sem saman veita jafningja-til-jafningi rauntíma mynd- og hljóðsamskipti og er einnig hægt að nota til að flytja hvaða tvöfaldur gögn. Venjulega virka vafrar sem jafningjar, en það getur líka verið farsímaforrit, til dæmis. Til að skipuleggja p2p samskipti á milli viðskiptavina þarf vafrastuðning fyrir ýmsar gerðir af mynd- og hljóðkóðun, stuðning við margs konar netsamskiptareglur, sem tryggir samspil vélbúnaðar við vafrann (í gegnum stýrikerfislög): vefmyndavélar, hljóðkort. Allur þessi ógrynni af tækni er falinn á bak við JavaScript API útdráttinn til þæginda fyrir þróunaraðilann.

Þetta snýst allt um þrjú API:

  • MediaStream API — tók í sundur síðast, í dag ætla ég að skrifa aðeins meira um hann. Þjónar til að taka á móti myndbandi / hljóðstraumum frá vélbúnaðinum

  • RTCPeerConnection — veitir samskipti milli tveggja viðskiptavina (p2p)

  • RTCDataChannel - þjónar til að flytja handahófskennd gögn milli tveggja viðskiptavina

Undirbúningur hljóð- og myndstrauma fyrir sendingu

Þetta byrjar allt með því að „handtaka“ vefmyndavélina og hljóðnemana fjölmiðlastraumana. Auðvitað henta hrástraumar ekki til að skipuleggja fjarfund, það þarf að vinna úr hverjum straumi: bæta gæði, samstilla hljóð við myndband, setja samstillingarmerki í myndbandsstrauminn og tryggja bitahraða sem samsvarar síbreytilegri bandbreidd rásarinnar . Vafrinn sér um allt þetta, verktaki þarf ekki einu sinni að hafa áhyggjur af því að útvega kóðun fyrir fjölmiðlastrauma. Inni í nútíma vafra eru nú þegar hugbúnaðarlög til að fanga, bæta gæði (fjarlægja bergmál og hávaða úr hljóði, bæta myndina), myndbands- og hljóðkóðun. Lagakerfið er sýnt á mynd. 1:

(Næstum) gagnslaus vefmyndavél sem streymir úr vafra. Part 2. WebRTCHrísgrjón. 1. Lög af hljóð- og myndvinnslu í vafranum

Öll vinnsla fer fram beint í vafranum sjálfum, ekkert aukaatriði. engin viðbætur krafist. Hins vegar eru hlutirnir enn ekki svo bjartir fyrir árið 2020. Það eru vafrar sem styðja ekki að fullu MediaStream API, þú getur fylgst með hlekknum og séð eindrægnitöfluna neðst. Sérstaklega IE veldur aftur vonbrigðum.

Þú getur gert mjög áhugaverða hluti með mótteknum straumum: þú getur klónað, breytt myndbandsupplausninni, hagrætt hljóðgæðum, þú getur tekið og „tengið“ Media Stream strauminn við merktu og skoðaðu sjálfan þig á html síðunni. Eða þú getur teiknað straum á striga, og stillt WebGL eða CSS3, og notað ýmsar síur á myndband, tekið unnið myndband af striga og sent það síðan yfir netið á netþjóninn, umritað og birt til allra (halló bigo live, twitch og aðrir). Hér mun ég ekki greina hvernig slíkt er gert, ég mun gefa nokkur dæmi sem finnast á vefnum:

https://jeeliz.com/ - strákarnir eru að gera rauntíma ferilskrá í Javascript. Þeir hafa heild vopnabúr ýmis js bókasöfn til að vinna með vídeóstraumi á striga: greina andlit, hluti, setja á síur (grímur, eins og á Instagram) o.s.frv. Frábært dæmi um hvernig hægt er að vinna úr rauntíma myndbandi beint í vafranum án viðbótarviðbóta.

Canvas captureStream API - API skjöl til að taka myndstraum af striga. Nú þegar stutt í Chrome, Opera og Firefox

RTCPeerConnection

Svo við komum að því atriði, en hvernig á að flytja myndbandið til annars notanda? Kemur til sögunnar RTCPeerConnection. Í stuttu máli, í næstum þessu skrefi þarftu að búa til RTCPeerConnection hlut:

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

Við tilgreinum iceServers sem einn af valmöguleikunum - þetta er þjónn sem hjálpar til við að veita tengingu milli tveggja vafra á bak við NAT'om. Það er, vandamálið er leyst hér: hvernig á að finna út ip viðmælanda ef hann er á bak við NAT þjónustuveitunnar hans? ICE siðareglur koma til bjargar, reyndar á ICE alls ekki við um WebRTC, en meira um það síðar.

Áður fengum við Usermedia strauma:

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

Næst kviknar nauðsynlegur atburður á peerConnection, þar sem við verðum að búa til tilboð (í skilmálar af SDP - Session Description Protocol) og úthluta því til peerConnection með setLocalDescription aðferðinni. Um SDP - hvað það er og um tilboð og svarsnið - munum við tala frekar.

Eftir að hafa úthlutað LocalDescription peerConnection, "semur" vafrinn saman ísframbjóðendur, það er að segja finnur ýmsar leiðir til að hafa samskipti í gegnum NAT. The onicegatheringstatechange atburður logar. Í onicegatheringstatechange meðhöndluninni leyfum við tengingu við webrtc-signaling-server strauminn til að skiptast á lotulýsingu á milli jafningja:

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-merkjaþjónninn er þjónninn sem þarf til að skiptast á lotulýsingu á milli tveggja jafningja, hann getur verið einfaldasti nettengi eða xhr-þjónn á hvaða PL sem er. Verkefni þess er einfalt: að samþykkja lotulýsingu frá einum jafningja og flytja hana yfir á annan.

Eftir að skipt hefur verið á lotulýsingum eru báðar hliðar tilbúnar til að útvarpa og taka á móti myndstraumum, á þeirri hlið sem tekur á móti myndbandsstraumnum er ontrack atburðurinn settur af stað á peerConnection, í meðhöndlun þess er hægt að úthluta mótteknum lögum til og skoðaðu uppáhalds viðmælandann þinn. Frekari kenning og smáatriði.

Tenglar og bókmenntir:

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection - skjöl RTCPeerConnection

https://github.com/pion/webrtc - innleiðing á WebRTC samskiptareglum á ferðinni

https://webrtcforthecurious.com/ - bók frá höfundum pion

https://hpbn.co/ - Bókaðu afkastamikið vafranet. Fjallað er ítarlega um þau atriði að tryggja afkastamikil afköst vefforrita. Í lokin er WebRTC lýst. Bókin er vissulega gömul (2013), en missir ekki mikilvægi.

Í næsta hluta vil ég gefa aðeins meiri hluta af kenningum og í framkvæmd að greina móttöku og vinnslu myndbandsstraums á þjóninum með því að nota pion, umkóðun yfir í HLS í gegnum ffmpeg fyrir síðari útsendingu til áhorfenda í vafranum.

Fyrir óþolinmóða: mjög grófa frumgerð mín af því að senda út myndband frá vefmyndavél til að bregðast við í gegnum pion-byggðan netþjón í twitch (þetta er bara tilraun).

Heimild: www.habr.com

Bæta við athugasemd