Linux: Kniha kouzel, 2.15 (1. března 2025)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

31. Zpracování videa a zvuku

Vývoj vanilkové příchuti Linuxu: Knihy kouzel byl 1. března 2025 ukončen. Tento text je zachován jako historický, ale chyby již nejsou opravovány. Odnože projektu pod kompatibilní licencí jsou vítány.

1. Úvod

FFmpeg je nástroj pro konverzi, úpravu a streamování videa, zvuku a titulků. Hlavní výhodou FFmpegu oproti videoeditorům s grafickým uživatelským rozhraním je modularita a opakovatelnost zpracování pro různé vstupní soubory.

Tato verze kapitoly nepokrývá všechny dostupné filtry ffmpegu (zvlášť v oblasti zpracování zvuku není pokrytí příliš dobré) a neobsahuje vysvětlení pojmu PTS. Rovněž chybí popis vestavěných funkcí používaných ve výrazech v parametrech filtrů.

2. Definice

  • Stopa (stream) je časovaná složka multimediálního souboru proložená v čase s ostatními stopami téhož souboru. Stopy v jednom souboru mohou být různého typu (obrazová, zvuková, titulková či datová) a mohou mít různou délku.
  • Kanál (plane/channel) je datová vrstva tvořící stopu s ostatními kanály. Všechny kanály stopy trvají vždy stejně dlouho a tvoří každý snímek obrazu či vzorek zvuku společně. Obrazová stopa se typicky dělí na kanály Y (svítivost), U a V (barva), případně ještě alfa (krytí); zvuková stopa mívá nejčastěji kanály FR a FL (stereo), méně často jeden kanál (mono) či více kanálů.
  • Snímek je základní kvantum obrazové stopy. Vzorkovací frekvence videa čili počet snímků za sekundu se nazývá fps. Hodnota fps se obvykle pohybuje v rozmezí 10 až 60.
  • Vzorek je základní kvantum zvukové stopy. Obvyklá vzorkovací frekvence zvuku je 44 100 vzorků za sekundu.
  • Filtr je objekt v grafu filtrů, který očekává určitý počet vstupů určitého typu v určitém pořadí (toto očekávání se může lišit v závislosti na parametrech). Na tyto vstupy je pak potřeba připojit buď stopy vstupů ffmpegu (typicky vstupních souborů) nebo výstupy jiných filtrů. Filtr mívá také výstupy, které je pak nutno připojit na vstupy jiných filtrů nebo na stopy výstupů ffmpegu. Filtr, která má výstupy, ale ne vstupy, se nazývá generátor, přestože může načítat data z disku.
  • Graf filtrů je orientovaný graf definovaný uživatelem, který popisuje tok dat různého typu přes ffmpeg ze vstupů na výstupy. V grafu filtrů nejsou dovoleny nepřipojené vstupy či výstupy filtrů.
Obrázek: ukázka grafu filtrů

2/1 Syntaxe grafu filtrů

Základním nástrojem pro zpracování multimediálních souborů v ffmpegu je tzv. graf filtrů (filtergraph), který může být buď kompletní, definovaný pomocí globálního parametru -filter_complex (resp. -filter_complex_script), nebo jednoduchý, definovaný pomocí výstupních parametrů -vf-af.

V komplexním grafu filtrů se každá stopa vstupu značí formou „[0:v]“, kde na místě 0 je pořadové číslo vstupu (počítáno od nuly) a na místě „v“ může být „v“ pro výchozí obrazovou stopu, „a“ pro výchozí zvukovou stopu, nebo pořadové číslo stopy v kontejneru vstupního souboru (lze zjistit z výstupu příkazu „ffprobe“).

Jednoduché propojení mezi filtry se v komplexním i jednoduchém grafu filtrů vytvoří tak, že se filtry zapíšou vedle sebe a oddělí čárkou (kde propojení není, píše se místo čárky středník). V komplexním grafu filtrů se vytvářejí také pojmenovaná propojení, jejichž identifikátory je nutno uzavřít do hranatých závorek. Zatímco u jednoduchého grafu filtrů se konec namapuje na stopu výstupního souboru automaticky, u komplexního grafu filtrů to musíme udělat ručně, samostatným výstupním parametrem „-map“.

3. Zaklínadla: Filtry

V této sekci používám následující konvence: vi značí obrazový vstup filtru (opakuje se tolikrát, kolik má filtr obrazových vstupů); analogicky ai zvukový vstup, vo obrazový výstup a ao zvukový výstup. Značky io1, io2 atd. značí pomocná propojení filtrů, kterým musíte vymyslet nové, v grafu filtrů dosud nepoužité identifikátory.

3/1 Úprava časové osy

