Brauzerdan (deyarli) foydasiz veb-kamera oqimi. 2-qism. WebRTC

Qandaydir tarzda одной eski va allaqachon tashlab qo'yilgan maqolalardan men veb-soketlar orqali kanvasdan videoni qanchalik oson va tabiiy ravishda translyatsiya qilishingiz mumkinligi haqida yozdim. O'sha maqolada men kameradan video va mikrofondan qanday qilib ovoz olish haqida qisqacha gapirib berdim MediaStream API, natijada paydo bo'lgan oqimni qanday kodlash va uni veb-soketlar orqali serverga yuborish. Biroq, aslida ular buni qilmaydi; eshittirishlar uchun ular o'rnatilishi va sozlanishi kerak bo'lgan maxsus dasturlardan foydalanadilar: bu mening boshimdan tashqarida bo'lishi mumkin. Ochiq Translyatsiya Software, yoki ular to'g'ridan-to'g'ri ishlaydigan WebRTC-dan foydalanadilar, ya'ni dekabr oyida Chromium brauzeridan uzib qo'yiladigan ala flesh-pleer plaginlarini o'rnatishni talab qilmaydi.

Bugun biz WebRTC haqida gaplashamiz.

Web Real-Time Communication (WebRTC) bu bitta protokol emas, bu standartlar, protokollar va JavaScript API-larning butun to'plami bo'lib, ular birgalikda real vaqtda tengdoshga video-audio aloqasini ta'minlaydi va shuningdek, istalgan ma'lumotlarni uzatish uchun ishlatilishi mumkin. ikkilik ma'lumotlar. Odatda brauzerlar tengdosh sifatida ishlaydi, lekin u, masalan, mobil ilova bo'lishi mumkin. Mijozlar o'rtasida p2p aloqasini tashkil qilish uchun har xil turdagi video va audio kodlash uchun brauzerni qo'llab-quvvatlash, turli xil tarmoq protokollarini qo'llab-quvvatlash, apparatning brauzer bilan o'zaro ta'sirini ta'minlash (OS qatlamlari orqali): veb-kameralar, ovoz kartalari. Bu texnologiyalarning barchasi ishlab chiquvchiga qulaylik yaratish uchun JavaScript API abstraksiyasi orqasida yashiringan.

Hammasi uchta API-ga tushadi:

  • MediaStream API — oxirgi marta demontaj qilingan, bugun men u haqida bir oz ko'proq yozaman. Uskunadan video / audio oqimlarini qabul qilish uchun xizmat qiladi

  • RTCPeerConnection - ikki mijoz o'rtasidagi aloqani ta'minlaydi (p2p)

  • RTCDataChannel — ikki mijoz oʻrtasida oʻzboshimchalik bilan maʼlumotlarni uzatish uchun foydalaniladi

Audio va video oqimlarni uzatish uchun tayyorlash

Hammasi veb-kamera va mikrofondan media oqimlarini "qo'lga olish" bilan boshlanadi. Xom oqimlar, albatta, telekonferentsiyani tashkil qilish uchun mos emas; har bir oqim qayta ishlanishi kerak: sifatni yaxshilash, audioni video bilan sinxronlashtirish, video oqimiga sinxronizatsiya belgilarini joylashtirish va doimiy o'zgaruvchan tarmoqli kengligiga mos keladigan bit tezligini ta'minlash. kanal. Brauzer bularning barchasiga g'amxo'rlik qiladi; ishlab chiquvchi media oqimlarini kodlash haqida tashvishlanishga ham hojat yo'q. Zamonaviy brauzer ichida allaqachon suratga olish, sifatni yaxshilash (ovozdan aks-sado va shovqinni olib tashlash, tasvirni yaxshilash), video va audio kodlash uchun dasturiy ta'minot qatlamlari mavjud. Qatlam diagrammasi rasmda ko'rsatilgan. 1:

Brauzerdan (deyarli) foydasiz veb-kamera oqimi. 2-qism. WebRTCGuruch. 1. Brauzerda audio va videolarni qayta ishlash qatlamlari

Barcha ishlov berish to'g'ridan-to'g'ri brauzerning o'zida amalga oshiriladi, qo'shimcha yo'q. plaginlar talab qilinmaydi. Biroq, 2020 yil uchun hamma narsa unchalik qizg'in emas. Hali to'liq qo'llab-quvvatlamaydigan brauzerlar mavjud MediaStream API, siz havolani kuzatib borishingiz va eng pastdagi muvofiqlik jadvalini ko'rishingiz mumkin. Ayniqsa, IE yana umidsizlikka tushadi.

