Lekce 5 - FFmpeg a transcoding - Stříhání, skládání, výřezy
V minulé lekci, FFmpeg a transcoding - Rozlišení, Bitrate, jsme si předvedli změnu souborového kontejneru, změnu kodeku (komprimačního algoritmu), změnu rozlišení a změnu datového toku (bitrate) videa. Tyto operace jsou, dá-li se tak říci, základem a mohou stačit pro 80% úprav multimediálních souborů.
Nyní nás čekají střihy a skládání. To je vhodné např. pokud si nahrajete nějaký video soubor z televize a jsou v něm reklamy. Je pochopitelné, že se jich chcete zbavit. V FFmpeg neexistuje žádná funkce, která pozná v obrazu, že se jedná o reklamy nebo něco, co tam nechcete. Musíme na to jít tak, že z celého videa (stopy) vyřízneme kratší úseky a ty pak sloučíme do jednoho videa. Nevýhoda je, že to je trochu pracné.
Formát času v FFmpeg
Čas je v FFmpeg definován docela jednoduše ve tvaru
(formátu) hodina:minuta:sekunda.milisekunda. Např. takto:
01:23:17.423
. Delší časové stopy než 24 hodin asi těžko
využijete.
Stříhání (trim) videa
Vyříznutí videa je jedna z jeho nejdůležitějších úprav. Provádí se
přes specifické parametry udávající začátek nové stopy:
-ss 00:00:00
a její konec: -to 00:00:00
. Na prvním
příkladu si ukážeme, jak vytvořit 5 sekundové video v kodeku h264 s
bitrate 3000 kbs a mp3 s 192 kbs z našeho vzoru. Pak si vyrobíme ještě dvě
další videa, hlavně proto, abychom měli podklady pro spojování videa
dále.
Příkaz pro vyříznutí 5s z videa je následující:
ffmpeg -i video.mp4 -ss 00:00:05 -to 00:00:10 -c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K videoStrih1.mkv -hide_banner
Samozřejmě lze tento příkaz napsat i bez specifikace konečného času a
pouze dobou trvání video stopy. Definujeme tedy začátek a délku stopy. Tato
varianta se specifikuje tak, že zadáme start jako -ss 00:00:00
a
délku video stopy jako -t 00:00:05
nebo -t 5
:
ffmpeg -i video.mp4 -ss 00:00:05 -t 5 -c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K videoStrih1.mkv -hide_banner
Na druhém příkladu si předvedeme vytvoření 8 sekundového videa s identickými parametry jako v případě prvního:
ffmpeg -i video.mp4 -ss 00:00:15 -to 00:00:23 -c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K videoStrih2.mkv -hide_banner
Na třetím příkladu si předvedeme vytvoření 4 sekundového videa s identickými parametry jako v případě prvního:
ffmpeg -i video.mp4 -ss 00:00:37 -to 00:00:41 -c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K videoStrih3.mkv -hide_banner
Jak vidíte, videa se vyrobila. Pokud si je přehrajete, tak lze pozorovat délku prvního videa 5 sekund, v případě druhého videa 8 sekund a u posledního 4 sekundy:

Tímto jednoduchým způsobem získáme video/audio úseky. FFmpeg nedisponuje jiným způsobem, jak identifikovat v obrazu např. reklamy. Je nutné vždy manuálně identifikovat časy, kdy dochází ke změně. Takových stop si pak musíme vyrobit několik a ty pak spojit do jednoho souboru. To je přesně to, co si dále ukážeme.
Skládání více videí do jednoho souboru
V FFmpeg existují celkem dva způsoby pro spojování multimediálních souborů, o kterých vím. První možnost je přes concat demuxer a druhá přes concat filter. Já osobně používám filter, protože demuxer umí pracovat pouze se souborovým kontejnerem .ts (prý i .avi, .mpg).
Concat demuxer
Je tedy nutné nejdříve převést dané stopy do daného formátu a pak teprve lze přes concat demuxer spojit daná videa do jednoho souboru.
Zde je varianta bez překódování:
ffmpeg -i "concat:003out.ts|004out.ts" -c copy output.ts
A zde je varianta s překódováním a uložením do jiného typu kontejneru:
ffmpeg -i "concat:000out.ts|005out.ts" -vcodec h264 -b:v 1800K -acodec mp3 output.mp4
Concat filter
Jako druhá možnost je využívat concat filter (známý jako mapa). Působí sice složitěji, ale zato je univerzálnější a efektivnější. Nesetkal jsem se se situací, že by mi nepodporoval nějaké kódování a nějaký souborový formát, který FFmpeg podporuje. Takže pokud bychom chtěli spojit ta tři videa v kodeku h264 s bitrate 3000 kbs a mp3 s 192 kbs z našeho vzoru, jenž jsme vytvořili v první části této lekce, pak by příkaz vypadal takto:
ffmpeg -i videoStrih1.mkv -i videoStrih2.mkv -i videoStrih3.mkv -c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" videoCelek.mkv
Působí docela složitě, ale zase tak složité to není. Pojďme si vysvětlit jeho jednotlivé části:
-i videoStrih1.mkv -i videoStrih2.mkv -i videoStrih3.mkv
- jedná se o zdrojové soubory, které mají být spojeny-c:v libx264 -b:v 3000K -c:a mp3 -b:a 192K
- specifikace video a audio kodeku vč. jeho bitrate (datového toku)videoCelek.mkv
jméno výstupního souboru-filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" -map "[v]" -map "[a]"
- specifikace nastavení mapy, které si podrobně rozepíšeme:[0:v] [0:a] [1:v] [1:a] [2:v] [2:a]
- zde definuje stopy (streamy) ze vstupních souborů, např.[0:v]
je video stopa ze souboruvideoStrih1.mkv
,[2:a]
je audio stopa ze souboruvideoStrih3.mkv
apod.concat=n=3:v=1:a=1 [v] [a]
- vstupem jsou 3 stopy, jenž se budou spojovat, a výstupem je jedna video stopa a jedna audio stopa-map "[v]" -map "[a]"
- informace o tom, že výstupní video a audio je složeno z mapy
Výsledek:

