Lekce 7 - FFmpeg a transcoding - Obrázky
V minulé lekci, FFmpeg a Transcoding - Audio, jsme si řekli něco o audio streamech a předvedli si jak převádět mezi různými audio kodeky.
Pokud chceme získat obrázek (snímek obrazovky) z videa, je to samozřejmě snadné. První způsob je pokusit se využít OS a klávesy PrintScreen. Tímto způsobem se obrázek nahraje do paměti OS a je k dispozici přes zkratku Ctrl + V. Takto snadno jej můžeme přesunout např. do Malování nebo nějakého jiného nástroje. Ovšem ne vždy to funguje. Samozřejmě i FFmpeg podporuje získávání obrázků z videa. Nicméně upozorňuji, že je to nástroj převážně pro transconding videa a případně audia. Podpora obrázků je spíše symbolická.
Podporované formáty
Samozřejmě jsou podporované nejznámější formáty obrázků jako
*.jpg
, *.bmp
a *.png
. Ve většině
případů jsou u obrázků souborové kontejnery (formáty) identické i s
kodeky, ale např. u rodiny souborového formátu JPEG to tak není. Zde je
seznam podporovaných
obrázkových formátů nebo lze využít opět výpis FFmpeg:
ffmpeg -codecs
Samozřejmě je nutné ověřit, jestli FFmpeg podporuje jak dekódování, tak i kódování daného formátu obrázku. V některých případech umí jen dekódovat či naopak kódovat. V tabulce níže si uvedeme souborové kontejnery, u kterých jsou podporovány obě varianty:
Typ kontejneru | FFmpeg parametr |
---|---|
TIFF - Tagged Image File - není plně podporován | tiff |
PNG - Portable Network Graphics | png |
GIF - Graphics Interchange Format | gif |
JPEG - Joint Photographic Experts Group (není plně podporován) | mjpeg nebo jpeg2000 nebo jpegls |
SGI RGB image format | sgi |
Microsoft BMP image | bmp |
Portable BitMap image | pbm |
Získání obrázků z video souboru
Získání samostatného obrázku je naprosto jednoduché. Pokud chceme obrázek JPEG, dělá se to tímto příkazem:
ffmpeg -i video.mp4 -ss 00:00:10.000 -vframes 1 obrazek.jpg
Pokud budeme chtít obrázek formátu PNG, tak tímto příkazem:
ffmpeg -i video.mp4 -ss 00:00:10.000 -vframes 1 obrazek.png
Pojďme si vysvětlit parametry příkazu:
-ss 00:00:10.000
- specifikuje okamžik (čas) ve video stopě, který chceme jako obrázek-vframes 1
- kolik obrázků chcemeobrazek.jpg
- název souboru a typ kontejneru (obrázkový formát)
Výsledek:
Jak vidíte, obrázek jsme získali.
Vlastní kodek a bitrate obrázku
Způsob výše funguje, ale neumožňuje nám nastavovat kodek a bitrate. Prohlédneme si tedy vlastnosti obrázku přes FFprobe:
ffprobe -i obrazek.jpg
Vidíme, že obrázek má předdefinovaný kodek (v tomto případě mjpeg) i hodnotu bitrate. Výhodou je, že s těmito předdefinovanými vlastnostmi vám defaultně půjde obrázek otevřít, ale pokud si začnete nastavovat specifické kodeky, pak je OS nemusí podporovat a obrázky otevřete snad jen ve specifických programech.
Nicméně pokud chceme získat obrázek v jiném kodeku rodiny JPEG, např. JPEG2000, postup je následující:
ffmpeg -i video.mp4 -ss 00:00:10.000 -c:v jpeg2000 -vframes 1 obrazekJPG2000.jpg
Mé Windows 10 obrázek nezobrazily, ale FFMpeg nevypsal žádnou chybu. Zobrazení přes FFplay fungovalo, i když to trochu déle trvalo:
ffplay -i obrazekJPG2000.jpg
Získání více obrázků
Pokud byste chtěli získat více obrázků za sebou, je nutné použít tento příkaz:
ffmpeg -i video.mp4 -ss 00:00:10.000 -vframes 10 obra%04d.jpg
Parametr -vframes 10
definuje počet obrázků, které chceme
získat. Pokud je jich více než 1
, samozřejmě musíme zajistit,
aby se obrázky uložily do samostatných souborů. To uděláme přidáním
dodatečného řetězce výstupního obrázku %04d
. Tento parametr
vytvoří obrázky s názvy od obra0001.jpg
,
obra0002.jpg
, ... až do obra0010.jpg
.
Časový rozdíl mezi obrázky
Pokud chceme definovat časový rozdíl mezi obrázky, je nutné použít
parametr -vf fps=cas
:
ffmpeg -i video.mp4 -vf fps=1/4 -vframes 5 obraN%04d.jpg
Parametr fps
(Frame Per Second) určuje počet obrázků za
sekundu. Hodnota 1
tedy uloží obrázek každou sekundu videa.
Pokud chceme uložit obrázek např. každé 4 sekundy, zadáme hodnotu
1/4
. Celkem tedy budeme mít 5 obrázků každé 4 sekundy.
Obrázek výřezu videa
Pokud bychom chtěli získat obrázek z videa přes výřez (tedy odstranit oblasti, které v obrázku nechceme), pak příkaz bude vypadat takto:
ffmpeg -i 1.mp4 -filter:v "crop=920:720:250:100" -ss 00:00:45.000 -vframes 1 obrazek.jpg
Opět připomenu, že obrázek bude rozměru 920
(šířka) na
720
(výška). Souřadný systém [0,0] je opět v levém horním
rohu a obrázek tedy bude začínat 250 pixelů zleva a 100 pixelů z vrchu.
Vložení obrázku do videa
Toto už jsou specialitky. Vámi zvolený obrázek (já si vyberu ikonu
FFmpeg uloženou v souboru icon.png
) vložíte do videa. Opět
připomínám, že filtry nelze najednou používat se streamcopy. Příkaz je
následující:
ffmpeg -i video.mp4 -i icon.png -filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p videoObrazek.mp4
Pojďme si vysvětlit parametry:
overlay=25:25:
- levý horní roh obrázku se umístí25
pixelů zleva a25
pixelů shora v obrazu videa. [0:0] je vlevo nahoře.enable='between(t,0,20)'
- obrázek bude ve videu v čase od00:00:00
do00:00:20
.
Jak vidíte v obrázku níže, tak obrázek ve videu skutečně je. Není problém tak do videa vložit prakticky své logo, aby nám jej někdo neukradl:
Vložení videa do videa
Tak jak jsme v předchozím příkladu do horního levého rohu vložili obrázek (logo), není problém tam podobným způsobem vložit i video. Např. vložíme rozlišení 320:240 od našeho 4K videa. Nejdříve si takovéto mikrovideo s malým rozlišením vyrobíme:
ffmpeg -i video.mp4 -vf scale=320:240 -an video320_240.mkv -hide_banner
Poté ho do 4K videa vložíme přes mapu:
ffmpeg -i video.mp4 -i video320_240.mkv -filter_complex "[1:v]setpts=1*PTS[a]; [0:v][a]overlay=25:25:enable='between(t,0,20)':shortest=1[out]" -map [out] -map 0:a -c:v libx264 -crf 25 -pix_fmt yuv420p -c:a copy videoVideo.mkv -hide_banner
Parametrů je hodně, pojďme si je popsat:
[0:v]
- pole vstupů začíná nulou, takže se jedná o definici video streamu ze souboruvideo.mp4
[1:v]setpts=1*PTS[a]
- video stream zvideo320_240.mkv
bude být normální průběh, 1sec = 1 sec, <1 zrychluje video, >1 zpomaluje videooverlay=25:25:
- levý horní roh videa se umístí25
pixelů zleva a25
pixelů shora v obrazu videa. [0:0] je vlevo nahoře.enable='between(t,0,20)'
- vložené mikrovideo bude ve videu v čase od00:00:00
do00:00:20
.
Jak vidíte v přiloženém obrázku, video je skutečně vloženo ve videu:
Export videa do gifu
Souborový formát .gif
slouží většinou jako pohyblivý
obrázek na webu. Často se používá jako banner. Na toto je asi
nejvhodnější a nejpodrobnější návod zde.
Nicméně pár příkladů si uvedeme. Jen připomenu, že vzniklý
*.gif
je nutné otevřít např. z přehrávače nebo
internetového prohlížeče (Chrome, Edge, Firefox, ...).
Příkaz pro převod videa do gif je následující:
ffmpeg -i video.mp4 mikrovideo.gif -hide_banner
Přenesení úseku videa
Pokud byste chtěli do gifu přenést pouze časový úsek od/do (např. 4 sekundy) v nějakém rozlišení, pak příkaz bude vypadat takto (opět použijeme mapu):
ffmpeg -i video.mp4 -ss 00:00:22.000 -to 00:00:28.000 -filter_complex "[0:v] fps=12,scale=w=860:h=-1,split [a][b];[a] palettegen=stats_mode=single [p];[b][p] paletteuse=new=1" mikrovideo1.gif -hide_banner
Parametry jsou:
-ss 00:00:22.000 -to 00:00:28.000
- definovaný časový úsek ze zdrojového videa[0:v]
- pole vstupů začíná nulou, takže se jedna o definici video streamu ze souboruvideo.mp4
fps=12
- frame per second, tedy 12 obrázků za sekunduscale=w=860:h=-1
- velikost banneru, definuje se jen šířka (width)
Změna obrázkového kontejneru (souborového formátu)
Poslední možnost, kterou bychom mohli využívat, je převod mezi jednotlivými obrázkovými formáty. Příkaz je:
ffmpeg -i obrazek.jpg obrazek.gif -hide_banner
nebo
ffmpeg -i obrazek.jpg obrazek.bmp -hide_banner
V příští lekci, FFmpeg a transcoding - Rotace, titulky, metadata, si předvedeme, jak se pracuje s titulky a metadaty.