Videoclip online cu Wowza și Amazon Elastic Transcoder
Publicat: 2022-03-11Succesul și adoptarea oricărei aplicații web astăzi depind în mare măsură de performanța, flexibilitatea și ușurința sa de utilizare.
În special în lumea ADHD de astăzi, utilizatorii își vor pierde rapid răbdarea cu o aplicație dacă încărcarea paginii acesteia durează prea mult. Pentru aplicațiile web care trebuie să accepte procesarea video – care este în mod inerent intensă în calcul și I/O – această provocare este deosebit de acută. Cu toate acestea, utilizatorii devin din ce în ce mai pretențioși, dorind ca videoclipurile lor să fie de înaltă calitate și să se încarce rapid, chiar dacă rulează pe un smartphone sau o tabletă.
De asemenea, utilizatorii pierd toleranța față de aplicațiile web care nu funcționează pe browserul sau dispozitivul preferat sau care nu acceptă formatul de date de care au nevoie pentru a le încărca sau exporta. Prin urmare, diversitatea formatelor video care trebuie acceptate face, de asemenea, încorporarea suportului video într-o aplicație web deosebit de dificilă.
Această postare descrie modul în care am folosit eficient tehnologiile open source și serviciile bazate pe cloud pentru a încorpora capabilități video într-o aplicație web bazată pe PHP.
Utilizare caz
Am făcut parte dintr-o echipă care trebuia să dezvolte un site web asemănător YouTube, unde utilizatorii înregistrați să poată încărca și partaja videoclipurile lor.
Sistemul trebuia să permită utilizatorilor înregistrați să își încarce videoclipurile într-o varietate de formate acceptate, care urmau să fie apoi convertite într-un format comun (MP4). De asemenea, trebuia să generăm un set de miniaturi și un colaj de imagini pentru a fi folosit în playerul video pentru a afișa cadrele pe o bară de progres video.
Lucrurile s-au complicat și mai mult de faptul că cerințele clienților ne-au împiedicat să folosim orice CDN sau API-uri de transcodare disponibile, așa că trebuia să ne dezvoltăm soluția de la zero.
Încărcare video
Deoarece procesul de încărcare în sine nu trebuia să fie specific videoclipului (aveam nevoie doar de o capacitate de încărcare a fișierelor ușor de utilizat), era logic să folosim o soluție open source existentă, mai degrabă decât să o folosim pe a noastră. Am selectat jQuery-File-Upload, în primul rând pentru că suporta două caracteristici esențiale în cazul nostru; și anume, o bară de progres de încărcare și încărcări în bucăți.
Încărcarea fragmentată ne-a permis să permitem unui utilizator să încarce un fișier video de aproape orice dimensiune (mai ales important pentru a accepta fișiere video la rezoluție HD). Cu această abordare, fișierul este împărțit în mai multe „bucăți” pe front-end, care invocă acțiunea de încărcare cu fiecare bucată de date (împreună cu metadatele pentru fiecare bucată, cum ar fi numărul de bloc și dimensiunea totală a fișierului). Fișierul video complet este apoi reasamblat pe back-end. De altfel, includerea numărului de fragmente în metadate sa dovedit deosebit de importantă, deoarece unele browsere (cum ar fi Mobile Safari) au tendința de a transmite bucățile în ordine aleatorie.
Procesare video online
Procesarea video poate fi la fel de simplă ca capturarea cadrelor ca imagini statice sau poate implica operații mai complexe, cum ar fi îmbunătățirea imaginii, stabilizarea fluxului video și așa mai departe. În cazul nostru, singurele cerințe de procesare video au fost (a) extragerea de codecuri video și alte metadate cheie și (b) generarea unui set de miniaturi și a unui colaj de imagini (pentru a fi utilizat în playerul video pentru a afișa cadrele progresului unui videoclip). bar).
FFmpeg – o bibliotecă cu sursă deschisă folosită pe scară largă, distribuită gratuit – a fost extrem de utilă în îndeplinirea acestor cerințe. FFmpeg oferă o soluție completă, multiplatformă pentru înregistrarea, conversia și transmiterea în flux a fișierelor audio și video. De asemenea, poate fi folosit pentru a converti videoclipuri și pentru a face editare simplă (de exemplu, tăierea, tăierea, adăugarea unui filigran etc.).
În scopurile noastre, am putut folosi FFmpeg pentru a împărți videoclipul în zece secțiuni și apoi a captura o miniatură pentru fiecare secțiune pentru a oferi funcționalitatea necesară.
Din păcate, totuși, nu există legături de limbaj PHP pentru biblioteca FFmpeg. Drept urmare, singura modalitate de a folosi FFmpeg din PHP este să invocați binarul din linia de comandă folosind comenzile de sistem. Există practic două moduri de a folosi FFmpeg în PHP:
- libav. Libav este un proiect de software gratuit, derivat de la FFmpeg în 2011, care produce biblioteci și programe pentru manipularea datelor multimedia. Pe Ubuntu, de exemplu, aceasta poate fi instalată cu comanda
sudo apt-get install libav-tools
. Comenzile libav sunt compatibile cu FFmpeg și avconv. PHP trebuie să aibă acces la linia de comandă laffmpeg/avconv
pentru a utiliza acest lucru în mod programatic. - PHP-FFMPeg. PHP-FFMPeg este un driver PHP orientat pe obiecte pentru binarul FFMpeg. Poate fi accesat prin simpla executare
composer update "php-ffmpeg/php-ffmpeg"
.
Am folosit PHP-FFMPeg, deoarece oferă acces ușor la funcționalitatea FFmpeg de care eram interesați. De exemplu, clasa FFProbe
din acest pachet vă permite să primiți informații despre codecuri sau lungimea unui anumit fișier video, după cum urmează:
$ffprobe = FFMpeg\FFProbe::create(); $ffprobe ->format('/path/to/video/mp4') // extracts file informations ->get('duration');
De asemenea, FFmpeg facilitează salvarea oricărui cadru video:
$ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('video.mpg'); $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) ->save('frame.jpg');
Exemplu de cod mai detaliat este disponibil aici.
O notă de precauție: din cauza unor legi privind brevetele, nu toate codecurile pot fi procesate de FFmpeg și unele formate nu sunt acceptate corect (sau complet). Îmi amintesc că m-am luptat cu câțiva ani în urmă, de exemplu, cu formatul .3gp
, când suportul pentru telefoanele cu caracteristici era o necesitate.
La coadă
După ce obținem codecurile și alte metadate ale unui videoclip, împingem videoclipul într-o coadă de conversie FIFO (primul intrat, primul ieșit). Coada a fost implementată folosind un script cron simplu care selectează un anumit număr de videoclipuri neprocesate de fiecare dată când rulează și le transmite unui utilitar de conversie (exemplu de cod sursă disponibil aici).
Utilitarul de conversie invocă FFMpeg pentru a efectua conversia și marchează fiecare videoclip ca fiind procesat.
De asemenea, am dezvoltat un mecanism simplu de estimare a timpului de așteptare, care calculează timpul mediu de conversie a 1 minut de videoclip. Folosind această medie, putem calcula și afișa pentru utilizator timpul estimat de procesare rămas după ce un videoclip s-a terminat de încărcat, în funcție de câte minute de videoclip rămân de procesat.
Conversie format video
Anumite formate recunoscute universal (cum ar fi JPEG și GIF) au apărut pentru imaginile statice care sunt în esență acceptate de toate dispozitivele și software-ul de procesare a imaginilor. În timp ce unele formate video sunt mai comune decât altele, nu a apărut încă un astfel de format acceptat universal pentru videoclipuri.
În cazul nostru, pe lângă nevoia de a converti dintr-o varietate de formate într-un singur format comun (MPEG-4), aveam nevoie ca videoclipurile convertite să fie optimizate pentru streaming pe dispozitive mobile.
Pentru conversia formatului video (cel puțin pentru nevoile noastre pe termen scurt), utilizarea Amazon Elastic Transcoder bazată pe cloud a fost cea mai bună opțiune disponibilă. Pe lângă ușurința generală de utilizare, serviciul de transcoder se ocupă de optimizare și de toate setările de codificare. Din fericire, este disponibil un SDK AWS pentru PHP, ceea ce simplifică invocarea serviciului din codul nostru PHP.
Notă: Utilizarea unui serviciu bazat pe cloud, cum ar fi Amazon Elastic Transcoder, este grozavă dacă doriți să începeți să rulați rapid. Cu toate acestea, rețineți că această opțiune poate deveni costisitoare pentru clientul dvs., mai ales dacă modelul său de afaceri este probabil să necesite utilizarea pe scară largă a videoclipurilor mari. Un alt factor de luat în considerare este că nu trebuie neapărat să presupuneți că videoclipurile sau modelul de afaceri ale clientului dvs. vor fi compatibile cu Termenii și condițiile.