@zrychlení 2×/4×/5×/16×#1 (1)
[vi] setpts=PTS/2 [vo] ; [ai] atempo=2 [ao]
[vi] setpts=PTS/4 [vo] ; [ai] atempo=2,atempo=2 [ao]
[vi] setpts=PTS/5 [vo] ; [ai] atempo=2,atempo=2,atempo=5/4 [ao]
[vi] setpts=PTS/16 [vo] ; [ai] atempo=2,atempo=2,atempo=2,atempo=2 [ao]
@zpomalení 2×/4×/5×/16×#2
[vi] setpts=2.0*PTS [vo] ; [ai] atempo=1/2 [ao]
[vi] setpts=4.0*PTS [vo] ; [ai] atempo=1/2,atempo=1/2 [ao]
[vi] setpts=5.0*PTS [vo] ; [ai] atempo=1/2,atempo=1/2,atempo=4/5 [ao]
[vi] setpts=16.0*PTS [vo] ; [ai] atempo=1/2,atempo=1/2,atempo=1/2,atempo=1/2 [ao]
@vyříznout časový úsek (po sekundách)(alternativy)#3
[vi] trim=začátek:konec,setpts=PTS-STARTPTS [vo] ; [ai] atrim=začátek:konec,asetpts=PTS-STARTPTS [ao]
[vi] trim=start=začátek:duration=trvání [vo] ; [ai] atrim=start=začátek:duration=trvání,asetpts=PTS-STARTPTS [ao]
@vyříznout časový úsek (po snímcích)(alternativy)#4
[vi] trim=start_frame=index-prvního-zahrnutého-snímku:end_frame=index-snímku-za-koncem,setpts=PTS-STARTPTS [vo]
[ai] atrim=start_sample=index-prvního-zahrnutého-vzorku:end_sample=index-vzorku-za-koncem,asetpts=PTS-STARTPTS [ao]
@obrátit celou stopu#5 (2)
[vi] reverse [vo]; [ai] areverse [ao]
@opakovat celý (krátký) obrazový/zvukový vstup po zadaný počet sekund#6 (3)
[vi] setpts=PTS-STARTPTS,loop=-1:32767,trim=0:cílový-počet-sekund [vo]
[ai] asetpts=PTS-STARTPTS,aloop=-1:2147483647,atrim=0:cílový-počet-sekund [ao]
@opakovat vyříznutou část obrazového/zvukového vstupu po zadaný počet sekund#7
[vi] trim=začátek:konec,setpts=PTS-STARTPTS,loop=-1:32767,trim=0:cílový-počet-sekund [vo]
[ai] atrim=začátek:konec,asetpts=PTS-STARTPTS,aloop=-1:2147483647,atrim=0:cílový-počet-sekund [ao]
@zpomalit obraz 10× s interpolací pohybu/zpomalit zvuk 10×#8 (4)
[vi] setpts=10.0*PTS,minterpolate=fps=25[:mi_mode=blend-nebo-dup] [vo]
[ai] atempo=1/2,atempo=1/2,atempo=1/2,atempo=8/10 [ai]

3/2 Škálování obrazu (resize)

@změna rozlišení (roztažení, smrsknutí, škálování)#1 (5)
[vi] scale=šířka:výška [vo]
@změnit šířku i výšku na polovinu a zajistit, aby oba rozměry byly sudé#2
[vi] scale=2*trunc(iw/4):2*trunc(ih/4) [vo]
@zvětšit šířku i výšku s interpolací pro pixel-art na dvojnásobek/dvojnásobek jinak/trojnásobek/čtyřnásobek#3
[vi] super2xsai [vo]
[vi] xbr=2 [vo]
[vi] xbr=3 [vo]
[vi] xbr=4 [vo]

3/3 Transformace a oříznutí obrazu

@nadstavení obrazu (padding)#1 (6)
[vi] pad=šířka:výška:posun-x-zleva:posun-y-shora[:barva] [vo]
@vyříznutí obrazu/oříznutí okrajů (cropping)#2
[vi] crop=šířka:výška:posun-x-zleva:posun-y-shora [vo]
[vi] crop=iw-zleva-zprava:ih-shora-zespodu:zleva:shora [vo]
@převrátit obraz (horizontálně/vertikálně)#3
[vi] hflip [vo]
[vi] vflip [vo]
@otočit obraz o +90° (o 90° proti směru hodinových ručiček)#4
[vi] transpose=2 [vo]
@otočit obraz o 180°#5
[vi] hflip,vflip [vo]
@otočit obraz o -90° (o 90° po směru hodinových ručiček)#6
[vi] transpose=1 [vo]
@otočit obraz o obecný úhel (ve stupních) proti/po směru hodinových ručiček#7
[vi] rotate=úhel*(-PI/180)[:výsl-šířka:výsl-výška][:c=barva-pozadí-nebo-none] [vo]
[vi] rotate=úhel*(PI/180)[:výsl-šířka:výsl-výška][:c=barva-pozadí-nebo-none] [vo]
@otočit obraz o obecný úhel (ve stupních) proti směru hodinových ručiček a zvětšit rozlišení na obdelník opsaný otočenému snímku; nevyplněné rohy ponechat průhledné#8
[vi] rotate=úhel*(-PI/180):rotw(úhel*(-PI/180)):roth(úhel*(-PI/180)):c=none [vo]
@opravit perspektivu ze zadaných souřadnic (vLevo, vpRavo, Nahoře, Dole)#9
[vi] perspective=LNx:LNy:RNx:RNy:LDx:LDy:RDx:RDy[:sense=destination][:interpolation=cubic] [vo]
@vyměnit dvě obdelníkové oblasti ve videu#10 (7)
[vi] swaprect=šířka-oblastí:výška-oblastí:x1:y1:x2:y2 [vo]

3/4 Překryv, skládání a prolínání obrazových stop (blend)

@naskládat videa stejné výšky vedle sebe/videa stejné šířky pod sebe#1 (8)
[vi] hstack=inputs=počet-vstupů[:shortest=1] [vo]
[vi] vstack=inputs=počet-vstupů[:shortest=1] [vo]
@prolnout několik vstupů#2 (9)
[vi] mix=nb_inputs=počet-vstupů:weights=váhy oddělené mezerami[:duration=longest-shortest-nebo-first] [vo]
@překrýt hlavní (první) videovstup překryvným (druhým); po skončení překryvného vstupu: ho skrýt/ukončit výstup/zamrznout překryvný vstup na jeho posledním snímku#3 (10)
[vi][vi] overlay=x=posun-x:y=posun-y:eof_action=pass [vo]
[vi][vi] overlay=x=posun-x:y=posun-y:eof_action=endall [vo]
[vi][vi] overlay=x=posun-x:y=posun-y:eof_action=repeat [vo]
@prolnout jeden a druhý videovstup (obecně/konkrétně)#4 (11)
[vi][vi] blend=all_expr=výraz[:eof_action=]repeat-endall-nebo-pass [vo]
[prvni][druhy] blend=all_expr=if(eq(mod(Y\,2)\,0)\,A\,B):eof_action=endall [vysledek]

