Vis dažniau galima pamatyti tinklapius, kuriuose yra atkuriama video medžiaga. Vis dažniau atsiranda būtinybė šitą dalyką įgyvendinti ir pačiam (pvz. pagal klientų poreikius). Šiame straipsnelyje trumpai apžvelgsiu kelias problemėles, kurias išspręsti užėmė kiek laiko. Taip pat papasakosiu kaip išsprendžiau vaizdo atkūrimo mobiliuosiuose įrenginiuose problemą.
Video konvertavimui nuo senų laikų naudoju man geriausią ir patogiausią programą – FFMpeg. Konvertuojant video į tokį formatą (o dar geriau – į kelis formatus), kuris sėkmingai būtų atkuriamas web terpėje ne tik su kompiuteriais, bet ir su mobiliaisiais įrenginiais, reikėtų turėti omenyje kelis dalykus.
Geras web-player’is
Šiuo metu rinkoje yra didelis skaičius playerių, siūlančių stabilų atkūrimą web terpėje. O ką reiškia stabilų? Kaip žinia, skirtingos naršyklės ir skirtingi įrenginiai mėgsta (palaiko) skirtingus video formatus. Pavyzdžiui, mobilieji iĮrenginiai gerai palaiko ir, pasinaudojant HTML5, sėkmingai atkuria MP4 video, užkoduotus su H.264 kodeku, tačiau Flash video failų neatkuria. Tuo tarpu Mozilla Firefox naršyklė, pasinaudojant HTML5 negali atkurti H.264 užkoduotų failų – tam dalykui naudojamas Flash arba kiti video formatai. Naršyklių video/audio formatų palaikymas:
Dėl tokio skirtingo formatų palaikymo, rimtesnių web playerių naudojamas toks atkūrimo būdas, kai bandoma patikrinti, kokį video formatą kliento naršyklė palaiko ir pateikti jai būtent tą formatą. Savaime suprantama, kad tam reikia ir konvertuoti video į skirtingus formatus, iš kurių player’is rinktųsi labiausiai tinkama konkrečiam atvejui. Iš esmės, kaip matosi iš lentelės, naudojant vienintelį MP4 failą galima pasiekti gan neblogo palaikymo. Tačiau senesnės naršyklės tokio video neatkurtų. Naujas (man) atradimas – stabiliai veikiantis ir nemokamas MediaElement.js web video ir audio grotuvas. Jis automatiškai visas HTML5 <video> žymes puslapyje pakeičia savo konteineriu, kurį pritaiko naudojamai naršyklei. Pavyzdžiui:
<video width="640" height="480"> <source src="/kelias/iki/video.mp4" type="video/mp4" /> <source src="/kelias/iki/video.webm" type="video/webm" /> <source src="/kelias/iki/video.ogv" type="video/ogg" /> <object width="640" height="480" type="application/x-shockwave-flash" data="/kelias/iki/flashmediaelement.swf"> <param name="movie" value="/kelias/iki/flashmediaelement.swf" /> <param name="flashvars" value="controls=true&file=/kelias/iki/video.mp4" /> <img src="/kelias/iki/paveikslelio.png" width="640" height="480" alt="Nėra galimybės atkurti video." /> </object> </video>
Esant tokiam dideliam formatų pasirinkimui (MP4, Webm, OGG, Flash), mes galime būti garantuoti, kad video failas bus sėkmingai atkurtas ant bet kokios naršyklės. Aišku, kad tai yra nevienintelis geras web video grotuvas. Visų jų veikimo principas yra panašus, bet visi turi skirtingą (daugiau arba mažiau patogų) API. Vienu žodžiu, grotuvas turi turėti fallback (iš HTML5 į Flash arba atvirkščiai) palaikymą ir patogų API.
Teisingas video konvertavimas
Paskaičius FFMpeg dokumentaciją iš esmės viskas tampa aišku, ir viskas veikia taip, kaip turi. Problemos prasideda (bent jau man prasidėjo) tada, kai yra reikalavimas atkurti video ir mobiliesiems įrenginiams. Standartiškai, konvertuodamas bet kokį video į MP4 formatą naudojau tokią (aišku, priklausomai nuo situacijos su skirtingais parametrais) komandą:
ffmpeg -i pradinis_failas.avi -vcodec libx264 -r 30 -b 500k -maxrate 500k -bufsize 1000k -s 640x480 -threads 0 -acodec libvo_aacenc -ab 128k rezultato_failas.mp4
Konvertuojant į kitus formatus atitinkamai naudojami kiti (ne libx264) kodekai. Tam, kad MP4 H.264 video būtų sėkmingai atkuriamas ant mobiliųjų įrenginių ( ypač dėl šito “priekabūs” yra Android įrenginiai ), reikia, kad:
- Senesnių įrenginių palaikymui, turi būti naudojamas atitinkamas H.264 kodavimo profilis. Norint gauti didžiausią palaikymą, reikia naudoti baseline profilį. Profilis nurodomas -vprofile argumentu.
- Video rezoliucija ir bitrate’as turi būti logiškai susiję – kuo didesnė rezoliucija, tuo bitrate’as turi būti didesnis.
- Video failo struktūroje esantys atomai (blokai – ftyp, moov ir mdat) turi būti sudėti teisingu eiliškumu. Tai susiję su tuo, kad anksčiau einančiuose atomuose saugoma informacija, reikalinga video atkūrimui prieš atsiunčiant pilną video failą i įrenginį. Dauguma video konvertavimo tools’ų į tai neatsižvelgia ir sudeda šiuos blokus randominiu eiliškumu (plačiau apie šią problemą galima paskaityti čia). Dėl to, dažniausiai, net ir su teisingais parametrais sukonvertavus video failą, jis nebus teisingai siunčiamas iš web puslapio, dėl ko kils problemų bandant jį peržiūrėti per mobilųjį įrenginį. Problemos sprendimas – FFMpeg paketas qt-faststart. Ši maža programėlė sudeda blokus reikiamu eiliškumu ir po šio žingsnio MP4 video sėkmingai groja ant visų device’ų.
Taigi?
Taigi tam, kad teisingai sukonvertuoti bet kokio video formato failą į MP4 su H.264 kodeku, pasinaudojant FFMpeg, reikia įvykdyti šias komandas:
ffmpeg -i pradinisfailas.avi -vcodec libx264 -vprofile baseline -preset slow -r 30 -b:v 500k -maxrate 500k -bufsize 1000k -vf scale="480:trunc(ow/a/2)*2" -threads 0 -acodec libvo_aacenc -b:a 128k rezultatofailas_.mp4 qt-faststart rezultatofailas_.mp4 rezultatofailas.mp4
Aišku, turi būti instaliuotos visos reikiamos programos ir kodekai. Kaip tai padaryti Ubuntu operacinėje sistemoje parodyta čia. Daugiau informacijos šia tema galima rasti:
- https://www.virag.si/2012/01/web-video-encoding-tutorial-with-ffmpeg-0-9/
- http://developer.android.com/guide/appendix/media-formats.html
- http://fabiensanglard.net/mobile_progressive_playback/index.php
Kažką tu čia atžagariai darai. Sudedi viską ką vartotojas suuploadina į s3, ir paskui konvertuoji klientuoji pas klientą. Gi pilna javascript bibliotekų kurios tą daro. Tokiu būdu nereikia visos tos makalynės kurią čia parašei + sutaupai daug serverio resursų.
Truputį pakoregavau tavo komentarą, nes daug klaidų buvo.
O kur čia pasakyta, kad šitie veiksmai turi būti atliekami lokaliai? Aišku, kad geriausia yra cloud’e tai daryti, pavyzdžiui AWS’e. Bet nelabai supratau ką tu pasakyti norėjai, ypač ryšio tarp javascript ir S3. “Konvertuoji pas klientą”? Per javascript’ą? :) Jėga. Tos, kaip pavadinai, makalynės bet kuriuo atveju reikia, ir iš klientinės pusės to nepadarysi be papildomo soft’o, kurio vartotojas neturi. O jeigu tu burtininkas, tai pamokyk daryt stebuklus :)
Vat tu čia ir klysti. Pilna bibliotekų kurios naršyklėje atlieka konvertavimą. Pavyzdziui, kad ir šitas: https://github.com/mbebenita/Broadway
Taip, kad konvertavimas serveryje (taip, “cloudas” irgi serveris) tampa nebereikalingas (https://github.com/kripken/emscripten – pasižiūrėk čia, gali praktiškai bet ką, kas parašyta su c/pp/obj-c paleist naršyklėje). Ir nereiks jokių ten tavo burtų, konvertuojant serveryje, bereikalingai naudojant resursus, įrašinėjant visokias ubuntu ir panašiai :)
“The decoder expects an .mp4 file and does not support weighted prediction for P-frames and CABAC entropy encoding. To create such bitstreams use ffmpeg and x264 with the following command line options:” ir toliau vis tiek naudojama FFMpeg komanda. Dekoderis tikisi jau paruošto video. O straipsnyje kalbėjau apie H.264 encode’inimą, kad būtų kuo geresnis Native naršyklių palaikymas.
Na tai pasakai vartotojui kokius formatus priimi, ir tegu suuploadina reikiamą formatą. Čia buvo tik vienas pavyzdys. Gali pavyzdžiui pasinaudot chrome’o NaCl.
Kuo labiau riboji vartotojo galimybes arba dar blogiau, pririši prie naršyklės, tuo tai neefektyvesnis sprendimas žiūrint iš patogumo vartotojui pusės. Dėl to kažkaip ir norisi kuo universalesnio sprendimo.