FFmpeg
FFmpeg - konverzija i titlovi
FFmpeg je moćno parče softvera sposobno da dekodira, enkodira, transkodira, strimuje, filtrira i pušta skoro sve poznate formate medijskih fajlova, počev od onih zastarelih pa do savrmenih tek uvedenih u primenu.
- Instalacija je jednostavna:
1sudo apt install ffmpeg
2ffmpeg -formats # formati koje podržava
3ffmpeg -codecs # lista kodeka koje se instaliraju sa njim
Ja ću se ovde fokusirati na 2 slučaja zanimljiva običnim korisnicima:
- Konverziju video i audio fajlova u smislu promene formata, bitrejta, rezolucije, tipa kompresije itd. , što smanjuje izlaznu veličinu ali uz gubitak kvaliteta prikaza.
- Ugrađivanje titlova u video fajlove, kao i lepljenje (hardcoding) titlova prvenstveno srpske latinice i ćirilice. TITLOVI
- Svuda u daljem tekstu CP1250 je oznaka za latinicu, a ako imamo ćirilični titl oznaka je CP1251.
KONVERZIJA
Da li vam se desilo da dođete u posed video ili audio snimka koji za svoju dužinu ima neverovatnu veličinu.
Običnom korisniku nije potreban preterani kvalitet klipa od 7 minuta koji ima 1 GB ili više.
Treba naći kompromisno rešenje, a za to su nam potrebni parametri video fajla.
U paketu sa FFmpeg instalira se i FFplay (jednostavni medijski plejer) i FFprobe (alat za analizu parametara multimedijskih fajlova).
Evo kako pomoću FFprobe možemo dobiti parametre našeg testnog fajla:
- Rezoluciju:
1ffprobe -v error -select_streams v:0 -show_entries stream=height,width -of csv=s=x:p=0 https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4
- Broj frejmova u sekundi - Frame Rate:
1ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4
2# 30000/1001 je 30 fps
- Veličinu fajla:
1ffprobe -v error -show_entries format=size -of default=noprint_wrappers=1 https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4
2# dobijena vrednost je bajtima (za iznos u MB treba podeliti sa 1048576)
Kao što vidimo komande su dugačke i mada daju sliku o upotrebljivosti, njihova primena nije baš praktična. Mnogo jednostavnije je instalirati neki GUI program, kao što je mediaInfo-gui:
1sudo apt update && sudo apt upgrade
2sudo apt install mediainfo-gui
Dakle naš fajl ima ~58 MB, rezoluciju 3840x2160 i Bitrate 22 Mb/s
napomena:
Podatke o parametrima video fajla možemo da dobijemo i iz komandne linije:1sudo apt install mediainfo 2mediainfo --Inform="Video;rezolucija = %Width%x%Height% Px, dijagonala = %DisplayAspectRatio/String%, bitrejt = %BitRate/String%, frejmrejt = %FrameRate% fps, dužina = %Duration/String1%, %InternetMediaType%" https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4
odgovor:
rezolucija = 3840x2160 Px, dijagonala = 16:9, bitrejt = 22.0 Mb/s, frejmrejt = 29.970 fps, dužina = 23 s 123 ms, video/H264
Možemo da uradimo sledeće:
- Možemo da ga smanjimo kompresijom uz pomoć H265 kodeka:
1ffmpeg -i https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4 -c:v libx265 -crf 28 output.mp4
Ovde koristimo CRF (Constant Rate Factor) kao default podešavanje kvaliteta i bitrate-a. Više o tome ovde.
Test fajl smo smanjili: sa 57.8 na 48.6 MB, odnosno nekih ~20%:
- Obzirom da naš fajl ima Bitrate 22 Mb/s, smanjimo ga na 10:
1ffmpeg -i https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4 -b:v 10M -minrate 10M -maxrate 10M output.mp4
Smanjili smo veličinu fajla na 26 MB, ali po cenu vidljive degradacije kvaliteta.
- Možemo da smanjimo rezoluciju na FullHD (1920x1080):
1ffmpeg -i https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4 -vf scale=1920:1080,setsar=1:1 output.mp4
Dobijamo sledeće parametre:
Evo tabele sa preporučenim rezolucijama za dijagonalu 16:9
Best Choice: | 2nd Best: | 3rd Best: |
---|---|---|
Multiples of 16 | Multiples of 8 | Multiples of 4 |
1920 x 1080 | 1792 x 1008 | 1856 x 1044 |
1280 x 720 | 1152 x 648 | 1216 x 684 |
1024 x 576 | 896 x 504 | 1088 x 612 |
768 x 432 | 640 x 360 | 960 x 540 |
512 x 288 | 384 x 216 | 832 x 468 |
256 x 144 | 128 x 72 | 704 x 396 |
576 x 324 | ||
448 x 252 | ||
320 x 180 | ||
192 x 108 |
Zaključak:
Na svakom od nas je da proceni koliki gubitak kvaliteta mu je prihvatljiv kad zadaje izlazne parametre.
Evo predloga kako bi to moglo da se uradi kombinujući više operacija u istoj komandi.
1ffmpeg -i https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4 -vf scale=1920:1080,setsar=1:1 -b:v 15M -minrate 13M -maxrate 16M -c:v libx265 -crf 28 output.mp4
Dovođenje video fajla na zadatu veličinu
- Hajde da razmotrimo scenario u kome nam je zadato da veličinu fajla svedemo na određenu vrednost i to promenom bitrejta.
Naš fajl Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 ima bitrejt 2150 kb/s , dužinu 5 min 8 s = 308 s i veličinu ~84 MB.
Zadatak je da fajl ne pređe 80 MB.
1 byte = 0.008192 kb # jedan bajt je jednak 8192 milionita dela kilobita.
1 MB = 1000000 byte = 1000000 x 0.008192 = 8192 kb (kilobita)Formula je: bitrejt (kb/s) = veličina fajla (kb)/ vreme trajanja (s)
Konvertujemo megabajte u kilobite (MB u kb):
80 MB x 8192 = 655360 kbUkupni bitrejt (video + audio) = 655360/308 = 2127 kb/s
2127 - 128 = 1999 kb/s # kad oduzmemo 128 za audio strim, za video ostaje 1999
Sad ide transkodiranje u 2 prolaza:
1ffmpeg -y -i Auntie.Edna.2018.1080p.BluRay.x264-\[YTS.AM\].mp4 -c:v libx264 -b:v 1999k -pass 1 -an -f null /dev/null && ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-\[YTS.AM\].mp4 -c:v libx264 -b:v 1999k -pass 2 -c:a aac -b:a 128k Auntie.Edna.80MB.mp4
Rezultat: fajl veličine 78,5 MB
Limitiranje broja jezgara-tredova pri precesiranju
- FFmppeg je program koji simultano koristi više procesorskih jezgara, odnosno tredova (paralelnih operacija).
Kako naći koliko jezgara i tredova poržava naš procesor:
1grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}' # broj fizičkih jezgara
2grep -c ^processor /proc/cpuinfo # broj tredova (number of threads)
Prva komanda mi daje broj 4, a druga broj 8, što znači da moj procesor Intel i7-3770 ima 4 jezgra i 8 tredova.
Kad pokrenem neko grupno enkodiranje (batch process), svih 8 tredova se aktiviraju dovodeći do zauzeća procesora od 100%.
Treba ograničiti broj tredova koje će koristiti FFmpeg kako bi rasteretili procesor za nešto drugo.
- Za enkodiranje u H.264:
1ffmpeg -i imput.mp4 -c:v libx264 -crf 23 -threads 4 output.mp4
gde smo sa -threads 4 zadali FFmpeg-u da komandu izvršava sa 4 treda.
Za grupno (batch) enkodiranje ista komanda bi bila:
1for i in *.mp4; do ffmpeg -i "$i" -c:v libx264 -crf 23 -threads 4 "${i%.mp4}-H.264.mp4"; done
dobijamo enkodirane istoimene fajlove samo sa sufiksom -H.264
- Za enkodiranje u H.265:
1ffmpeg -i imput.mp4 -c:v libx265 -crf 23 -x265-params pools=6 output.mp4
gde smo sa -x265-params pools=6 zadali FFmpeg-u da komandu izvršava sa 6 tredova. Za grupno (batch) enkodiranje ista komanda bi bila:
1for i in *.mp4; do ffmpeg -i "$i" -c:v libx265 -crf 23 -x265-params pools=4 "${i%.mp4}-H.265.mp4"; done
TITLOVI
Neka nam testni fajl bude Auntie Edna.
Ako još niste instalirali/ažurirali youtube-dl evo komande:
1sudo apt-get remove -y youtube-dl && sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl && sudo chmod a+rx /usr/local/bin/youtube-dl
daunlodujmo Ednu u maksimalnoj ponuđenoj rezoluciji (1728x1080):
1cd /folder/gde/vrsimo/konverziju
2youtube-dl -F https://vimeo.com/311038206
Dobićemo ovako nešto:
Izaberemo jednu od ponuđenih opcija sa najvećom rezolucijom (ja sam uzeo poslednju):
1youtube-dl -f dash-fastly_skyfire-video-1197402664 https://vimeo.com/311038206
Sad skinimo titl odavde.
Imamo video fajl (Auntie Edna-311038206.mp4) i titl (Auntie.Edna.2018.720p.BluRay.x264-[YTS.AM].srt) koje ćemo preimenovati u Auntie_Edna.mp4 i titl.srt.
1mv 'Auntie Edna-311038206.mp4' Auntie_Edna.mp4
2mv Auntie.Edna.2018.720p.BluRay.x264-[YTS.AM].srt titl.srt
Ugradićemo titl u fajl kao njegov sastavni deo bez re-enkodiranja:
1ffmpeg -i Auntie_Edna.mp4 -sub_charenc CP1250 -i titl.srt -map 0:v -map 0:a -c copy -map 1 -c:s:0 mov_text -metadata:s:s:0 language=srp Auntie_Edna_sa_titlom.mp4
-
U fajl Auntie_Edna_sa_titlom.mp4 je ugrađen titl uz audio i video komponentu:
-
Ugrađivanje titla u mkv fajl:
1ffmpeg -i input.mkv -sub_charenc CP1250 -i subtitle.srt -map 0:v -map 0:a -c copy -map 1 -c:s:0 srt -metadata:s:s:0 language=srp output.mkv
-
Ili ugrađivanje više titlova u mkv fajl:
1ffmpeg -i input.mp4 -i subtitle_eng.srt -i subtitle_fre.srt \ 2 -map 0:v -map 0:a -map 1 -map 2 \ 3 -c:v copy -c:a copy -c:s copy \ 4 -metadata:s:s:0 language=eng -metadata:s:s:1 language=fre \ 5 output.mkv
Nalepićemo titl na video kao sastavni deo slike uz re-enkodiranje:
-
Titl žute boje,sa transparentnom pozadinom, font Arial 24, testni fajl promenjen u Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -vf "subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=24,OutlineColour=&H100000000,Outline=1,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'" Auntie-Edna.mp4
-
Titl isti kao u prethodnom slučaju ali sa crnom pozadinom:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -vf "subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=24,OutlineColour=&H100000000,Outline=1,BorderStyle=3,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'" Auntie--Edna.mp4
-
Crna boja je u redu ako je na fajl već nalepljen neki strani titl koji odvlači pažnju. Obično to nije tako drastično, pa vizuelno više prija polutransparentna pozadina:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -vf "subtitles=titl.srt:charenc=CP1250:force_style='BackColour=&H80000000,Fontname=Arial,Fontsize=22,OutlineColour=&H100000000,Outline=1,BorderStyle=4,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'" Auntie__Edna.mp4
-
Transparentna pozadina titlova + enkodirano -crf 28 u x265;
fajl smanjen sa 84 na 29 MB:1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -vf "subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=24,OutlineColour=&H100000000,Outline=1,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'" -c:v libx265 -crf 28 Auntie---Edna.mp4
-
Prethodne operacije smo obavljali ostavljajući nepromenjenu rezoluciju 1920x808 što odgovara dijagonali (Aspect Ratio) od 2,4:1.
Vidimo iz predloženih rezolucija da FFmpeg "voli" standardni odnos 16:9.
Evo kako bi smo skalirali naš video fajl sa 1920x808 [A.R - 2.40:1] na 1280:720 [A.R. - 16:9] uz zadržavanje proporcija slike, dakle popunjavanje praznog prostora crnim trakama:1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1" Auntie.-.Edna.mp4
-
Ako skaliranje na različitu rezoluciju iskombinujemo sa lepljenjem titlova, dobićemo:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -filter_complex "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=20,OutlineColour=&H100000000,Outline=1,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'[v]" -map "[v]" -map 0:a -c:a copy Auntie-.-Edna.mp4
-
Ima tu još prostora ispod titla, hajde da maksimalno iskoristimo crnu traku:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -filter_complex "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=20,OutlineColour=&H100000000,Outline=1,Alignment=2,MarginV=1,Shadow=1,PrimaryColour=&H0000FFFF'[v]" -map "[v]" -map 0:a -c:a copy Auntie-..-Edna.mp4
- Ako bi uz sve iz prethodne tačke dodali re-enkodiranje u H265 da bi smanjili veličinu fajla:
1ffmpeg -i Auntie.Edna.2018.1080p.BluRay.x264-[YTS.AM].mp4 -filter_complex "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,subtitles=titl.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=20,OutlineColour=&H100000000,Outline=1,Alignment=2,MarginV=1,Shadow=1,PrimaryColour=&H0000FFFF'[v]" -map "[v]" -map 0:a -c:a copy -c:v libx265 -crf 28 Auntie-Edna.mp4
-
Kako bi recimo isekli deo fajla i na njega nalepili titl.
Evo primera kako iz desete epizode šeste sezone Game of Thrones izrenderovati titl na segment od 00:57:14 do 01:01:51 u kome Lyanna Mormont drži istorijski govor Severnjacima:1ffmpeg -ss 00:57:14 -to 01:01:51 -copyts -i GoT.S06E10.mkv -vf "subtitles=GoT.S06E10.srt:charenc=CP1250:force_style='Fontname=Arial,Fontsize=24,OutlineColour=&H100000000,Outline=1,Alignment=2,Shadow=1,PrimaryColour=&H0000FFFF'" -c:a copy -ss 00:57:14 -y king_in_the_north.mp4
I to bi bilo to...