Možná to působí složitě, ale pokud si to párkrát zkusíte, pak zjistíte, že to moc složité není. Analogicky takto můžete spojovat video i z méně vstupů (2 vstupů) či naopak z více (4, 5, 6, 7, 8, .. vstupů).
Uveďme si vzorový příklad jak vytvořit 4 stopy a z nich jedno společné video. V případě více/méně stop provedeme analogicky úpravu. Mimochodem, není problém si z toho udělat *.bat skript a trochu si celý postup zautomatizovat.
ffmpeg -i 000out.ts -vcodec h264 -b:v 3M -ss 0:04:47 -to 0:11:16 -acodec aac Test1.mkv ffmpeg -i 000out.ts -vcodec h264 -b:v 3M -ss 0:18:19 -to 0:29:51 -acodec aac Test2.mkv ffmpeg -i 000out.ts -vcodec h264 -b:v 3M -ss 0:35:41 -to 0:47:22 -acodec aac Test3.mkv ffmpeg -i 000out.ts -vcodec h264 -b:v 3M -ss 0:55:07 -to 1:17:42 -acodec aac Test4.mkv ffmpeg -i Test1.mkv -i Test2.mkv -i Test3.mkv -i Test4.mkv -vcodec h264 -b:v 3M -acodec aac -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] [3:v] [3:a] concat=n=4:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" Video4Stopy.mkv
Výřezy (Croping) videa
FFmpeg nám samozřejmě umožňuje provést i výřez videa. To se provádí
přes filtr, např. -filter:v "crop=w:h:x:y"
, kde w
ke
šířka a h
výška videa, x
a y
je
poloha výchozího bodu ve videu našeho výřezu. Obrazovka je vlastně graf
pixelů a pozice [0,0] se nachází v levé horním rohu obrazu. Znaménková
konvence obrazovky (grafu) je +/+ doprava/dolů. Pokud bychom například
chtěli, abychom začali s videem v levém horním rohu, pak souřadnice budou
x
=0, y
=0 a velikost výřezu obdélníku bude
800
na 600
. Příkaz by byl poté následující:
ffmpeg -i video.mp4 -filter:v "crop=800:600:0:0" -c:v libx264 -b:v 5000K -c:a mp3 -b:a 192K videoCrop.mkv -hide_banner
Pokud ovšem chceme posunout výchozí bod v ose x
o
500
pixelů a v ose y
o 1500
pixelů a
výsledný obdélník chceme 640
x480
, pak příkaz
bude následující:
ffmpeg -i video.mp4 -filter:v "crop=640:480:500:1500" -c:v libx264 -b:v 5000K -c:a mp3 -b:a 192K videoCrop1.mkv -hide_banner
Změna rychlosti běhu videa (audia)
Samozřejmě lze i video příp. audio zrychlit/zpomalit, podle toho, co si
budete přát. To zajistíme filtrem s parametrem "setpts=x*PTS"
.
Pokud bude x
větší než 1
, pak video zpomalujeme, a
pokud bude menší než 1
, pak video zrychlujeme. Zkusme si to:
ffmpeg -i video.mp4 -vf "setpts=0.25*PTS" Zrychleni4x.mp4
Nezapomeňte, zrychlování/zpomalování vždy provádějte na samostatném streamu (videa nebo audia). A při zrychlení oblast stopy odříznout
V příští lekci, FFmpeg a Transcoding - Audio, si probereme kodeky a úpravu audio streamu.