Olingan oqimlar bilan siz juda qiziqarli narsalarni qilishingiz mumkin: siz klonlashingiz, video piksellar sonini o'zgartirishingiz, audio sifatini o'zgartirishingiz, Media Stream oqimini qabul qilishingiz va unga “birikishingiz” mumkin. teg va html sahifasida o'zingizga qarang. Yoki siz kanvasda oqim chizishingiz, WebGL yoki CSS3-ni o'rnatishingiz va videoga turli filtrlarni qo'llashingiz, qayta ishlangan videoni tuvaldan olishingiz va keyin uni tarmoq orqali serverga yuborishingiz, transkod qilishingiz va hammaga nashr qilishingiz mumkin (salom bigo live, twitch) va boshqalar). Bu erda men bunday narsalar qanday amalga oshirilishini tahlil qilmayman, men Internetda topilgan bir nechta misollarni keltiraman:

https://jeeliz.com/ - yigitlar real vaqt rejimida Javascriptda CV tayyorlamoqda. Ularda bir butun bor arsenal Tuvaldagi video oqimi bilan ishlash uchun turli JS kutubxonalari: yuzlarni, ob'ektlarni aniqlash, filtrlarni qo'llash (Instagramdagi kabi maskalar) va boshqalar. Qo'shimcha plaginlarsiz to'g'ridan-to'g'ri brauzerda real vaqtda videoni qanday qayta ishlashingiz mumkinligiga ajoyib misol.

Canvas captureStream API - Tuvaldan video oqimini olish uchun API hujjatlari. Chrome, Opera va Firefox-da allaqachon qo'llab-quvvatlanadi

RTCPeerConnection

Endi biz savolga keldik: videoni boshqa foydalanuvchiga qanday o'tkazish mumkin? Oldinga chiqadi RTCPeerConnection. Muxtasar qilib aytganda, deyarli ushbu bosqichda siz RTCPeerConnection ob'ektini yaratishingiz kerak:

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

Variantlardan biri iceServers - bu NAT orqasida joylashgan ikkita brauzer o'rtasida ulanishni ta'minlashga yordam beradigan server. Ya'ni, muammo bu erda hal qilinadi: suhbatdoshning IP-ni uning provayderining NAT-ning orqasida bo'lsa, qanday aniqlash mumkin? ICE protokoli yordamga keladi; aslida ICE WebRTC bilan umuman bog'liq emas, lekin bu haqda keyinroq.

Ilgari bizda Usermedia oqimlari bor edi:

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

Keyinchalik, onnegotiationneeded hodisasi peerConnection-da ishga tushadi, uning ishlov beruvchisida biz taklif yaratishimiz kerak (SDP - Sessiya tavsifi protokoli bo'yicha) va uni setLocalDescription usuli orqali peerConnection-ga tayinlashimiz kerak. SDP haqida - bu nima va taklif va javob formatlari haqida - biz bundan keyin gaplashamiz.

LocalDescription peerConnection-ni tayinlagandan so'ng, brauzer muz nomzodlarini "to'playdi", ya'ni NAT orqali aloqa qilish uchun turli yo'llarni topadi. onecegatheringstatechange hodisasi yonadi. Onicegatheringstatechange ishlov beruvchisida biz tengdoshlar o'rtasida Sessiya tavsifini almashish uchun webrtc-signaling-server oqimiga ulanishga ruxsat beramiz:

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 - bu ikki tengdosh o'rtasida sessiya tavsifi almashinuvini ta'minlash uchun zarur bo'lgan server; u istalgan tilda oddiy websocket yoki xhr server bo'lishi mumkin. Uning vazifasi oddiy: bir tengdoshdan sessiya tavsifini qabul qiling va uni boshqasiga yuboring.

Sessiya tavsiflari almashgandan so'ng, ikkala tomon ham video oqimlarni translyatsiya qilish va qabul qilishga tayyor, video oqimini qabul qiluvchi tomonda, peerConnection-da ontrack hodisasi ishga tushiriladi, uning ishlov beruvchisida qabul qilingan treklar tayinlanishi mumkin. va sevimli suhbatdoshingizga qarang. Qo'shimcha nazariya va tafsilotlar.

Havolalar va adabiyotlar:

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

https://github.com/pion/webrtc - yo'lda WebRTC protokollarini amalga oshirish

https://webrtcforthecurious.com/ - pion ijodkorlarining kitobi

https://hpbn.co/ - Yuqori samarali brauzer tarmog'ini kitob qiling. Veb-ilovalarning yuqori unumdorligini ta'minlash masalalari batafsil ko'rib chiqiladi. Oxirida WebRTC tavsiflanadi. Kitob, albatta, eski (2013), lekin o'z ahamiyatini yo'qotmaydi.

Keyingi qismda men nazariyaning biroz ko'proq qismini bermoqchiman va amalda pion yordamida serverda video oqimini qabul qilish va qayta ishlashni tahlil qilish, ffmpeg orqali HLS-ga transkodlash, keyinchalik brauzerda tomoshabinlarga translyatsiya qilish uchun.

Sabrsizlar uchun: Twitch-dagi pion-ga asoslangan server orqali reaksiyaga kirishish uchun veb-kameradan video translyatsiya qilishning juda qo'pol prototipi (bu shunchaki tajriba).

Manba: www.habr.com

a Izoh qo'shish