Amazon își folosește elementele de bază de stocare și calcul, S3 (Serviciul de stocare simplu) și EC2 (Elastic Compute Cloud) – combinate cu Auto Scaling și SNS (Serviciul de notificare simplu) – pentru a oferi capacitatea de a crește și de a reduce practic instantaneu.
Instalarea aws-sdk este simplă, deoarece Amazon menține o versiune a pachetului care poate fi instalată de Composer. Pur și simplu adăugați ”aws/aws-sdk-php": "2.*"
în fișierul dvs. composer.json
și faceți o composer update
.
Evident, accesarea Amazon Elastic Transcoder necesită un cont Amazon, așa că va trebui să-l configurați și dacă dvs. (sau clientul dvs.) nu aveți deja unul.
Utilizarea serviciului Amazon Elastic Transcoder a presupus mai întâi încărcarea fișierelor video într-un compartiment corespunzător pe S3. Apoi am făcut ca jobul de transcoder să fie responsabil pentru decodare și generarea unei miniaturi care, la finalizare, postează o solicitare HTTP la adresa specificată. Acest lucru necesită o anumită configurație în panoul AWS, dar este destul de simplu și Amazon oferă o documentație bună despre cum să faceți acest lucru.
Simțiți-vă liber să utilizați pachetul nostru de transcoder, care ajută la simplificarea integrării pentru Symfony 2. Include o descriere de utilizare și oferă un controler pentru implementarea rapidă a unui serviciu de notificare trimis de Amazon pentru a colecta informații despre videoclipul procesat. Un exemplu de utilizare este disponibil aici.
În plus, aici este disponibil un exemplu de controlor care gestionează notificările Amazon, care implementează și confirmarea unei adrese de abonament. Serviciul va posta mai întâi adresa URL de vizitat pentru a confirma că acesta este un receptor de notificare valid. Tot ceea ce este necesar este să marcați videoclipul ca procesat. De atunci, putem folosi videoclipul transcodat care este stocat în cloud.
Streaming
Streaming video este o capacitate care necesită performanțe ridicate: așteptările utilizatorilor pentru streaming neîntrerupt sunt mari și toleranța pentru latență este extrem de scăzută. Această provocare este adesea exacerbată de necesitatea de a transmite în flux video către mai mulți clienți simultan, în timp real.
În cazul nostru, trebuia să sprijinim fiecare utilizator să își poată crea propriul canal video și să înceapă difuzarea. Soluția noastră a constat din trei componente:
- Bord. Aplicație care servește ca tablou de bord al unui streamer, oferind posibilitatea de a difuza videoclipuri.
- Vizualizator. Client video care consumă și afișează un flux video.
- Motor de streaming. Serviciu de streaming video bazat pe cloud.
Pe lângă faptul că tehnologia Video on Demand (VOD) este încă în evoluție, o altă problemă cu care ne-am confruntat a fost că accesul la cameră nu era bine acceptat și oferea doar o conexiune P2P. De asemenea, scopul nostru a fost să oferim difuzare online pentru mai mulți utilizatori concurenți. În plus, suportul pentru getUserMedia/Stream
API (prevăzut anterior ca elementul <device>
) nu este încă consecvent în browserele moderne. Pe baza acestor factori, am decis să folosesc tehnologia Flash, deoarece era într-adevăr singura alegere rezonabilă. Prin urmare, ambele aplicații (Dashboard și Viewer) au fost implementate folosind Flex și ActionScript .
Pentru motorul de streaming, am folosit Wowza . Deși există și alte soluții necomerciale (cum ar fi Red5, care este comercializat în esență ca înlocuitor de dropin pentru Wowza), în cazul nostru, suportul pentru produse comerciale a fost un factor important. De asemenea, cel puțin în momentul în care construiam sistemul, Wowza oferea documentație mai bună, ceea ce reprezenta un avantaj suplimentar. (Rețineți că puteți obține o versiune de probă a Wowza gratuit timp de 30 de zile și, de asemenea, există o versiune de probă a dezvoltatorului pe care o puteți utiliza până la 180 de zile. Dar există anumite limitări; streaming poate funcționa numai pentru doi clienți și există o limită privind numărul maxim de conexiuni.)
Wowza Streaming Engine
Am folosit aplicația LiveStream furnizată cu Wowza. Pentru a-l configura, lăsați goale applications/app_name
și în conf/app_name
copiați fișierul Application.xml
din catalogul conf
. Editați fișierul pentru a configura secțiunea <Streams>
după cum urmează:
<Streams> <StreamType>live</StreamType> <StorageDir>${com.wowza.wms.context.VHostConfigHome}/content</StorageDir> <KeyDir>${com.wowza.wms.context.VHostConfigHome}/keys</KeyDir> <LiveStreamPacketizers></LiveStreamPacketizers> <Properties></Properties> </Streams>
Parametrul cheie este <StreamType>live</StreamType>
care definește că acesta va fi un flux dintr-un flux video live (de exemplu, o cameră). Rețineți că, după editarea și salvarea acestui fișier, va trebui să reporniți Wowza.
Aplicații Flash (Flex/ActionScript).
Flash oferă un sistem complet integrat pentru a conecta o cameră și un microfon la un server de streaming Wowza. Acest lucru este util în special dacă experiența dvs. cu ActionScript este limitată.
Întreaga aplicație se bazează în esență pe interacțiunea dintre următoarele obiecte:
- NetConnection. Clasa NetConnection creează o conexiune bidirecțională între un client și un server. Clientul poate fi o aplicație Flash Player sau AIR. Serverul poate fi un server web, Flash Media Server, un server de aplicații care rulează Flash Remoting sau serviciul Adobe Stratus.
- Aparat foto. Clasa Camera este utilizată pentru a captura video de la sistemul client sau camera dispozitivului.
- Microfon. Clasa Microfon este folosită pentru a monitoriza sau capta sunetul de la un microfon.
- NetStream. Clasa NetStream deschide un canal de streaming unidirecțional printr-o NetConnection.
În primul rând, ne conectăm la serverul de streaming Wowza folosind instanța NetConnection și apoi atașăm ascultătorul de evenimente care va asculta modificările stării conexiunii la rețea:
nc = new NetConnection(); nc.connect(serverAddress:string); nc.addEventListener( NetStatusEvent.NET_STATUS, // event type eNetStatus, // listener function false, // use capture? 0, // priority true // use weak reference? );
Iată un exemplu minimalist de ascultător de evenimente care conectează camera și microfonul la serverul de streaming:
private function eNetStatus(e:NetStatusEvent):void { switch (e.info.code) { case "NetConnection.Connect.Success": camera = Camera.getCamera(); mic = Microphone.getMicrophone(); ns = new NetStream(nc); ns.publish(streamName, "live"); ns.attachCamera(camera); ns.attachAudio(mic); break; case "NetConnection.Connect.Closed": // debug trace... display user message break; }
Codul clientului este foarte asemănător, cu excepția faptului că afișăm doar intrarea video pe partea utilizatorului. Acest lucru se face prin conectarea fluxului la obiectul Video
, așa cum se arată în acest exemplu simplu:
if(event.info.code == "NetConnection.Connect.Success") { ns = new NetStream(nc); ns.client = nsClient; ns.addEventListener(NetStatusEvent.NET_STATUS, nsClient.onNetStatus); ns.play(streamName); video = new Video(); addChild(video); // this will display video video.attachNetStream(ns); // connect NetStream to video }
Învelire
Se poate aștepta ca fluxul live și video să joace un rol din ce în ce mai important în aplicațiile mobile și web. Prin urmare, este important ca dezvoltatorii web să se familiarizeze cu transcodarea, procesarea și streamingul video. Numeroase instrumente, biblioteci și servicii există astăzi pentru încorporarea acestor capabilități în aplicațiile web. Acest articol arată cum am folosit și integrat mai multe dintre aceste tehnologii pentru a crea cu succes un site de bază asemănător YouTube cu relativă ușurință.