ProHoster > Блог > Administrado > (Preskaŭ) senutila retkamerao fluanta de retumilo. Parto 2. WebRTC
(Preskaŭ) senutila retkamerao fluanta de retumilo. Parto 2. WebRTC
Iel en одной el malnovaj kaj jam forlasitaj artikoloj, mi skribis pri tio, kiel facile kaj nature oni povas elsendi filmeton el kanvaso per retejoj. En tiu artikolo, mi mallonge parolis pri kiel kapti video de fotilo kaj sono de mikrofono uzante MediaStream API, kiel kodi la ricevitan rivereton kaj sendi ĝin per retejsockets al la servilo. Tamen, fakte ili ne faras tion, por elsendoj ili uzas aŭ specialan programon, kiu devas esti instalita kaj agordita: senprokraste, ĉi tio povas esti Malfermu Elsendo Programaro, aŭ ili uzas WebRTC, kiu funkcias tuj el la skatolo, tio estas, ĝi ne postulas la instaladon de ajna kromaĵo al la flash player, kiu estos eltranĉita de la Chromium retumilo jam en decembro.
Hodiaŭ ni parolos pri WebRTC.
Reteja Realtempa Komunikado (WebRTC) ne estas ununura protokolo, ĝi estas tuta kolekto de normoj, protokoloj kaj JavaScript-APIoj, kiuj kune disponigas samul-al-kunulan realtempan video-aŭdan komunikadon, kaj ankaŭ povas esti uzata por transdoni ajnan. binaraj datumoj. Kutime retumiloj funkcias kiel samuloj, sed ĝi ankaŭ povas esti poŝtelefona aplikaĵo, ekzemple. Por organizi p2p komunikadon inter klientoj, retumilo subteno por diversaj specoj de video kaj audio kodigo necesas, subteno por diversaj retaj protokoloj, certigante la interago de aparataro kun la retumilo (per OS tavoloj): retkameraoj, sonkartoj. Ĉio ĉi tiu miksaĵo de teknologioj estas kaŝita malantaŭ la JavaScript API-abstraktado por la komforto de la programisto.
Ĉio resumas al tri API-oj:
MediaStream API — malmuntita lastan fojon, hodiaŭ mi skribos iom pli pri li. Servas ricevi video/aŭdiajn fluojn de la aparataro
RTCDataChannel - servas por transdoni arbitrajn datumojn inter du klientoj
Preparante sonajn kaj videofluojn por transdono
Ĉio komenciĝas per "kaptado" de la retkamerao kaj mikrofonaj amaskomunikiloj. Kompreneble, krudaj fluoj ne taŭgas por organizi telekonferencon, ĉiu rivereto devas esti prilaborita: plibonigu la kvaliton, sinkronigu audion kun video, metu sinkronigajn markojn en la videofluo, kaj certigu la bitrapidecon respondan al la konstante ŝanĝiĝanta bendolarĝo de la kanalo. . La retumilo prizorgas ĉion ĉi, la programisto eĉ ne devas zorgi pri disponigado de kodado por amaskomunikiloj. Ene de moderna retumilo, jam estas programaraj tavoloj por kapti, plibonigi kvaliton (forigi eĥon kaj bruon de sono, plibonigi la bildon), video- kaj sonkodigado. La tavolskemo estas montrita en fig. 1:
Rizo. 1. Tavoloj de audio kaj video prilaborado en la retumilo
Ĉiu prilaborado okazas rekte en la retumilo mem, sen pliaj. neniu kromaĵo bezonata. Tamen, aferoj ankoraŭ ne estas tiel rozaj por 2020. Estas retumiloj, kiuj ankoraŭ ne plene subtenas MediaStream API, vi povas sekvi la ligilon kaj vidi la kongruotabelon ĉe la fundo. IE precipe estas denove seniluziiga.
Vi povas fari tre interesajn aferojn kun la ricevitaj riveretoj: vi povas kloni, ŝanĝi la video-rezolucion, manipuli la sonkvaliton, vi povas preni kaj "alkroĉi" la Media Stream-rivereto al etikedu kaj rigardu vin sur la html-paĝo. Aŭ vi povas desegni fluon sur kanvaso, kaj agordi WebGL aŭ CSS3, kaj apliki diversajn filtrilojn al video, kapti la prilaboritan videon el kanvaso kaj poste sendi ĝin tra la reto al la servilo, transkodi kaj publikigi al ĉiuj (saluton bigo live, twitch kaj aliaj). Ĉi tie mi ne analizos kiel tiaj aferoj estas faritaj, mi donos kelkajn ekzemplojn trovitajn en la reto:
https://jeeliz.com/ - la infanoj faras realtempan CV en Javascript. Ili havas tuton arsenalo diversaj js-bibliotekoj por labori kun videofluo sur kanvaso: detekti vizaĝojn, objektojn, apliki filtrilojn (maskoj, kiel en Instagram), ktp. Bonega ekzemplo pri kiel vi povas prilabori realtempan videon rekte en la retumilo sen aldonaj kromprogramoj.
Kanvas captureStream API - API-dokumentado por kapti videofluon el kanvaso. Jam subtenata en Chrome, Opera kaj Firefox
RTCPeerConnection
Do ni venis al la afero, sed kiel efektive transdoni la videon al alia uzanto? Venas al la antaŭo RTCPeerConnection. Resume, preskaŭ ĉe ĉi tiu paŝo vi devas krei objekton RTCPeerConnection:
Ni specifas iceServers kiel unu el la ebloj - ĉi tiu estas servilo kiu helpas havigi konekton inter du retumiloj malantaŭ NAT'om. Tio estas, la problemo estas solvita ĉi tie: kiel ekscii la ip de la interparolanto se li estas malantaŭ la NAT de sia provizanto? La ICE-protokolo venas al la savo, fakte, ICE tute ne validas por WebRTC, sed pli pri tio poste.
Antaŭe, ni ricevis Usermedia-fluojn:
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);
Poste, la evento de negotiationneeded pafas sur la peerConnection, en kies prizorganto ni devas krei oferton (laŭ SDP - Session Description Protocol) kaj asigni ĝin al la peerConnection per la setLocalDescription-metodo. Pri SDP - kio ĝi estas kaj pri la oferto kaj respondformatoj - ni parolos plu.
Post atribuado de LocalDescription peerConnection, la retumilo "kunvenas" glacikandidatojn, tio estas, trovas diversajn manierojn komuniki per NAT. La unuonicegatheringstatechange-okazaĵo pafas. En la pritraktilo onicegatheringstatechange, ni permesas konekton al la webrtc-signaling-server-rivereto interŝanĝi la Seanca Priskribon inter samuloj:
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);
}
};
La webrtc-signaling-server estas la servilo postulata por interŝanĝi la seanpriskribon inter du samuloj, ĝi povas esti la plej simpla retsocket aŭ xhr-servilo sur iu PL. Ĝia tasko estas simpla: akcepti seancan priskribon de unu samaĝulo kaj transdoni ĝin al alia.
Post la interŝanĝo de Sesiaj priskriboj, ambaŭ flankoj pretas elsendi kaj ricevi videofluojn, ĉe la flanko, kiu ricevas la videofluon, la onttrack-evento estas ekigita sur la peerConnection, en kies prizorganto, la ricevitaj trakoj povas esti asignitaj al kaj rigardu vian plej ŝatatan interparolanton. Plia teorio kaj detaloj.
https://hpbn.co/ - Book High Performance Folium Networking. La aferoj pri certigo de alta rendimento de TTT-aplikoj estas detale diskutitaj. Ĉe la fino, WebRTC estas priskribita. La libro certe estas malnova (2013), sed ne perdas sian gravecon.
En la sekva parto, mi volas doni iom pli da teorio kaj praktike analizi la ricevon kaj prilaboradon de videofluo en la servilo uzante pion, transkodi al HLS per ffmpeg por posta elsendo al spektantoj en la retumilo.