3/5 Jas, kontrast, barva a spol.

@odbarvit obrázek na stupně šedi#1
[vi] hue=s=0 [vo]
@nastavit kontrast (rozsah -2.0 až 2.0; neutrální hodnota 1.0)#2 (12)
[vi] eq=contrast=hodnota[:eval=frame] [vo]
@nastavit jas (rozsah -1.0 až 1.0; neutrální hodnota 0.0)#3
[vi] eq=brightness=hodnota[:eval=frame] [vo]
@nastavit saturaci (rozsah 0.0 až 3.0; neutrální hodnota 1.0#4
[vi] eq=saturation=hodnota[:eval=frame] [vo]
@nastavit gama-korekci (rozsah 0.1 až 10.0; neutrální hodnota 1.0)#5
[vi] eq=gamma=hodnota[:eval=frame] [vo]
@nastavit kontrast, jas, saturaci a gama korekci současně#6
[vi] eq=contrast=kontrast:brightness=jas:saturation=saturace:gamma=gama[:eval=frame] [vo]
@invertovat barvy/barvy a alfa-kanál#7
[vi] negate [vo]
[vi] negate=negate_alpha=1 [vo]
@efekt „sépie#8
[vi] colorchannelmixer=0.393:0.769:0.189:0:0.349:0.686:0.168:0:0.272:0.534:0.131[,eq=contrast=0.8:saturation=1.2] [vo]
@rozmazat obraz (normálně/maximálně/minimálně/obecně)#9
[vi] gblur=2 [vo]
[vi] gblur=1024 [vo]
[vi] gblur=0 [vo]
[vi] gblur=sigma [vo]
@zašumět obraz proměnným RGB-šumem#10 (13)
[vi] noise=alls=síla-šumu-0-až-100:allf=t [vo]
@ztmavit/zesvětlit okraje snímku (efekt „vignette“)#11 (14)
[vi] vignette=a=úhel-čočky[:x0=x-středu:y0=y-středu][:eval=frame] [vo]
[vi] vignette=mode=backward:a=úhel-čočky[:x0=x-středu:y0=y-středu][:eval=frame] [vo]

3/6 Zapékání titulků

@zapéci titulky do obrazu (normálně)#1 (15)
[vi] subtitles=soubor-s-titulky [vo]
@zapéci titulky s časovým posunem (opozdit titulky/opozdit video/příklad)#2 (16)
[vi] setpts=PTS-posun-sekund/TB,subtitles=soubor-s-titulky,setpts=PTS+posun-sekund/TB [vo]
[vi] setpts=PTS+posun-sekund/TB,subtitles=soubor-s-titulky,setpts=PTS-posun-sekund/TB [vo]
[vst] setpts=PTS+1.25/TB,subtitles=titulky.srt,setpts=PTS-1.25/TB [vvyst]
@zapéci titulky do obrazu (obecně/podtrženým červeným písmem Arial velikosti 48)#3 (17)
[vi] subtitles=soubor-s-titulky[:force_style=nastavení-stylu] [vo]
[vi] subtitles=soubor-s-titulky:force_style=FontName\=Arial\,Fontsize\=48\,PrimaryColour\=&H000000FF\,Underline\=1 [vo]

3/7 Roztmívačky, zatmívačky a další přechody (obr. i zvuku)

@vložit roztmívačku/zatmívačku#1 (18)
[vi] fade=t=in:st=začátek:d=trvání[:c=barva][:alpha=1] [vo]
[vi] fade=t=out:st=začátek:d=trvání[:c=barva][:alpha=1] [vo]
@spojit za sebe dva zvukové vstupy prolínačkou (konkrétně sedmisekundovou/obecně)#2
[ai][ai] acrossfade=d=7:c1=exp:c2=exp [ao]
[ai][ai] acrossfade=d=trvání-prolínačky:c1=funkce-zatmívačky:c2=funkce-roztmívačky [ao]
@spojit za sebe dva obrazové vstupy prolínačkou (konkrétně sedmisekundovou/obecně)#3 (19)(20)
[prvnivideo] split [x1][x2];[x2] trim=0:5.12 [x3];[x3][druhevideo] concat=n=2:v=1:a=0 [x4];[x1] fade=out:st=5.12:d=7.0:alpha=1 [x5];[x4][x5] overlay=eof_action=pass [vystup]
[vi] split [io1][io2];[io2] trim=0:začátek [io3];[io3][vi] concat=n=2:v=1:a=0 [io4];[io1] fade=out:st={začátek}:d={trvání}:alpha=1 [io5];[io4][io5] overlay=eof_action=pass [vo]
@aplikovat zvukovou zatmívačku/roztmívačku#4 (21)
[ai] afade=out:st=čas-začátku:d=trvání-v-s:curve=tvar [ao]
[ai] afade=in:st=čas-začátku:d=trvání-v-s:curve=tvar [ao]
@roztmívačka/zatmívačka saturace#5 (22)
[vi] hue=s=max(0\,min(1\,(t - začátek)/trvání)) [vo]
[vi] hue=s=max(0\,min(1\,(začátek - t)/trvání)) [vo]

3/8 Retušování (obrazu)

@zakrýt/odstranit logo nebo jiný rušivý element z obrazu#1
[vi] delogo=x=posun-x-zleva:y=posun-y-shora:w=šířka:h=výška [vo]
@zneviditelnit předmět#2 (23)
[vi] removelogo=obrázek-s-mapou.png [vo]

3/9 Vykreslování do videa

@obdelník (jen čáry/vyplněný/invertující)#1
[vi] drawbox=posun-x-zleva:posun-y-shora:šířka:výška:barva[@krytí-0-až-1][:tloušťka] [vo]
[vi] drawbox=posun-x-zleva:posun-y-shora:šířka:výška:barva[@krytí-0-až-1]:fill [vo]
[vi] drawbox=posun-x-zleva:posun-y-shora:šířka:výška:invert[@krytí-0-až-1]:fill [vo]
@trojúhelník#2
@kruh#3
@text#4

3/10 Ostatní

@odstranit prokládání#1 (24)
[vi] yadif [vo]
@proložit obraz#2 (25)
[vi] interlace [vo]
@aplikovat na obraz Sobelův operátor detekce hran#3
[vi] sobel [vo]
@rozdělit snímky po dávkách a každou dávku vykreslit po řádkách do mřížky daných rozměrů#4
[vi] tile=počet-sloupců-mřížkyxpočet-řádků-mřížky[:margin=šířka-okraje][:padding=rozestup-mřížky][:color=barva-pozadí][:nb_frames=velikost-dávky] [vo]

3/11 Nízkoúrovňové manipulace

@nahradit všechny pixely barvou/průhledností při zachování ostatních parametrů stopy#1 (26)
[vi] fade=t=in:s=2G:c=barva [vo]
[vi] fade=t=in:s=2G:alpha=1 [vo]
@aplikovat výraz po pixelech#2 (27)
@sestavit každý nový snímek z pixelů původního (obecně/příklad)#3 (28)
[vi] geq=p(SW*(výraz-x)\,SH*(výraz-y)) [vo]
[video] geq=p(SW*((X/SW)+100)\,SH*((Y/SH)+150)) [vo]
@oříznout hodnoty složek obrazu (kromě alfa-kanálu)#4
[vi] limiter=[min=minimum][:max=maximum] [vo]
@aplikovat na zvukové vzorky obecný výraz#5 (29)
[ai] aeval=výraz[|výraz-pro-druhý-kanál]:c=same [ao]
@vynásobit vzorky dvou vstupů#6
[ai][ai] amultiply [ao]
@nastavit novou vzorkovací frekvenci bez ovlivnění vzorků#7
[ai] asetrate=nová-frekvence [ao]

3/12 Manipulace obrazu po snímcích

@prohazovat a zahazovat snímky podle zadaného klíče#1 (30)
[vi] shuffleframes=indexy dělené mezerami [vo]
@náhodně prohazovat snímky v čase (snímky se do bufferu vkládají sekvenčně a vybírají v náhodném pořadí)#2 (31)
[vi] random=velikost-bufferu [vo]
@z každé dávky snímků vybrat ten nejreprezentativnější a ten roztáhnout na celou délku dávky#3 (32)
[vi] thumbnail=počet-snímků-na-dávku [vo]

3/13 Základní úprava zvuku

@změnit hlasitost (snížit na desetinu/zvýšit na pětinásobek)#1
[ai] volume=0.1 [ao]
[ai] volume=5.0 [ao]
@přidat ozvěnu#2 (33)
[ai] aecho=0.6:0.3:ms-zpoždění:hlasitost-ozvěny [ao]
@přidat dvě a více ozvěn#3
[ai] aecho=0.6:0.3:ms-zpoždění-1|ms-další-zpoždění:hlasitost-ozvěny-1|hlasitost-další-ozvěny [ao]
@smíchat paralelní audiostopy#4
[ai] amix=počet-vstupů:duration=longest,shortest,nebo-first[:weights=váhy vstupů] [ao]

3/14 Pokročilá úprava zvuku

@převzorkovat stopu na novou frekvenci#1
[ai] aresample=nová-frekvence [ao]
@vylepšit zvuk pro poslech přes sluchátka#2
[ai] earwax [ao]
@zvýraznit rozdíl mezi stereokanály#3
[ai] extrastereo[=koeficient] [ao]
@rozkolísat amplitudu/fázi zvuku#4 (34)
[ai] tremolo=f=frekvence-Hz[:d=síla] [ao]
[ai] vibrato=f=frekvence-Hz[:d=síla] [ao]

3/15 Vložit ticho

@před stopu (do všech kanálů/do kanálů různě)#1
@za stopu#2 (35)
anoisesrc=a=0:d=trvání-v-s [io1]; [ai][io1] concat=n=2:v=0:a=1 [ao]
@nadstavení zvuku na určitou délku#3
[ai] apad=whole_len=cílový-min-počet-vzorků [ao]
@přidat na konec zvukové stopy nekonečné ticho#4
[ai] apad [ao]

3/16 Konverze mono/stereo/L/R

@duplikovat kanál mono-stopy na stereo-stopu#1
[ai] channelmap=mono-FR|mono-FL [ao]
@smíchat kanály stereo-stopy do mono-stopy#2
[ai] channelsplit,amix,channelmap=0-mono:mono [ao]
@sloučit kanály stereo-stopy do mono-stopy daným výrazem#3 (36)
[ai] [channelmap=FR-0|FL-1,]aeval=výraz:c=mono [ao]
@rozdělit stereo-stopu na FR a FL stopu/na dvě mono-stopy („pravou“ a „levou“)#4
[ai] channelsplit=channels=FR|FL [ao][ao]
[ai] asplit[io1][io2];[io1] channelmap=FR-mono:mono [ao];[io2] channelmap=FL-mono:mono [ao]
@spojit FR a FL stopu/„pravou“ a „levou“ mono-stopu do jedné stereo-stopy#5
[ai][ai] amerge [ao]
[ai][ai] join=map=0.0-FR|1.0-FL [ao]
@prohodit levý a pravý kanál stereo-stopy#6
[ai] channelmap=FR-FL|FL-FR [ao]

3/17 Generátory a čtení „bokem“

@bílý/jiný šum#1 (37)
anoisesrc=c=white[:d=trvání-v-s][:a=amplituda][:r=vzorkovací-frekvence] [ao]
anoisesrc=c=druh-šumu[:d=trvání-v-s][:a=amplituda][:r=vzorkovací-frekvence] [ao]
@načíst ze souboru obraz/zvuk/obraz i zvuk#2
movie=vstupní-soubor [vo]
amovie=vstupní-soubor [ao]
movie=vstupní-soubor:s=dv+da [vo][ao]
@ticho#3
anoisesrc=a=0[:d=trvání-v-s][:r=vzorkovací-frekvence]
@tón o zadané frekvenci#4 (38)
sine=f=frekvence-v-Hz[:d=trvání-v-s][:r=vzorkovací-frekvence]
@černý/modrý/poloprůhledný zelený/zcela průhledný obraz#5 (39)
color=c=#000000:s=šířkaxvýška[:r=fps][:d=trvání-v-sekundách]
color=c=#0000FF:s=šířkaxvýška[:r=fps][:d=trvání-v-sekundách]
color=c=#00FF0080:s=šířkaxvýška[:r=fps][:d=trvání-v-sekundách]
color=c=#00000000:s=šířkaxvýška[:r=fps][:d=trvání-v-sekundách]

3/18 Rozdělování a spojování

@naklonovat videovstup/audiovstup na více shodných výstupů#1
[vi] split=počet-výstupů [vo]
[ai] asplit=počet-výstupů [ao]
@spojit (za sebou) obrazové vstupy#2
[vi] concat=n=počet vstupů:v=1:a=0 [vo]
@spojit (za sebou) zvukové vstupy#3
[ai] concat=n=počet vstupů:v=0:a=1 [ao]
@spojit (za sebou) obrazové a zvukové vstupy#4
[vi][ai][vi][ai] concat=n=počet-dvojic-vstupů:v=1:a=1 [vo][ao]

3/19 Ostatní filtry

@pohltit obraz/zvuk bez výstupu#1
[vi] nullsink
[ai] anullsink
@ponechat obraz/zvuk beze změny#2
[vi] copy [vo]
[ai] acopy [ao]

4. Zaklínadla: Příkaz ffmpeg

Příkaz ffmpeg přijímá tři typy parametrů: globální, vstupní a výstupní. Globální parametry platí pro danou instanci ffmpegu jako celek. Vstupní parametry se zadávají v sekvenci ukončené parametrem -i a vstupním souborem a platí pouze pro daný vstup. Výstupní parametry se zadávají v sekvenci ukončené výstupním souborem a platí pouze pro daný výstup.

 

@obecný tvar příkazu ffmpeg#1
ffmpeg globální parametry [vstupní parametry -i vstup] [výstupní parametry] první-výstup [[výstupní parametry] další-výstup]

4/1 Globální parametry

@nastavit graf filtrů/načíst ho ze souboru#1 (40)
-filter_complex 'graf filtrů'
-filter_complex_script soubor
@existující výstupní soubor přepsat bez ptaní/nepřepsat a skončit s chybou#2
-y
-n
@vypnout interakci ffmpegu s uživatelem (vhodné při použití ve skriptu)#3
-nostdin

4/2 Výstupní parametry

@pro obrazové stopy: nastavit kodek/nepřekódovávat/zakázat výstup#1 (41)
-c:v kodek
-c:v copy
-vn
@pro zvukové stopy: nastavit kodek/nepřekódovávat/zakázat výstup#2 (42)
-c:a kodek
-c:a copy
-an
@nastavit bitrate obrazových stop/zvukových stop#3 (43)
-vb bitrate
-ab bitrate
@oříznout časovou osu (alternativy)#4
[-ss začátek] [-to konec]
[-ss začátek] [-t trvání-v-sekundách]
@nastavit jednoduchý graf filtrů pro obrazovou stopu/zvukovou stopu#5
-vf 'jednoduchý graf filtrů'
-af 'jednoduchý graf filtrů'
@vynutit konstantní fps obrazové stopy#6
-r[:číslo-stopy] fps
@nastavit jednoduchý graf filtrů pro obraz/pro zvuk#7
-vf 'jednoduchý-graf-filtrů'
-af 'jednoduchý-graf-filtrů'
@vynutit poměr stran videa obrazové stopy#8 (44)
-aspect[:číslo-stopy] hodnota
@konverze zvukové stopy na stereo/na mono#9
-ac[:číslo-stopy] 2
-ac[:číslo-stopy] 1
@zakázat výstup titulkových stop/datových stop#10
-sn
-dn
@vynutit vzorkovací frekvenci zvuku (v Hz, obvykle 44100, ale také 22050 či 48000)#11 (45)
-ar[:číslo-stopy] frekvence

4/3 Vstupní parametry

@oříznout časovou osu vstupního videa/nahrávky#1
[-ss začátek-s] [-t maximální-trvání-s] -i vstup
@načíst statický obrázek (jpg,png,bmp,tif,...) jako nekonečné video (pozor – ne gif!)#2
-loop 1 -i obrázek
@složit obrazovou stopu z obrázků#3
-framerate počet-snímků-za-sekundu -i předpona%05d.přípona

4/4 Celé příkazy

@konvertovat video a zvuk z jednoho formátu na druhý#1 (46)
ffmpeg -i vstupní-soubor.přípona -qscale:0 0 [-qscale:1 0] výstupní soubor.přípona
@spojit za sebou soubory#2 (47)
ffmpeg -f concat -safe 0 -i <(for x in soubor; do realpath -ze -- "$x"; done | sed -zE $'/^\\x2f/!d;s/\x27/&\\x5c&&/g;s/.*/file \x27&\x27/' | tr \\0 \\n) -c copy výstup
@rozložit video na obrázky ve formátu podle výstupní přípony: JPEG (jpg), PNG (png), BMP (bmp), TIFF (tif)#3
ffmpeg -i video.přípona -r počet-snímků-za-sekundu -f image2 -q:v 0 obrázek-%05d.výstupní-přípona
@vygenerovat sekvenci zmenšených náhledů z videa (šířka max. 640 pixelů), přibližně pro každou minutu#4 (48)
ffmpeg -i video -r 1/60 -q:v 14 -vf 'scale=min(640\,iw):-1' nahled%05d.jpg

5. Zaklínadla: Ostatní příkazy

@analyzovat soubor (ukáže stopy a jejich parametry)#1
ffprobe vstupní-soubor
@vypnout úvodní banner s verzí a konfigurací pro ffmpeg/ffprobe (jen pro interaktivní bash)#2
alias ffmpeg="ffmpeg -hide_banner"
alias ffprobe="ffprobe -hide_banner"
@vypnout úvodní banner s verzí a konfigurací pro ffmpeg/ffprobe#3
ffmpeg() { command ffmpeg -hide_banner "$@";}
ffprobe() { command ffprobe -hide_banner "$@";}"

6. Parametry příkazů

Parametry příkazů a způsob volání ffmpegu jsou uvedeny v sekci „Zaklínadla: Příkaz ffmpeg“.

7. Instalace na Ubuntu

sudo apt-get install ffmpeg [libavcodec-extra chromium-codecs-ffmpeg-extra]

Poznámka: ačkoliv jsou kodeky v balíčku chromium-codecs-ffmpeg-extra svobodné, mohou být omezeny patentovou ochranou podporovaných formátů. Pokud vám to vadí, použijte místo „chromium-codecs-ffmpeg-extra“ jen „chromium-codecs-ffmpeg“.

8. Ukázka

Ukázka vyžaduje, abyste v aktuálním adresáři měl/a video „video.mp4“ a to mělo alespoň 30 sekund, obraz (šířku i výšku alespoň 300 pixelů) a zvuk. První uvedený příkaz vypíše parametry videa. Druhý video zmenší na polovinu, vynechá zvuk a vlevo od obrazu umístí jeho černobílou kopii. Třetí příkaz obraz otočí o 180° a vymění dvě obdelníkové oblasti videa; současně do zvuku přidá roztmívačku a dvojnásobnou ozvěnu.

ffprobe video.mp4
ffmpeg -nostdin -filter_complex '[0:v]scale=2*trunc(iw/4):2*trunc(ih/4),split[a][b];[a]hue=s=0[a2];[a2][b]hstack[vv]' -i video.mp4 -c:v h264 -b:v 2048k -an -map '[vv]' bez-zvuku.mp4
ffmpeg -nostdin -hide_banner -filter_complex '[0:v]hflip,vflip,swaprect=100:150:10:15:200:50[vv];[0:a]afade=in:st=1:d=5:curve=exp,aecho=0.6:0.3:250|500:0.8|0.6[av]' -i video.mp4 -c:v h264 -b:v 2048k -c:a libmp3lame -b:a 64k -map '[vv]' -map '[av]' -to 20 hratky.mp4

9. Tipy a zkušenosti

  • Pokud obraz či zvuk neupravujete a nekonvertujete, můžete jejich původní kvalitu a kodek zachovat zákazem překódování pomocí parametru -c:v copy pro obraz, resp. -c:a copy pro zvuk. Zvuk můžete v takovém případě ořezávat pomocí výstupních parametrů -ss, -to-t, u obrazu to silně nedoporučuji, protože pak typicky trpí výpadky na začátku a konci výsledného videa.
  • Většina kodeků odmítne zapsat video, jehož šířka či výška v pixelech je lichá; myslete na to při používání filtru -scale.
  • Výstupy filtrů splitasplit musejí být odebírány paralelně, jinak hrozí přetečení bufferu. Řadě problémů se lze vyhnout tím, že místo rozdělení vstupu na dva načtete tentýž vstupní soubor vícekrát (více parametry -i). Rychlým (ale škaredým a nebezpečným) řešením problémů někdy může být zneužití filtrů „reverse“ a „areverse“, které dokážou v paměti zřídit buffer neomezené velikosti (resp. velikosti omezené jen množstvím dostupné paměti).
  • Můžete-li téhož efektu dosáhnout pomocí filtru nebo pomocí výstupního parametru, preferujte parametr; dává jistější výsledky, možná i kvalitnější.
  • Pokud použijete kodek „mjpeg“ a vypisuje vám varování „deprecated pixel format used, make sure you did set range correctly“, toto můžete bezpečně ignorovat.
  • Při zapékání titulků se ujistěte, že soubor s titulky je v kódování UTF-8 (což často nebývá). Titulky, které nepůjde tímto kódováním znaků dekódovat, filtr „subtitles“ bez varování vynechá!
  • Ačkoliv parametr „-filter_complex“ jako globální parametr správně patří na začátek příkazu, jeho uvedení tam je nepraktické a dle mých zkušeností ho ffmpeg správně přijme, i když ho uvedete až před parametry „-map“.
  • Kromě datových stop mohou být součástí multimediálního souboru i metadata, která se automaticky zkopírují do výstupního souboru a nepodařilo se mi přijít na způsob, jak se jich snadno zbavit.

10. Další zdroje informací

man ffmpeg
man ffmpeg-filters

Dalším velmi dobrým zdrojem je oficiální dokumentace k filtrům, ke které se dostanete tak, že si nainstalujete balíček „ffmpeg-doc“ a v prohlížeči otevřete soubor „/usr/share/doc/ffmpeg/manual/ffmpeg-filters.html“.

11. Zákulisí kapitoly

V této verzi kapitoly chybí:

  • filtry chorus, equalizer, highpass, lowpass, pan, silenceremove, stereowiden, volume (dynamicky)
  • popis vestavěných aritmetických funkcí
  • vysvětlení PTS
  • Otestovat, zda „-pix_fmt yuv420p“ umožní bezproblémové přehrátí videa s kodekem h264 (nebo mpeg4) na Windows 7 a Windows 10.
  • Dodělat ukázku.

Tato kapitola záměrně nepokrývá:

  • nic
1 Důvodem k rozdílné implementaci různého zrychlení a zpomalení je, že filtr „atempo“ akceptuje parametr pouze v rozsahu 0.5 až 2.0; vyšších, resp. nižších hodnot je možno dosáhnout zřetězením více těchto filtrů.
2 Pozor! Filtr reverse musí celé video nekomprimované uložit do paměti. Pro zpracování dlouhého videa tedy doporučuji dočasně zapnout opravdu velký odkládací soubor nebo video obracet po částech.
3 Na vstupu vezme maximálně 32 767 snímků a max. 2 147 483 647 zvukových vzorků, což obvykle odpovídá cca 21,8 minut obrazu a 13,5 hodině zvuku.
4 Poznámka: filtr „minterpolate“ je neparalelizovatelný a může být velmi pomalý.
5 Pozor, při zápisu do souboru musejí být šířka a výška obrazu pro většinu kodeků sudé! Toto omezení však neplatí, dokud je obrazová stopa jen zpracovávána uvnitř ffmpegu.
6 Barva se zde uvádí ve formátu #RRGGBB[AA] ve stejném významu jako v CSS).
7 Všechny hodnoty mohou používat rozměry snímku (w, h), čas v sekundách (t) a sekvenční číslo snímku (n).
8 Všechny použité vstupy musejí mít kromě stejné výšky/šířky také stejný formát pixelu (pixel-format).
9 Všechny vstupy musejí mít stejné rozměry. Toto lze docílit vhodným předzpracováním.
10 Hodnoty posunu jsou výrazy s výsledkem v pixelech. Mohou používat: rozměry hlavního videa (W, H), rozměry překryvného videa (w, h), čas v sekundách (t) a sekvenční číslo snímku (n). Poznámka: výstup filtru overlay není nikdy delší než délka jeho hlavního (prvního) vstupu a hlavní vstup rovněž určuje jeho šířku a výšku.
11 Ve výrazu můžete použít hodnoty: sekvenční číslo snímku (N), souřadnice pixelu ((X/SW), (Y/SW)), šířka a výška ((W/SW), (H/SW)), čas v sekundách (T) a především hodnotu složky prvního vstupu (A) a druhého vstupu (B).
12 Záporné hodnoty vyústí v inverzní obraz.
13 Přípustné hodnoty parametry allf jsou a, p, t, u a jejich kombinace operátorem +; při letmém vyzkoušení se mi jevily použitelné jen varianty „t“ a „t+u“ (jemnější).
14 Úhel čočky je v rozsahu 0 (žádný účinek) až PI/2 (maximální účinek). Pro vyhodnocování výrazů pro každý snímek musíte přidat parametr „eval=frame“.
15 Pokud název souboru obsahuje mezery či jiné speciální znaky, uzavřete ho do apostrofů. Zadáváte-li graf filtrů přímo na příkazové řádce do apostrofů, musíte kvůli bashi apostrof zadat kombinací "'\''".
16 Posun se zadává v sekundách s desetinnou částí, např. „2.0“ pro posun o dvě sekundy.
17 Nastavení stylu jsou ve formátu ASS, přičemž znaky = a , musíte odzvláštnit kvůli ffmpegu.
18 Všechny snímky před začátkem roztmívačky a za koncem zatmívačky budou nastaveny na uvedenou barvu, resp. zprůhledněny (je-li uveden parametr „alpha=1“).
19 Tip: Pro pochopení fungování této konstrukce důrazně doporučuji si uvedený graf filtrů nakreslit.
20 Začátek prolínačky zde znamená počet sekund od začátku prvního videa, kdy má prolínačka začít. Tento počet sekund je nutno předem zjistit.
21 Podporované tvary jsou: tri, qsin, hsin, esin, log, ipar, qua, cub, squ, cbr, par, exp, iqsin, ihsin, dese, desi, losi a nofade. Poznámka: Veškerý zvuk po konci zatmívačky, resp. začátkem roztmívačky bude tímto filtrem nahrazen tichem; to platí i pro tvar nofade.
22 Čas začátku a trvání efektu jsou v sekundách.
23 Mapa by měla mít stejný rozměr jako video a musí obsahovat bílé pixely na pozicích, kde je na videu předmět k odstranění, a černé pixely na místech, která se nemají změnit. Tento filtr je pro velké oblasti výpočetně náročný, proto by měla být drtivá většina pixelů mapy zcela černá.
24 Odstranění prokládání zvýší fps na dvojnásobek. Existuje na ně i mnoho dalších filtrů.
25 Prokládání obrazu sníží fps na polovinu.
26 Ačkoliv stejného efektu můžete dosáhnout i použitím univerzálních nízkoúrovňových filtrů, použití filtru „fade“ by mělo být výrazně rychlejší.
27 K tomuto úkolu slouží filtr „geq“, ale jeho efektivní použití je náročné a vyžaduje pochopení formátu pixelu a barevných kanálů U a V. Rovněž se mi nepodařilo s ním upravit alfa-kanál.
28 Ve výrazech můžete použít souřadnice výstupního pixelu „(X/SW)“ a „(Y/SH)“, šířku snímku „(W/SW)“, výšku snímku „(H/SH)“, čas v sekundách „T“ a sekvenční číslo snímku „N“. Souřadnice mimo rozsah budou zarovnány na nejbližší platnou hodnotu.
29 Ve výrazu můžeme použít: hodnotu prvního/druhého kanálu (val(0)/val(1)), čas vzorku v sekundách (t), číslo vzorku (n), číslo počítaného kanálu (ch), původní počet kanálů (nb_in_channels), vzorkovací frekvenci (s).
30 Filtr načte do vstupního bufferu tolik snímků ze vstupu, kolik jste zadal/a indexů. Následně na výstup vybírá snímky z bufferu podle indexů, které jste uvedli. Indexy se mohou opakovat a lze uvést speciální index -1, který způsobí vynechání snímku na výstupu (zahození).
31 Velikost bufferu musí být v rozmezí 2 až 512 (výchozí hodnota je 30); snímky se do bufferu vkládají sekvenčně a vybírají se v náhodném pořadí.
32 Má velké paměťové nároky, nepoužívat pro velký počet snímků; rozumný je tak maximálně 1000.
33 Hlasitost ozvěny je v rozsahu 0 až 1.0 a nesmí být 0. Filtr mírně sníží hlasitost původních zvuků, je potřeba ji vyladit.
34 Frekvence je v rozsahu 0.1 až 20000; rozumně slyšitelné jsou hodnoty do 20 Hz. Síla je v rozsahu 0.0 až 1.0.
35 V případě opakovaného použití v rámci jednoho grafu filtrů nahraďte identifikátor „tmpticho“ při každém použití jiným identifikátorem.
36 Hodnota první stopy je „val(0)“ a hodnota druhé „val(1)“.
37 Amplituda se uvádí v rozsahu 0 až 1. Místo white lze použít také pink, brown, blue a violet.
38 V praxi může být nutno zvýšit výchozí hodnotu parametru „samples_per_frame“, ale nemám s tím zkušenosti. Amplituda generovaného signálu je 1/8.
39 Nejsou-li zadány parametry „d“ a „r“, výstup generátoru bude nekonečný s fps 25.
40 Některá zaklínadla v této kapitole používají vložené příkazy bashe pomocí syntaxe „'"$(příkaz)"'“; tyto konstrukce budou v dané podobě fungovat jen na příkazové řádce.
41 Doporučené kodeky: „h264“ (synonymum „libx264“), „mpeg4“ (starší), „rawvideo“ (opatrně). Další použitelné kodeky: „gif“. Při generování série obrázků: „png“, „tiff“, „mjpeg“.
42 Doporučené kodeky podle formátu: „aac“ (pro mp4), „libmp3lame“ (pro mp3, ale i mp4), „pcm16_le“ (pro wav), „libvorbis“ (pro ogg), „flac“ (pro flac).
43 Možno použít přípony, např. 128k či 5M.
44 Doporučené hodnoty: 4:3, 16:9, 1:1, 5:4, 16:10
45 Doporučená hodnota: 44100; další obvyklé: 22050, 48000.
46 Uvedený parametr „-qscale“ se pokusí zachovat kvalitu vstupního souboru.
47 Názvy souborů při volání tímto způsobem nesmějí obsahovat apostrof. Při spojování tímto způsobem nedochází k překódování, takže vstupní soubory si musejí velmi přesně odpovídat všemi parametry, jinak hrozí problémy při přehrávání.
48 Časování je u tohoto příkazu velmi přibližné, proto se hodí spíše na dlouhá videa, kde posun o půl minuty či minutu nebude vadit.
[BY-SA]

Veškerý obsah této stránky (text, obrázky, zdrojový kód) je možno upravovat a šířit pod podmínkami licence Creative Commons Attribution-ShareAlike 4.0 International. Upozorňuji, že uvedená licence vyžaduje uvedení seznamu autorů, licence a zdroje a poskytnutí stejné či kompatibilní licence k provedeným změnám, jsou-li nějaké. Příslušné údaje jsou dostupné na stránce „Přehled autorů“. Šíření obsahu bez těchto údajů nebo šíření upravené verze bez poskytnutí adekvátní licence k provedeným úpravám je pravděpodobně porušení licenčních podmínek a může být postihováno. Poskytování zdrojového kódu při šíření není touto licencí vyžadováno.

Pro nové verze, další informace, aktuální zdrojový kód a možnost se zapojit do projektu „Linux: Kniha kouzel“ navštivte jeho repozitář na GitHubu.