FFMPEG jako univerzální nástroj pro video, zvuk a titulky

FFMPEG je konzolový program (dostupný pro Windows, Linux i MacOS), který dokáže automaticky zpracovat jakékoliv video, audio a dokonce i titulky a změnit kodek, bitrate, velikost, poměr stran nebo aplikovat další filtry.

Nevýhoda je, že neexistuje žádné GUI, ve kterém byste mohli vše přehledně nastavit (pravda, existují i GUI, jako třeba MeGUI, ale ani ty neumí nastavit vše). Přístup přes konzoli navíc umožňuje např. vytvořit skript, pomocí kterého pak můžete hromadně převádět videa (např. všechny díly seriálu).

Poznámka: Parametry budu uvádět pro Windows konzoli (cmd.exe). Pro PowerShell (Windows 10), Terminal (MacOS) a Bash (Linux) může být potřeba parametry jinak escapovat.

Pro Windows je netypické, že parametry se uvádí s pomlčkou místo lomítka. Pro Linux a MacOS naopak to, že i vícepísmenné parametry se uvádějí pouze s jednou pomlčkou.

Rychlá navigace

Momentálně převádím videa do HEVC pomocí nVidia karet, takže uvedené poznatky o ostatních (softwarových) video kodecích mohou být omezené pouze na to, co se o nich píše v dokumentaci.

Vstup a výstup

Základní parametry určují vstupní a výstupní soubor. Vstupní soubor se označuje parametrem -i (input). Pomocí opakování parametru -i můžete zadat i více souborů. Výstupní soubor může být vždy jen jeden a tak se uvádí jako úplně poslední parametr. Pokud jsou v názvu mezery, je potřeba uvést je do uvozovek (nebo před mezeru zapsat zpětné lomítko „\ „). Navíc můžete přidat parametr -y (overwrite: yes), pokud chcete výstupní soubor automaticky přepsat, pokud již existuje (to se hodí, když příkaz testujete a ukládáte stále do stejného souboru).

> ffmpeg -y -i "input.mkv" -parametry "output.mkv"
> ffmpeg -y -i "video.avi" -i "audio.wav" -i "text.sub" -parametry "output.mkv"

Na Windows můžete vytvořit Batch a pak můžete nechat jméno výstupního souboru automaticky vygenerovat:

set output=%~dpn1
ffmpeg -i "%1" "%output%.mkv"

Pomocí příkazu SET vytvoříte proměnnou. Pomocí %1 získáte první parametr Batch souboru. Pokud mezi znak procent a číslo parametru zadáte vlnovku, můžete pak určit, které části (pokud jde o soubor) se použijí: d je písmeno disku (např. „c:„), p je cesta („\users\admin\Video\„), n je jméno souboru („film.1080p„) a x je přípona („.mkv„).

Pro více-průchodové kodeky můžete jako výstupní soubor použít NUL (/dev/null na Linux a MacOS).

> ffmpeg -i "input.mkv" -pass 1 NUL

Poznámka: ve speciálních případech (např. když chcete z videa uložit snímky), může být potřeba zadat více výstupních souborů:

> ffmpeg -i "input.mkv" frame1.jpg frame2.jpg frame*.jpg

Časové posunutí vstupu

Pokud vám vložený zvuk nebo titulky nepasují na video, můžete je nechat posunout.

Poznámka: při exportu zvuku z DVD nebo Bluray většina programů posun zaznamená do jména souboru jako hodnotu DELAY -500ms, což znamená, že zvuk by se měl o půl sekundy předbíhat před videem. Ne vždy to ale skutečně platí a někdy je v takovém případě ověřit, že udaný čas je vhodný a nebo budete potřeba najít vhodnější posun.

Posun je potřeba před vstupní parametr souboru, který chcete posunout, zadat parametr -itsoffset s hodnout počtu sekund, o kolik chcete soubor posunout:

> ffmpeg -y -i "video.avi" -itsoffset 0.5 -i "audio.wav" "output.mkv"

Tento příklad říká, že zvuk bude uložen s půl sekundovým zpožděním a je potřeba ho použít, pokud se zvuk ve výsledném videu předbíhá před videem.

Pokud chcete opravit časování zvuku nebo titulků, které jsou uloženy v souboru s videem, musíte daný soubor uvést vícekrát a pak použít parametr -map (viz dále):

> ffmpeg -y -i "video.avi" -itsoffset 0.5 -i "video.avi" -map 0:v -map 1:a "output.mkv"

Tento příklad použije soubor video.avi dvakrát, kdy z prvního vezme video a z druhého posunutého vezme zvuk.

Poznámka: Nedoporučuje se používat posun na video nebo obecně první stream v souboru. V takové případě pak přehrávač nemusí být schopen správně sesynchronizovat všechny streamy a výsledek bude ještě horší než původní video. Pokud tedy máte zvuk a titulky (např. z české televize), které na sebe pasují, ale nepasují na video (protože je z americké televize), posuňte raději zvuk i titulky, než abyste se snažili ušetřit si práci tím, že posunete jen video.

Vstupní formáty

FFMPEG vždy* vytváří výstupní soubor ve formátu MKV (Matroska; MK je zkratka pro Matroska Kontejner).

Výraz vždy platí pro případ, kdy je výstupem video. Pokud je výstupem zvuk, titulky nebo sekvence obrázků, vždy se uloží soubor v příslušném formátu (např. *.mp3 pro MP3 zvuk, *.srt pro titulky, *.png pro snímky z videa, atd.).

Jako vstupní soubory můžete použít celou řadu formátů a kontejnerů:

  • AVI (Audio-Video interleave) je kontejner (RIFF) vyvinutý pro Windows a může obsahovat jedno video a jeden zvuk (v novější verzi i titulky). Funguje tak, že vždy obsahuje jeden snímek videa a k němu příslušející část zvuku. Přehrávač tak má vždy k dispozici vše, co potřebuje k přehrání části videa. Jelikož je z roku 1992, nepodporuje (plně) moderní kodeky (MPEG-4 a novější) a funkce (např. B snímky). Je používán starými digitálními fotoaparáty a kamerami (z 90. let).
  • MOV (QuickTime Movie) je konkureční formát vyvinutí firmou Apple pro jejich MacOS (MacOS X používá novější QuickTime X, který je součástí iTunes pro MacOS a Windows). Na rozdíl od AVI podporuje více audio i video stop v jednom soubory a místo video stopy může obsahovat sekvenci JPEG obrázků, ale pro uložení video v tomto formátu je potřeba zakoupit QuickTime Pro. Některé (starší) digitální fotoaparáty a kamery ukládají video v tomto formátu právě proto, že stačí uložit zvuk a nasnímané JPEG obrázky (takže není potřeba mít v zařízení další video kodek).
  • MP4 je formát definovaný MPEG standardem za účelem sjednocený rozdílů AVI a MOV. Podporuje více video a audio stop a titulky. Plně podporuje všechny MPEG formáty (AVC, HEVC, MP3, AAC, TTXT titulky atd.) a může obsahovat i další data, i když to není příliš často používané. Je používán většinou HD a 4K fotoaparátů, kamer a chytrých telefonů.
  • 3GP, 3GPP a 3GP2 je součást MPEG standardu pro uložení MPEG-2 (H.263) videa a AMR zvuku v mobilních zařízeních. Generuje menší velikost souboru, ale podporuje pouze video a zvuk v malém rozlišení a kvalitě (kvalita telefonního hovoru). Používali ho „klasické“ mobilní telefony.
  • MKV je Matroska kontejner, který může obsahovat prakticky cokoliv od videa a zvuku, přes titulky a seznam kapitol až po písma použitá v titulcích nebo menu s odkazy do videa. Může obsahovat i více stop (včetně několika video stop, různých formátů titulků, atd.). Je používán pro stahování videí z internetu, je podporován většinou moderních přehrávačů, ale není používán pro ukládání (např. z videokamery). Poslední písmeno určuje typ obsahu, kde MKV je video, MKA je zvuk bez videa, MKS jsou pouze titulky (prakticky nepoužívané) a MK3D je 3D film.
  • OGG je kontejner určený pro šíření video a audio souborů používající OGG Vorbis kodeky (viz dále). Podle typu obsahu může mít různé přípony (OGG a OGV pro video, OGA pro video, OGX pro ostatní). Lze také použít pro další svobodné (open-source) formáty jako FLAC, Opus, Theora, atd.
  • AVS (AviSynth) není ve skutečnosti video kontejner ale skript, který jen odkazuje na jiný video soubor (stream, DVD, BluRay, apod.) a určuje, jak se má zpracovat. Obvykle je výsledkem nějakého DVDrip nebo BDrip programu, ale můžete ho stáhnout i z internetu (pak obvykle obsahuje URL streamu). Abyste mohli použít AVS jako vstupní soubor pro FFMPEG, musíte použít 32-bitovou verzi FFMPEG (protože AviSynth nemá 64-bitovou knihovnu) a mít nainstalovaný program AviSynth (současná verze FFMPEG vyžaduje verzi AviSynth 2.6+) nebo umístit soubor avisynth.dll do složky FFMPEG.

Hardwarová akcelerace vstupu

Pokud máte grafickou kartu Nvidia s podporou AVC a HEVC (GeForce 9xx, 10xx a novější), můžete ji použít pro rychlejší dekódování vstupního videa:

> ffmpeg -hwaccel nvdec -i input.mkv output.mkv

Parametr -hwaccel (hardware acceleration) je potřeba zadat před vstupním souborem, který obsahuje video kompatibilní s MPEG (AVC, HEVC, MPEG4 a některé verze DivX a Xvid. Tímto ale spustíte obecný MPEG dekodér, který je sice rychlejí než softwarové dekódování (prováděné v CPU), ale…

Pokud máte 100% jistotu, že vstupní video obsahuje AVC nebo HEVC video, můžete použít hardwarový dekodér přímo určený pro tyto videa. Výhoda je v tom, že je mnohem rychlejší než obecný MPEG dekodér, ale nevýhoda je, že pokud ho zvolíte špatně, dekódování selže. Dekódovací kodek pro vstupní video se určuje stejně jako pro výstupní video parametrem -c:v:

> ffmpeg -c:v h264_cuvid -i avc_input.mkv output.mkv
> ffmpeg -c:v hevc_cuvid -i hevc_input.mkv output.mkv

Poznámka: ve starší verzi FFMPEG nebylo možno použít obecný dekodér nvdec, ale bylo potřeba použít cuvid dekodér parametrem -hwaccel cuvid a za něj uvést jméno dekodéru přes parametr c:v před vstupním souborem:

> ffmpeg -hwaccel cuvid -c:v h264_cuvid -i avc_input.mkv output.mkv

Pozor ale na to, že dekódování videa je zhruba stejně náročné jako jeho enkódování. Pokud tedy na slabší kartě oba procesy zaberou více než 50% výkonu GPU, budou se navzájem brzdit. Pak je lepší nechat dekódování na CPU a využít výkon GPU na enkódování.

Pokud máte v PC více grafických karet (SLI, MB, apod.), hardwarová akcelerace vstupu bude probíhat na první kartě, která to podporuje. Použitím parametru hwaccel_device můžete dekódování přesunout na jinou kartu, pokud si myslíte, že je vhodnější:

> ffmpeg -hwaccel nvdec -hwaccell_device 1 -i input.mkv output.mkv

Před použitím akcelerace vstupu (a výstupu) si nejprve ověřte, že je opravdu výhodnější a jak je potřeba úlohy rozdělit.

Například na mé sestavě 2×GeForce 1080 a 6×4GHz CPU, zabere dekódování 4K videa asi 25% výkonu karty (té první) a následné enkódování pak 35% výkonu karty (a dvě jádra CPU). Lze tedy bez problémů využít první kartu pro dekódování dvou 4K videí současně a zároveň je obě enkódovat na druhé kartě. Pokud bych měl ale kartu jen jednu, bylo by možno ji využít pouze pro dekódování jednoho videa a druhé by se muselo dekódovat na CPU, aby měla karta dostatek výkonu na enkódování druhého videa. Navíc CPU by muselo být alespoň 8-jádrové, protože 4 jádra jsou potřeba pro enkódování obou videí a zbylá 2 jádra by si se 4K videem neporadila.

Framerate vstupního videa

Pokud nemá vstupní video stabilní počet snímků za sekundu (např. internetový stream nebo záznam videohry), může docházet k tomu, že vstupní dekodér se pokusí opravit počet snímků tím, že některé zahodí nebo doplní tak, aby splnil předpokládaný framerate (fps). Pokud to není žádoucí, můžete použít parametr -vsync pro upřesnění, jak se má video načíst.

Výchozí hodnota 1 nebo cfr znamená, že dekodér musí vždy vrátit stejný počet snímků za sekundu (i za cenu ztráty nebo zdvojení snímků):

> ffmpeg -vsync 1 -i input.mkv output.mkv

Ve většině takových případů ale chcete, aby se snímky zpracovali přesně tak, jak byly nahrány. Pokud ne, mohlo by se video jevit trhaně. Použijte parametr 0 nebo passthrough:

> ffmpeg -vsync 0 -i input.mkv output.mkv

Třetí možnost 2 nebo vfr použijte, pokud například nahráváte hru s 60fps, ale chcete ji uložit jako video s 50fps (PAL). Dekodér pak bude sice zahazovat nadbytečné snímky, ale nebude si vymýšlet nové tam, kde hra běžela pomaleji než 50fps:

> ffmpeg -vsync 2 -i input.mkv output.mkv

Kodek

Nejčastěji používaný parametr -c, který označuje kodek, který se použije pro převod souboru. Za parametr je potřeba uvést :v:a nebo :s pro rozlišení videa, zvuku a titulků (dříve -vcodec-acodec a -scodec).

Pro seznam kodeků, které podporuje vaše verze FFMPEG, můžete použít parametr -codecs:

> ffmpeg -codecs

Před jménem kodeku se zobrazují písmena slova DEVILS (ďáblové; starší verze mohou používat jiné pořadí), které znamenají: D = načtení vstupního videa (decode), E = uložení výstupního videa (encode), V označuje video kodek (alternativně A je audio kodek a S formát titulků), I označuje intra frame-only kodek (tedy kodek, který zpracovává pouze jednotlivé snímky bez jejich vzájemného vztahu; tyto kodeky nejsou vhodné pro filmy, ale naopak jsou vhodné pro videa určená pro další střih), L označuje schopnost ztrátové komprese (Lossy) a S podporu bezztrátové komprese (Lossless).

Pro následné získání podrobného popisu kodeku a jeho parametrů použijte nápovědu s parametrem encoder=XXX, kde místo XXX uvedete jméno kodeku. Například pro získání parametrů pro hardwarový HEVC použijte:

> ffmpeg -h encoder=nvenc_hevc

Nejpoužívanější kodeky pro uložení filmů

  • MPEG-4, používaný u DVD a DVB-T (využívá kompresy H.263 a vychází z MPEG-1/H.261 a MPEG-2/H.262). Z MPEG-4 vychází „pirátské“ kodeky DivX 3 a Xvid a komerční (placené) DivX 4+, které se zaměřují na lepší kompresi za cenu ztráty kvality a proto se dříve používali pro nelegální filmy. V dnešní době jsou již příliš nekvalitní, aby mělo smysl je používat pro nová videa. Smysl mají jen pokud máte hodně staré PC nebo přehrávač, který nepodporuje nebo výpočetně nezvládá modernější kodeky.
  • AVC (Advanced Video Codec, MPEG-4 part 10 též označovaný H.264), který se používá u HD BluRay a filmů šířených v MKV formátu. AVC má přibližně 2x lepší kompresi než MPEG-2 a dosahuje lepší kvality u HD videa.
  • HEVC (High Efficiency Video Codec též H.265, původně označený MPEG-H part 2), který se používá pro 4K BluRay a nejmodernější DVB-T2 (používané i v ČR). Pro HEVC stačí poloviční bitrate při zachování stejné kvality jako AVC u HD. U 4K může být i 3x až 4x efektivnější.
  • QuickTime a Windows Media Video jsou formáty používané ve video editorech na MacOS a Windows a také pro filmy zakoupené v obchodech iTunes (AppStore) a Zune Marketplace). Video uložené v tomto formátu je vázáno licencí, takže se příliš nerozšířili. Video může obsahovat DRM, takže nepůjde použít v FFMPEG!
  • Theora (OGG) je svobodný (open-source) kodek jako alternativa ke komerčním MPEG, QuickTime a WMV. Nepoužívá žádné patentované technologie, takže lze legálně využít k jakýmkoliv účelům.

Nejpoužívanější Audio Kodeky

  • PCM (Pulse-Coded Modulation) je formát, který ukládá zvuk tak, jak byl nahrán (A/D převod). Zvuk na CD je kódován pomocí LPCM (Linear PCM). Nadstavbou je FLAC (a APE), který používá bezztrátovou kompresi pro zmenšení souboru. Běžně používaný formát je 44.1kHz při 16 bitech, který má bitrate kolem 700kbps; PCM i FLAC podporují Stereo (2.0) i prostorový zvuk (5.1).
  • MP3 (zkratka z MPEG Layer 3), které ze zvuku vylučuje nadbytečné části (např. když levý i pravý kanál hrají to samé, uloží jen jeden, tzv. Joint-Stereo). Jde tedy o ztrátovou kompresi vhodnou pro filmy a písničky pro méně náročné posluchače. Kompresí je MP3 asi o polovinu lepší než starší MP2.
  • AAC (Advanced Audio Codec; interně označované jak AAC-LC = AAC with Low Complexity) je stejně jako AVC součástí MPEG-4 standardu a je tedy kvalitnější než MP3 a používá se jako jeho modernější verze. AAC (na rozdíl od MP3) podporuje i více kanálů, takže jde použít pro prostorový zvuk, ale nepoužívá se pro komerční filmy a DVB-T, protože si filmová studia zvykla na AC3 od Dolby Digital. Naopak se využívá v DAB standardu (digitální rádio). V kompresi je AAC asi o třetinu až polovinu lepší než MP3 a dvakrát lepší než MP2.
  • HE-AAC nebo AAC HEv1 nebo AAC+ nebo (chybně) MP4 (High Efficiency AAC; interně označené AAC-LC SBR = AAC with Low Complexity and Spectral Band Replication) je vylepšená verze AAC (stejně jako HEVC zlepšuje kompresi AVC), která zlepšuje kvalitu zvuku pomocí uložení dalších informací o zdrojovém zvuku (SBR) a také zlepšuje kompresi pomocí Modified Discrete Cosine Transformation (MDCT). Pozor ale na to, že u nižších bitrate je SBR větší než schopnost MDCT, takže soubor budě větší (a kvalitnější) než AAC-LC. Další verze AAC HEv2 navíc doplňuje Parametric Stereo (PS), které zlepšuje kompresi 2-kanálového zvuku (modernější verze Joint-Stereo u MP3), ale nejde použít pro Mono nebo více-kanálový zvuk. Používá se pro DAB+. Podporované jsou na Android 4.1+ a iOS 4+ a tedy vhodné pro moderní mobily coby „MP3 přehrávače“. HEv1 a HEv2 je zpětně kompatibilní s AAC-LC, takže i starší přehrávače je přehrají, jen budou ignorovat SBR složku (a u HEv2 budou ignorovat PS a hrát jen Mono).
  • AC3 (nově označovaný jako Dolby Digital) je formát pro ztrátové uložení vícekanálového zvuku (2.0 až 5.1). Používá se na DVD a v (multi-)kinech. Kvalita je srovnatelná s AAC, ale má trochu horší kompresi (takže AAC může být o 5 až 10% menší při stejné kvalitě). E-AC3 (Enhanced AC3) je vylepšený formát obsahující další informace o zvuku (obdoba SBR u AAC). Nemusí být ale zpětně kompatibilní s hodně starými přehrávači, které podporují jen první verze AC3.
  • DTS (Digital Theater System) je bezztrátová komprese pro vícekanálové zvuky používaný na novějších DVD, BluRay a některých kinech. DTS má vždy bitrate 1536kb/s (u DVD může být i poloviční 768kb/s). DTS má řadu rozšíření, např. DTS-ES (6.1/7.1), DTS-HD (používá částečně ztrátovou kompresy), DTS TrueHD (vylepšená bezztrátová komprese) a DTS NEO:6 (Dolby Pro Logic II, tedy Stereo zvuk doplněný o informaci, jak ho přehrát na 5.1/6.1/7.1 systémech).
  • Dolby Atmos a DTS:X (a také DTS-TrueHD Atmos) jsou nové formáty (resp. vylepšení AC3 a DTS), které přidávají podporu pro horní reproduktory (reproduktory na stropě nebo na horní straně soundbaru či reproduktorů) neboli 3D zvuk. Formát se označuje třemi čísly, např. 5.1.2 znamená 5 prostorových kanálů, 1 subwoofer a dva horní kanály (levý a pravý).
  • Vorbis (OGG) je svobodný (open-source) kodek pro ztrátovou kompresi zvuku, který měl nahradit formáty MP3 a WMA (Windows Media Audio). I když je Vorbis (a WMA) kvalitnější než MP3 (s kompresí lepší asi o třetinu), nikdy nedosáhl rozšíření, protože neměl vlastní zařízení; na rozdíl od MP3 a iPod přehrávačů (a méně úspěšného Zune). FFMPEG ho automaticky použijte, pokud nezvolíte kodek pro audio stopu.
  • Opus je svobodný kodek určený pro ztrátovou kompresi zvuku vyvinutý pro Skype (ještě než ho koupil Microsoft) a vychází z OGG projektu. Jelikož sloužil pro přenos kvalitních hovorů přes Skype (v době, kdy byl internet pomalý), používá rozdílné komprese pro hlas (zvuk do 8kHz) a hudbu (nad 8Khz). Dnes ho používá většina VoIP telefonů a webových prohlížečů (video-chat).

Nejpoužívanější formáty titulků

  • SUB/IDX (Subtitles with Index) je formát používaný na DVD. Titulky jsou uloženy jako obrázky (*.SUB) s časovými značkami (*.IDX), takže mohou obsahovat libovolné znaky (češtinu, arabštinu, atd.) a formátování (i když to se málokdy používá). Pro převod na ostatní formáty je potřeba použít OCR (rozpoznávání textu).
  • SUP (SubPictures) je modernější verze SUB/IDX používané na BluRay. Používá stejný princip (obrázky), jen v jiném (lepším) formátu.
  • SRT je základní textový formát, který obsahuje číslo titulku, počáteční a koncový čas a následně prostý text. Díky použití časových značek je nezávislý na frekvenci (fps) a dá se tak použít jak na PAL tak NTSC. Díky jednoduchému formátu je oblíbený u překladatelů, protože není potřeba speciální program pro jejich vytvoření. Novější verze SRT podporuje jednoduché formátování (tučné písmo, apod.)
  • SUB je starý formát používaný u nelegálních filmů. Titulky se časují podle čísel snímků, takže jsou přesnější než ostatní formáty, ale dá se použít vždy pouze s danou verzí filmu (podle počtu snímků).
  • SSA a ASS (SubStation Alpha a Advanced SSA) jsou titulky vyvinuté (z SRT formátu) pro (japonské) karaoke systémy a s oblibou se používá pro překlad japonských seriálů (anime). Podporuje nejen formátování (četně karaoke synchronizace), ale i pozicování či posouvání textu. Titulek tak může být umístěn přímo přes původní (japonský) text (např. cedule na zdi) a posouvat se s obrazem.
  • VTT (Web Video Text Track) jsou titulky vytvořené jakou součást HTML5 standardu pro video přehrávače v prohlížečích. Vychází z SRT formátu, ale nejsou s ním zpětně kompatibilní. Podporuje formátování podobně jako HTML stránky (i když nepoužívá CSS).

Poznámka: Pro převod mezi formáty SRT, SUB, SSA/ASS a VTT můžete použít FFMPEG. Pro převod SUB/IDX a SUP musíte použít OCR, které se součástí Subtitle Edit programu.

Použití kodeku

Například pro použítí AVC (H.264)  pro zpracování video použijte parametr:

> ffmpeg -i input.mkv -c:v h264 output.mkv

Pro použití MP3 (MPEG Layer 3) na zvuk použijte:

> ffmpeg -i input.mkv -c:a mp3 output.mkv

Pro převod titulků (např. WebVTT z Youtube) do ASS použijte:

> ffmpeg -i input.vtt -c:s ass output.mks

Hardwarová akcelerace výstupu

Pokud máte NVIDIA kartu (řady GeForce 9×0, 10×0 a novější), můžete použít vestavěné kodeky (v seznamu se označují nvenc) a CUDA jádro pro rychlejší převod videí. Pro použití AVC (H.264) použijte:

> ffmpeg -i input.mkv -c:v nvenc_h264 output.mkv

Pro novější HEVC (H.265) pak:

> ffmpeg -i input.mkv -c:v nvenc_hevc output.mkv

Použití grafické karty se hodí pro rychlý převod, kdy nepotřebujete úplně nejlepší a nejmenší soubor, ale chcete rychle převést větší množství videí. Např. 8 jádrový procesor na 4GH zvládne zpracovat HD video do kodeku HEVC rychlostí zhruba 30 snímků za sekundu a 4K asi 2 snímky za sekundu (takže převod trvá hodiny až dny). Naproti tomu grafická karta (GTX 1080) na 1,7GHz zvládne HD video zpracovat rychlostí až 500 snímků za sekundu a 4K až 50 snímků za sekundu, takže převod HD filmu trvá pár (desítek) minut (samozřejmě záleží na videu, použitých filtrech, atd.).

Grafická karta ale nemá tolik možností jako softwarový kodek, takže  obvykle vytvoří o něco větší soubor. Navíc má výchozí hodnoty většinou nastavené na co nejrychlejší zpracování, takže pokud potřebujete vytvořit kvalitní a/nebo malý soubor, musíte uvést mnohem více parametrů (viz dále).

Navíc běžně dostupné verze karet (určené pro hraní) jsou omezeny na maximálně 3 současně zpracovaná videa nezávisle na tom, kolik karet v PC máte (např. 3xSLI). Pokud chcete skutečně používat Nvidia karty pro převod více videí současně, musíte sáhnout po verzi k tomu přímo určené (např. nVidia Titan). Poznámka: omezení na 3 videa je pouze softwarové (v ovladačích), takže je možné na internetu najít upravené ovladače, které umožní i na obyčejné kartě zpracovat více videí současně. Takové ovladače zase ale nemusejí být vhodné pro hraní her!

Zpracování kopírováním

Pokud nechcete kodek měnit, můžete použít klíčové slovo copy. Např. při zpracování videa můžete zadat „-c:a copy“ a FFMPEG pouze přiloží audio ve stejném formátu, v jakém je ve stupním souboru. Pro zkopírování všech stop použijte jen -c copy. Pro zkopírování titulků (subtitle) použijte -c:s copy.

> ffmpeg -i input.mkv -c copy output.mkv
> ffmpeg -i input.mkv -c:v copy -c:a copy -c:s copy output.mkv

Pro zkopírování všech stop a následný převod konkrétní stopy použijte:

> ffmpeg -i input.mkv -c copy -c:v hevc output.HEVC.mkv

Pozor, pokud parametr -c neuvedete, FFMPEG sám vybere kodek a tím danou stopu převede:

> ffmpeg -i video.mkv -c:v hevc video.HEVC.mkv
... příkaz převede i audio na jiný formát!!!

Bitrate a kvalita

Při zadání kodeku je také (většinou, např. PCM a DTS mají pevný bitrate) potřeba určit kvalitu zpracování videa a zvuku. To má pak v důsledku vliv na datový tok (bitrate) neboli kolik bajtů zabere jedna sekunda videa nebo zvuku.

Konstantní bitrate CBR

Nejjednodušší možnost je zadat přímo pevný bitrate (CBR), který udáte kvalitu výstupního souboru – obvykle se používá pro audio ve formátu MP3, AAC nebo AC3. Uvádí se do parametru -b za který uvedete :v pro video a :a pro audio a následně hodnotu:

> ffmpeg -i input.mkv -c:v h264 -c:a mp3 -b:v 2000k -b:a 192k output.mkv

Pozor na to, že bitrate uvádí celkový datový tok pro celou stopu. U vícekanálového audia tak musíte počítat s tím, že stejný tok znamená nižší kvalitu pro jednotlivé stopy. Např. 64kb/s u mono odpovídá 128kb/s stereo MP3 a 384kb/s 5.1. Obvykle používané 448kb/s u AC3 5.1 tedy odpovídá stereo kvalitě 150kbps AAC nebo 192kb/s MP3. Obvykle platí, že použití vyššího bitrate než je vstupní nezlepší kvalitu, ale pouze zvětší soubor. Pokud tedy chcete převést 448kb/s AC3 na Stereo, nemá smysl použít 320kb/s MP3, protože stejné kvality dosáhnete i s 192kb/s MP3.

Různé kodeky mají různou kvalitu komprese, takže při převodu ze staršího do novějšího kodeku (např. MPEG4 na HEVC, nebo MP2 na AAC) je potřeba příslušně upravit bitrate. Například staré video uložené v MPEG-2 s bitrate 2000kbps nebo MPEG-4 (resp. DivX či Xvid) s bitrate 1500kbps můžete uložit bez ztráty kvality jako 1000kbps AVC (x264) nebo 500kbps HEVC (x265) (s drobným zhoršením je potřeba počítat, protože každé překódování JPEG/MPEG vyvolá mírnou ztrátu kvality). Stejně tak MP2 uložené s 192kbps můžete převést na MP3 128kbps nebo AAC 96kbps. U běžného videa tak můžete ušetřit 30% – 60% místa na disku.

Při zadávání bitrate (i jakékoliv jiné číselné hodnoty, pokud to dává smysl) můžete použít přípony k a M pro určení tisíců nebo milionů, přičemž se vždy počítá s očekávanou jednotkou. Pro bitrate tak hodnota 128k (pro zvuk) znamená 128kb/s neboli 128000b/s a hodnota 10M (pro video) znamená 10Mb/s neboli 10’000kb/s (či 10’000’000b/s). Vždy se počítá s násobky 1000, nikoliv s binárním 1024!

Proměnlivý bitrate VBR

Pro kodeky podporující proměnný bitrate (VBR) můžete zadat tzv. kvantifikátor kvality, který určuje přibližnou kvalitu, které by se měla kvalita videa nebo zvuku přiblížit. Ten se místo -b uvádí do parametru -q (quality; ve starších verzích se používalo -qscale) nebo pro některé kodeky -vbr a má rozsah podle daného kodeku (např. 1 až 31 pro AVC, 0 – 51 pro HEVC, 0 až 9 pro MP3, 0 až 5 pro AAC, apod). Nejmenší číslo (obvykle 0 nebo 1) znamená obvykle nejlepší kvalitu:

> ffmpeg -i input.mkv -c:v h264 -c:a mp3 -q:v 16 -q:a 4 output.mkv

Kvantifikátor s doporučeným bitrate

Když použijete nastavení podle kvantifikátoru (to platí jak pro parametr -q, tak i pro dále uvedené -qp, -qmin a -qmax nebo -crf či -cq), můžete také připojit parametr -b:v (tedy bitrate pro video), který kodek použije jako vodítko pro bitrate, kterého byste chtěli dosáhnout. A když bitrate neuvedete, kodek si vybere vlastní doporučený, kterého se bude držet (např. pro HEVC je to 2000kb/s, což je dostatečné pro běžná videa s ohledem na schopnosti HEVC).

Rozdíl mezi konstantním bitrate a doporučením bitrate je v tom, že konstatního bitrate se kodek musí držet, což znamená, že některé snímky může uložit s hodně špatnou kvalitou (např. výbuchy) a naopak u jiných bude zbytečně ukládat data, která nepotřebuje, aby bitrate splnil (např. černé přechody). Oproti tomu doporučený bitrate (označuje se avg, tedy průměrný bitrate, ale není to přesné) není až tak závazný, a pokud kodek zjistí, že pro některý snímek nebo klidně celé video není daný bitrate vhodný, nemusí se ho držet a může použít vyšší nebo nižší.

Pro příklad i když HEVC používá doporučený bitrate 2000kb/s, při zadání –q 40 pro video 320×480 klidně uloží video s 500kb/s a naopak 4K video uloží s bitrate 10’000kb/ při zadání -q 19.

Rozdíl je v tom, jak bude kodek odhadovat kvantifikátor pro jednotlivé snímky. Např. když kodek pro nějakou scénu odhadne kvantifikátor 25 a vypočte, že by ji zkomprimoval na 2500kb/s, podívá se na doporučený bitrate a pokud je očekávaný bitrate výchozích 2000kb/s, zkusí, jak kvalitní by scéna byla s kvantifikátorem 24 nebo 23 tak, aby se ještě více přiblížil 2000kb/s, ale příliš nesnížil kvalitu videa. Pokud ale doporučený bitrate nastavíte na 5000kb/s, zkusí kodek naopak to, jestli by s kvantifikátorem 26 nebo 27 nedosáhl výrazně lepší kvality vzhledem k tomu, že 2500kb/s je méně než doporučujete. Scénu pak uloží třeba s 3000kb/s, což je více než původní odhad, ale pořád méně než doporučená hodnota.

> ffmpeg -i input.mkv -c copy -c:v hevc -q:v 16 -b:v 5M output.mkv

Pokud doporučený bitrate zkombinujete s minimální nebo maximálním kvantifikátorem (-qmin a/nebo -qmax) a následně se kvantifikátor při převodu drží této minimální nebo maximální hodnoty, znamená to, že doporučený bitrate je příliš vysoký nebo nízký – to sice nijak neovlivní kvalitu videa v daném rozsahu, ale úpravou doporučeného bitrate byste mohli dosáhnout lepší komprese (tedy menšího souboru) nebo vyšší kvality. Například pokud zadáte rozsah kvantifikátoru jako 19 – 32 a bitrate 3000kb/s a celý převod je hodnota q=18 (FFMPEG zobrazuje o jedna menší hodnotu), znamená to, že se video ukládá v nejlepší možné kvalitě (daného rozsahu).  Pokud v takovém případě snížíte bitrate třeba na 2000kb/s, začne kodek využívat celého rozsahu, bude ukládat video s proměnlivým bitrate a dosáhne menšího souboru. Naopak pokud bude q=31 po celý převod, znamená to, že ztrácíte příliš detailů a zvýšením bitrate získáte lepší kvalitu videa za cenu trochu většího souboru nebo pokud je pro vás velikost souboru důležitá, zkuste posunem rozsahu třeba na 24 – 40 zlepšit kvalitu alespoň některých snímků při zachování průměrného bitrate. Pokud se během převodu hodnota q drží konstantě uprostřed (např. q=25), znamená to jen, že video neobsahuje výrazné odchylky, pro které by bylo potřeba kvantifikátor měnit a není ani potřeba upravovat vstupní parametry.

Maximální bitrate

V kombinaci s kvantifikátorem můžete použít ještě parameter -maxrate:v, který udává maximální datový tok. To je výhodné v případě, že video plánujete streamovat přes internet nebo LAN (např. z NAS) nebo přehrávat z USB 2.0 disku (např. v TV). U HEVC to obvykle není potřeba, protože to má samo o sobě nízký datový tok. Tím zamezíte tomu, aby některé scény (např. výbuchy) zabrali příliš mnoho a způsobili zasekávání videa:

> ffmpeg -i input.mkv -c:v h264 -c:a copy -q:v 16 -maxrate:v 10M output.mkv

Pozor na to, že udání kvality nemá přímý vztah na bitrate a záleží na kodeku. U AVC tedy -q:v 20 může (podle videa) odpovídat 10Mb/s zatímco u HEVC bude -q:v 20 znamenat 5Mb/s (protože HEVC má 2x lepší kompresy). Také záleží na obsahu, takže MP3 s -q:a 1 bude u hudby přes 220kb/s zatímco hovor bude kolem 160kb/s.

Konstantní kvantifikátor QP

Některé kodeky (Xvid, AVC a HEVC) podporují ještě tzv. konstantní kvantifikátor kvality (též označovaný quatization parameter, proto je parametr -qp), který naopak udává kvalitu, kterou video musí dosáhnout. Hodnota je v rozsahu 0 až 51 (kde 0 je nejmenší komprese a tedy maximální kvalita, 51 je prakticky nekoukatelná kvalita). Jelikož je tento parametr jen pro video, již se neuvádí „:v„:

> ffmpeg -i input.mkv -c:v h264 -c:a mp3 -qp 16 -q:a 4 output.mkv

Pro AVC se doporučuje kvantifikátor 20 (resp. 16 až 24 podle požadované kvality) nebo, pokud jde ale o animovaný film, můžete jít až na 30 (resp. 28 až 32; nezapomeňte ale použít -tune animation, viz dále). Pro HEVC můžete použít 28 (24 až 32), protože snese větší kompresi bez viditelné ztráty kvality. Čísla menší než 16 u AVC a 19 u HEVC nemá smysl používat, protože nepřinesou zlepšení; uvedené hodnoty jsou tzv. visual lossless neboli zdánlivě bezztrátové.

Čím je vyšší rozlišení videa (HD nebo 4K), tím vyšší kompresi (tedy větší číslo QP) můžete použít. Pro HD (720p nebo 1080p) se tedy doporučuje 20 (AVC) a 28 (HEVC), zatímco pro 4K je lepší 24 a 32. Naopak pro staré SD video (480p, 320×240, apod.) použijte buď 16 (AVC) nebo 24 (HEVC), pokud je to kvalitní video (DVDrip s původním bitrate 2 až 5Mb/s) nebo naopak 32 až 40 pro nekvalitní (většinou seriály nahrané z videa při bitrate 800 – 1600kb/s).

Každých 6 bodů QP změní bitrate a velikost souboru zhruba o polovinu. Například pokud QP 16 vytvoří 10GB soubor, pro QP 22 bude 5GB, pro 28 jen 2,5GB a pro 32 jen 1GB.

Kvantifikátor z rozsahu

Pokud se nemůžete rozhodnout pro konkrétní hodnotu, můžete použít parametry -qpmin a -qpmax a určit tak rozsah hodnot. Kodek se pak bude chovat podobně jako při zadání -crf (viz dále):

> ffmpeg -i input.mkv -c:v h264 -qpmin 16 -qpmax 24 output.mkv

Pokud chcete použít zcela automatický režim, zadejte celý rozsah od 0 do 51; kodek pak sám odhadne nejlepší QP pro každý snímek:

> ffmpeg -i input.mkv -c:v h264 -qpmin 0 -qpmax 51 output.mkv

Pokud po použití -qpmin nebo -qpmax vrátí kodek vrátí „neznámý parametr“, zkuste místo toho použít parametry -qmin a -qmax:

> ffmpeg -i input.mkv -c:v h264 -qmin 16 -qmax 24 output.mkv

Při udání rozsahu se kodek řídí doporučeným bitrate (viz výše). Pokud tedy zadáte rozsah např. 16 až 24 pro HEVC, ale necháze výchozí doporučený bitrate 2000kb/s, bude kodek většinu snímků zpracovávat s kvantifikátorem 24, protože bitrate 2000kb/s je příliš nízký pro daný rozsah a bude to stejné jako použít parametr -qp 24. Pokud tedy chcete použít rozsah v určité kvalitě, může být potřeba nejprve zjistit přibližný bitrate pro dané kvality a následně zadat průměrnou hodnotu, aby kodek věděl, jak má video zpracovávat.

Pro příklad změníme doporučený bitrate na 5Mb/s, který více odpovídá zadanému rozsahu kvantifikátorů:

> ffmpeg -i input.mkv -c:v hevc -qmin 16 -qmax 24 -b:v 5M output.mkv

Poznámka: Mohlo by se to někomu zdát podivné, ale čím je bitrate menší a kvantifikátor QP větší (a tedy dosáhnete vyšší komprese a menšího souboru), tím je zpracování videa rychlejší. Je to tím, že MPEG (a všechny ztrátové komprese) je založena na tom, že nejprve zahodí nepotřebné detaily (podle nastaveného QP) a pak teprve komprimuje obrázek – čím méně detailů, tím méně dat ke zpracování, což vede k rychlejší kompresi a menšímu souboru. Naopak bezztrátové komprese jako ZIP, WinRAR, FLAC, PNG, atd. musí zpracovat vše, a tudíž lepší komprese a menší soubor vyžadují více času na zpracování.

Proměnlivý kvantifikátor CRF

Pro AVC a HEVC můžete použít ještě jednu možnost a tou je CRF (Constant Rate Factor, což by se dalo přeložit jako Neměnný dojem ze sledování). Někdy je též označováno jako Constant Quality (Konstantní kvalita). Proto se pro softwarové AVC a HEVC uvádí jako -crf (pro hardwarové kodeky viz dále).

Při použití tohoto nastavení kvality se bude kodek snažit nastavit takový kvantifikátor (QP), aby každá scéna byla dostatečně kvalitní podle zadaného parametru, ať už se jedná o den (jasné barvy), noc (tma a jasná světla), honičky (rychlé změny), výbuchy (náhlé rozjasnění), atd. Jde tedy o nejlepší možnost pro celovečerní filmy, které obsahují rozličné scény a každá vyžaduje jiný způsob zpracování. Na druhou stranu je nejnáročnější na zpracování a tedy nejpomalejší. Pokud ho chcete použít, doporučuji použít hardwarový kodek (nVidia karta) nebo softwarový s rychlou optimalizací (preset = very fast).

Hodnota CRF je v rozsahu 0 až 51 (nebo 0 až 63 pro 10-bit formát pixelů – viz dále) a určuje výchozí hodnotu kvantifikátoru QP; kodek pak v závislosti na analýze scény hodnotu QP zvýší nebo sníží (zhruba o +/- 4 body) pro dosažení stejného dojmu kvality.

Pro AVC je doporučená hodnota 23 (resp. 18 až 28 podle požadované kvality) zatímco pro HEVC (díky lepší kompresy) je doporučeno použít hodnotu 28 (resp. 23 až 32):

> ffmpeg -i input.mkv -c:v h264 -c:a copy -crf 23 output.mkv
> ffmpeg -i input.mkv -c:v libx265 -c:a copy -crf 28 output.mkv

Pro hardwarový kodek HEVC se parametr určuje jako -cq (Constant Quality) a navíc je potřeba ho zkombinovat s minimální kvalitou -qmin (viz výše) a predikcí kvality -rc (viz dále) s hodnotou vbr_hq (Variable Bitrate); také se doporučuje zvolit preset buď slow nebo llhq a zadat doporučený bitrate (viz výše) nebo -qmax (nejhorší přípustnou kvalitu), protože výchozí kvalita 2Mb/s nemusí být vhodná pro všechna (hlavně HD a 4k) videa.

U novějších karet Turing (např. RTX 20×0) a Ampere (RTX 30×0) jsou parametry trochu přepracovány a je potřeba místo -rc vbr_hq zadat -rc vbr -tune hq. Navíc u karet Ampere se změnily hodnoty pro -preset , takže místo slow a fast lze zvolit p1 (nejrychlejší) až p7 (nejpomalejší). Pro rychlý přechod p6 odpovídá slow a p2 = fast.

Celé nastavení proměnného kvantifikátoru pro hardwarové HEVC je tedy:

//Maxwell a Pascal (GTX 9x0 a 10x0)
> ffmpeg -i input.mkv -c:v hevc_nvenc -rc:v vbr_hq -preset slow -cq:v 28 -qmin 19 -b:v 5M -maxrate:v 10M output.mkv

//Turing a Ampere (RTX 20x0 a 30x0)
> ffmpeg -i input.mkv -c:v hevc_nvenc -rc:v vbr -tune hq -preset p7 -cq:v 28 -qmin 19 -b:v 5M -maxrate:v 10M output.mkv

Pokud chcete nechat odhad kvality na kodeku, můžete použít parametr s hodnotou 0 nebo menší (třeba -1). Kodek pak u každého snímku videa provede automatickou analýzu a vybere nejvhodnější kompresy tak, aby zachoval co nejlepší kvalitu, ale zároveň dosáhl dobré komprese s ohledem na doporučený bitrate.

Vzhledem k použití doporučeného bitrate ale automatika není úplně nezávislá a neznamená to, že video uloží v nejlepší možné kvalitě. Při zpracování automatikou doporučuji sledovat, jaké kvantifikátory kodek používá a jaký je výsledný bitrate. Pokud se kvantifikátor nemění a bitrate se drží těsně u doporučené hodnoty (např. při 2000kb/s pro HEVC se mění mezi 1900 a 2100), znamená to, že doporučený bitrate není pro dané video vhodný a kodek se víceméně přepnul do režimu konstantního bitrate. U takového videa je pak vhodné zkusit pro automatiku změnit bitrate (obvykle zvýšit) a ověřit, jestli třeba při doporučeném bitrate 3000kb/s, 5000kb/s nebo 10Mb/s nebude automatika lépe odhadovat kvantifikátor pro jednotlivé snímky (tedy kvantifikátor a bitrate bude více skákat).

Poznámka: pamatujte na to, že FFMPEG při enkódování sice zobrazuje bitrate, ale je to průměrná hodnota za určitou dobu (zhruba půl sekundy) a navíc jde o bitrate celého souboru. Pokud tedy jsou v souboru i zvuky (DTS, AC3, apod.), bude zobrazený bitrate mnohem vyšší, než je kvalita videa a navíc bude zkreslený proměnnými datovými toky zvuků a dalších stop.

Predikce kvality RC

U AVC a HEVC můžete použít tzv. rate control neboli řízenou kvalitu. Ta funguje tak, že kodek se podívá vždy na několik snímků dopředu a podle jejich obsahu určí, jak nejlépe uložit současný snímek vzhledem k tomu, co bude následovat (např. již nebude vkládat klíčový snímek, pokud za pár snímků přijde nová scéna).

Rate control se skládá ze dvou parametrů, kde -rc určuje způsob, jakým se bude měnit kvalita, a -rc-lookahead (volně přeloženo jako pohled do budoucnosti) určuje, kolik následujících snímků se má prohlédnout za účelem uložení toho současného (v příkladu se prohlédne následující jedna sekunda videa při 25fps).

Při použití -rc-lookahead byste ještě měli přidat parametr -b_adapt a vypnout tak obousměrné snímky (B-frames), které nejsou příliš kompatibilní s „pohledem dopředu“, protože odkazují na starší snímky (navíc HW kodeky je nepodporují vůbec).

> ffmpeg -i in.mkv ... -rc:v vbr_hq -rc-lookahead 25 -b_adapt 0 out.mkv

Pro -rc můžete použít různé metody (které se dost často mění, takže vypsat jejich seznam nedává smysl), ale nejlepší je vbr_hq (Variable bitrate for high quality mode neboli proměnlivý datový tok pro dosažení vysoké kvality; resp. vbr -tune hq), která mění bitrate tak, aby dosáhla co nejlepšího výsledku (tedy vysoké kvality tam, kde je potřeba, a nízkého bitrate, kde to potřeba není).

Alternativní metody jsou cbr_hq (Constant bitrate for high quality mode) a constqp (Constant quantization parameter), které naopak podle analýzy snímků zvolí datový tok nebo kvantifikátor vhodný pro celou sekvenci snímků.

Poznámka: parametr -rc lze použít i pro některé audio kodeky, proto je lepší použít -rc:v, aby nedošlo ke kolizi. U hardwarového kodeku je parametr -rc vyžadován pro aktivování režimu proměnlivého bitrate.

Adaptivní kvantifikátor

Rozšíření CRF (neboli CQ) režimu pro kodek HEVC (a možná jiné) umožňuje uložit část snímku s jiným kvantifikátorem (tzv. Adaptivní kvantifikátor neboli AQ), například pokud je část scény na světle a jiné ve tmě nebo se liší rychlostí pohybu, apod. Kodek pak může různé části jednoho snímku uložit s různou kvalitou, aby tak zachoval dojem z videa (konstantní kvalita) a přitom ušetřil místo na disku.

Pro použití AQ u HW kodeků potřebujete kartu Turing nebo Ampere. Starší Maxwell a Pascal je nemají implementovány ve svém procesoru. Zapnutí AQ u podporovaných karet navíc zrychlí zpracování, protože karta může plně využít všechny funkce, které má k dispozici, k analýze vstupního videa a snížit tak nároky na výsledné zpracování.

Základní rozšíření se jmenuje Prostorově Adaptivní kvantifikátor (Spatial AQ) a aktivuje je parametrem -spatial-aq 1 volitelně doplněný o parametr -aq-strength (síla AQ), který udává, jak hodně se má kodek snažit AQ ve snímku použít (1 = hodně málo, 15 = hodně často). Výchozí hodnota je 8; pokud vidíte nepřirozené přechody mezi jednollitými barvami, sílu zvyšte; pokud naopak vidíte črozmazání nebo čtverečky (artefakty) místo detailů (obličeje, písmena, apod.), pak sílu snižte.

Díky Spacial AQ může kodek lépe (tedy s lepší kvalitou) uložit scény s velkými jednobarevnými plochami (černá tma, modré nebe nebo moře, zelená tráva, šedá silnice, apod.). Jinými slovy: použije vyšší bitrate v části, kde by mohlo vlivem nízkého množství detailů dojít k přílišné kompresy (tedy určení nízkého QP základním CQ/VBR algoritmem) a vzniku nepřirozených přechodů barev, a naopak sníží bitrate v částech, kde je dostatek detailů a tohle nehrozí (to proto, aby se zachoval průměrný bitrate a nedošlo k překročení maximální povolené hodnoty).

Pozor na to, že příliš vysoká hodnota (10 až 15) může způsobit to, že AQ přidá příliš detailů do míst, kde žádné nejsou, čímž vynutí snížení bitrate v částech s detaily a místo, aby se artefakty odstranili, tak se přesunou do míst, kde by jinak nebyly.

Další rozšíření se jmenuje Časově Adaptivní kvantifikátor (Temporal AQ), který používá predikci -rc-lookahead k tomu, aby určil, na které části scény je vhodné použít prostorové AQ, aby se dosáhlo co nejlepší kvalitu videa vzhledem k tomu, jak se budou jednotlivé objekty po scéně pohybovat (proto je doporučeno zvýšit -rc-lookahead oproti běžné hodnotě; pozor ale, že se tím zpomalý zpracování). Aktivuje se parametrem -temporal-aq 1.

Časové AQ funguje tak, že najde části scény, které se příliš (nebo vůbec) nebudou (v čase) měnit a na začátku scény v nich zvýší detaily (tedy bitrate). Díky tomu pak v další části scény nebude potřeba na tuto část plýtvat bitratem a ten se bude moci použít na části, kde se něco hýbe a je buď potřeba tento pohyb podrobně popsat, aby nedošlo k efektu rozmazání pohybu, nebo doplnit pozadí dříve zakryté pohybujícím se předmětem. Typicky scéna, která začíná pohledem na prázdný prostor, do kterého následně něco vstoupí (např. auto přijíždějící na parkoviště) nebo naopak scéna, ze které něco zmizí (např. konec rozhovoru dvou lidí, kteří následně odejdou z místnosti).

> ffmpeg -i in.mkv ... -spatial-aq 1 -aq-strength 8 -temporal-aq 1 -rc-lookahead 100 output.mkv

Pokud porovnáte velikost videa uloženého s konstantní kvalitou (CQ) bez AQ a se zapnutým AQ, pravděpodobně si všimnete, že video je po použití AQ výrazně větší (klidně i o 30%). Je to proto, že zatímco AQ zlepšuje kvalitu části snímku nebo scény na úkor jejího zbytku, tak CQ hlídá kvalitu celého snímku. Pokud tedy AQ záměrně sníží kvalitu části snímku (obvykle v části, kde je hodně detailů), přinutí tím CQ zvýšit bitrate, aby se zachovali všechny detaily (dle nastavené hodnoty -cq). Při použití CQ + AQ, pokud je pro vás důležitá velikost souboru, doporučuji použít vyšší CQ (tedy horší kvalitu), protože o lepší vyvážení poměru kvality a bitrate se postará AQ. Navíc se tím zpracování zrychlí a vykompenzuje tak zpomalení způsobené větším -rc-lookahead. Také je možno vzít v úvahu to, že AQ již dostatečně analyzuje jak aktuální, tak i následné snímky, takže není potřeba používat dvoukrokové zpracování a můžete snížit hodnotu -preset a/nebo -multipass a ještě více zrychlit zpracování:

//bez AQ použijeme doporučenou kvalitu 28
> ffmpeg -i input.mkv -c:v hevc_nvenc -rc:v vbr -tune hq -preset p6 -multipass 2 -cq:v 28 -qmin 19 output.mkv

//se zapnutým AQ můžeme snížit celkovou kvalitu
> ffmpeg -i input.mkv -c:v hevc_nvenc -rc:v vbr -tune hq -preset p2 -multipass 1 -cq:v 32 -qmin 19 -spatial-aq 1 -aq-strength 8 -temporal-aq 1 -rc-lookahead 100 output.mkv

Poznámka: parametry -preset p6 multipass 2 odpovídá u Ampere staršímu -preset slow, zatímco -preset p2 -multipass 1 částečně odpovídá staršímu fast; navíc s tím, že první průchod se provede jen se čtvrtinovým rozlišením a tedy čtyřnásobnou rychlostí. Podle mých prvotních testů zapnutí AQ s vyšší rychlostí způsobí zvětšení souboru jen v řádu desetin procent (resp. pár MB), zatímco z hlediska rychlosti se video zpracuje dvakrát i vícekrát rychleji.

Vážený odhad kvantifikátoru

Vážená (neboli weighted) analýza predikce -rc-lookahead umožňuje rozpoznat začátek nebo konec scény se zčernáním (tzv. fade-in a fade-out), kdy se scéna mění tím, že se postupně ztmavuje nebo zesvětluje. Na základě této analýzy pak může kodek přizpůsobit kompresy tak, aby ušetřil místo a přitom zachoval kvalitu přechodu scény.

Aktivuje se parametrem -weighted-pred a vyžaduje zadání parametru -rc-lookahead, který pak určuje, jak dlouhé zčernání je kodek schopen rozpoznat (např. při 25fps a lookahead 100 dokáže rozpoznat 4-sekundový přechod).

> ffmpeg -i in.mkv ... -rc-lookahead 100 -weighted-pred 1 output.mkv

Pozor, tento režim nelze použít na vstupním videu, které obsahuje tzv. obousměrné snímky (B-frames), protože ty mohou odkazovat na starší snímky, které si predikce nemusí pamatovat.

Pokud tedy použijete tento parametr a dostanete chybu „Cannot read input“ nebo „Failed to lock input frame“ často doprovázený nějakým záporným číslem (což je právě odkaz na starší snímek) nebo dokonce restartem grafické karty (při použití hardwarové akcelerace vstupu), znamená to, že vstup obsahuje B snímky a video nelze zpracovat. Pro nápravu stačí vynechat parametr -weighted-pred a video by se mělo normálně zpracovat.

Odlišná kvalita pro část videa

Pokud chcete část videa uložit v odlišné kvalitě, můžete použít (i opakovaně) parametr -rc_override:v, který má parametr se třemi čísly, kde první dvě udávají počáteční a koncový snímek a třetí udává hodnotu parametru -q (kladné číslo) nebo -qp (záporné číslo). Např. pro uložení prvních 30 sekund (obvykle loga produkce) v nižší kvalitě:

> ffmpeg -i input.mkv -c:v h264 -q:v 16 -rc_override "0,750,24" output.mkv

Pixel formát

Video se ukládá tak, že každý pixel definuje 3 složky – buď barvy (obvykle RGB, tedy červenou, zelenou a modrou) nebo jas a dvě barvy (PAL, NTSC, apod.). Pokud každou složku uložíte jako 8bitovou (jak se ukládají např. BMP nebo JPG obrázky), bude mít každá složka k dispozici pouze 256 různých hodnot (24bit RGB, neboli TrueColor).

Jelikož ale většina kodeků (vycházejích z MPEG) používá kompresy na základě vymazávání nepatrných rozdílů v odstínech barev, použití celé 24bitové škály pak nedává smysl (pokud ji přesto chcete použít, zadejte rgb24). Proto se používají obvykle méněbitové formáty, kdy každý pixel může zabrat jen 15, 12, 10, nebo 9 bitů. V případě RGB se obvykle používá 15bitový formát (5bitů na barvu, 32 odstínů; formát RGB555), u YUV (jas a barvy) se používá 12bitový formát (4 bity na složku, 16 odstínů; formát yuv420p). U černobílých filmů jde použít jen 9bitů (512 odstínů šedé; formát gray9)

Pokud chcete kvalitnější video, můžete vynutit vícepixelový formát. Pokud naopak chcete co nejmenší soubor a oželíte drobné barevné chyby, můžete použít 10bitový formát.

Formát pixelu zadáváte parametrem -pix_fmt (pixel format). Nestačí ale zadat jen 9, 10 nebo 15, ale je potřeba zadat název barevného schématu, které daný kodek podporuje. Jejich seznam získáte zadáním příkazu:

> ffmpeg -pix_fmts

Ve sloupci BITS_PER_PIXEL uvidíte, kolik bitů zabere jeden pixel. Ve sloupci NB_COMPONENTS je pak uvedeno, kolik složek bude mít každý pixel – 3 znamená RGB nebo YUV, 1 je černobílý obraz (gray), 4 je průhledný obraz RGBA a 0 znamená, že se nic nebude ukládat (např. formáty D3D11(DirectX 11) a cuda (CUDA jádro) mohou sloužit k testování, jak rychle dokáže grafická karta video zpracovat pokud není zpomalována rychlostí disku, na který se video ukládá).

Pro co nejmenší HEVC soubor tedy použijte:

> ffmpeg -i input.mkv -c:v HEVC -pix_fmt p010le output.mkv

Poznámka: 10 bitový formát používejte pouze ve spojení s HEVC, protože ten je dostatečně kvalitní na to, aby snesl pouze 3bity na složku. Ostatní kodeky (AVC, MPEG-4, apod.) při tomto formátu vytváří příliš mnoho chyb a artefaktů.

Při hardwarovém zpracování videa pozor na to, že karta primárně pracuje v 24bitovém (resp. 12bitovém NV12) formátu a převod do 10bitového probíhá až v procesoru, který převod zpomaluje.

Preset

Některé kodeky (AVC, HEVC, DivX, Xvid, apod.) podporují parametr -preset (uložená nastavení), pomocí kterého můžete rychle nastavit parametry převodu.

Pro kodeky AVC a HEVC to jsou např. fast, medium a slow, které udávají rychlost převodu a velikost souboru (ale neovlivňují kvalitu). Nastavení medium je výchozí rychlost zpracování, které má dobrý poměr rychlost/velikost, ale v praxi není výhodné. Nastavení fast zpracuje video rychle, ale výsledný soubor bude velký – hodí se tedy na testování výsledné kvality. Naopak slow bude trvat déle (protože použije dva průchody pro každý snímek), ale výsledný soubor bude co nejmenší – hodí se tedy pro výsledný převod pro uložení nebo zálohování:

> ffmpeg -i input.mkv -c:v h264 -qp 16 -preset fast output.mkv
> ffmpeg -i input.mkv -c:v h264 -qp 16 -preset slow output.mkv

Doladění

Kodeky AVC a HEVC podporují parametr -tune, který říká kodeku, co vlastně zpracovává, aby mohl lépe optimalizovat kompresní algoritmy.

Pro AVC je doporučeno použít film (hraný film) nebo animation (kreslený film). Pro prezentace obsahující statické fotky můžete použít stillimage

> ffmpeg -i input.mkv -c:v h264 -qp 16 -preset slow -tune film output.mkv

Pro HEVC nejsou hodnoty film a stillimage dostupné a v takovém případě parametr -tune vůbec neuvádějte!

Pro staré filmy (nebo nové filmy natáčené staršími kamerami) obsahující zrnění byste měli použít optimalizaci grain, které vezme zrnění v úvahu a upraví podle toho enkódování. V opačném případě dojde k jeho přílišnému rozmazání a ke zvýšenému výskytu artefaktů a dalších chyb.

> ffmpeg -i output.mkv -c:v h264 -qp 16 -preset slow -tune grain output.mkv

Pokud zpracováváte online streamy, použijte parametr zerolatency (pro odchozí stream načítaný z místního disku) nebo fastdecode (pro příchozí stream ukládaný na disk). Tím zajistíte, že zpracování každého snímku bude vždy trvat jen tak dlouho, kolik umožňuje fps (a počet jader procesoru, protože např. na 8 jádrovém CPU může zpracovat 8 snímků najednou, takže jeden snímek může zpracovávat 8x déle než na 1 jádrovém CPU).

Optimalizaci fastdecode také můžete použít při zpracování HD nebo 4k videa, které plánujete přehrávat z mobilu nebo jiného méně výkonného zařízení, protože tato optimalizace zároveň ukládá video ve formátu, který nepotřebuje tolik výkonu na přehrávání (ale zabere více místa).

Ostatní volby jako psnr a ssim slouží pouze pro testování při vývoji.

Profil

Všechny MPEG kodeky (tedy i AVC a HEVC) se rozdělují do tzv. profilů, které určují, jaké zařízení potřebujete pro přehrání daného souboru.

To je proto, že ne všechny přehrávače, televize, konzole a přenosná zařízení mají stejně výkonný procesor a dostatečně velkou obrazovku a nemusejí tedy být schopny zpracovat a zobrazit všechna rozlišení.

Pokud ukládáte video pro použití v PC, obvykle vás profil nemusí vůbec zajímat. Pro specifická zařízení budete muset použít speciální profil, který obvykle najdete v návodu nebo specifikaci na daného zařízení. Rozlišují se 3 profily: baseline (nejjednodušší určený pro mobilní zařízení), main (základní určený pro běžné DVD přehrávače a TV) a high (určený pro výkonná PC, BluRay přehrávače, herní konzole, atd.).

Profil je dále nutné kombinovat s tzv. levelem, který určuje, jaké rozlišení je dané zařízení schopno přehrát. V současnosti se používají levely 3.x (mobilní rozlišení od 176×144 až 720×576; level 3.1 ještě podporuje 1280×720), 4.x (HD rozlišení 720p, pro 1080p je potřeba 4.2) a 5.x (4K rozlišení). V blízké budoucnosti pak možná narazíte na 6.x (8K).

Do FFMPEG předáváte hodnoty přes parametry -profile:v a -level:

> ffmpeg -i input.mkv -c:v h264 -qp 16 -profile:v high -level 4.2 output.mkv

Stříhání

Pomocí FFMPEG můžete  ustřihnout začátek videa, abyste ho nemuseli překódovávat celé. K tomu slouží parametr -ss (seek start). Důležité ale je, kam parametr umístíte.

Pokud parametr umístíte před vstupní soubor, bude oříznut vstupní soubor a nebude se tedy překódovávat ta část před určeným časem:

> ffmpeg -ss 1:00:00 -i input.mkv output.mkv   //přeskočí první hodinu

Poznámka: čas můžete zadat ve formátu hodiny:minuty:sekundy.milisekundy (kde hodiny a milisekundy jsou volitelné) nebo jen jako počet sekund (volitelně s milisekundami jako desetinné číslo), takže 1:00:00.0 se rovná hodnotě 3600.0.

Výhoda oříznutí vstupního souboru je v tom, že se přeskočená část nemusí zpracovávat a převod tak proběhne rychleji. Nevýhoda je v tom, že přeskočení se provede pomocí klíčových snímků, takže začátek nebude přesně tam, kde jste určili, ale o pár sekund dříve (v příkladu výše např. na 0:59:47). Doplnění: od verze 2.1 se provede vyhledání klíčového snímku a následně přeskočí zbytek videa až k požadovanému času. Dříve uvedené (přeškrtnuté) ale stále platí v případě, že video kopírujete bez překódování (parametr -c:v copy)!

Druhá nevýhoda oříznutí vstupního souboru je v tom, že změní čas videa a pokud tedy do videa přikládáte (hard-coded) titulky, budete v nich muset změnit časová razítka (což FFMPEG sám neumí, ale můžete použít třeba Aegisub).

Druhá možnost je oříznout výstupní soubor, čímž umožníte videu začít přesně v daný okamžik. Toho dosáhnete tím, že parametr umístíte mezi vstupní a výstupní soubor:

> ffmpeg -i input.mkv -ss 1:01:16 output.mkv 
//začne přesně 1 hodinu, 1 minutu a 16 sekund po začátku videa

Nevýhoda oříznutí výstupního souboru je v tom, že vstupní soubor se bude zpracovávat od začátku, takže v uvedeném příkladu se bude muset překódovat celá první hodina a přitom se nebude ukládat. Nenechte se zmást tím, že v tomto případě FFMPEG nebude zobrazovat proces převodu pro přeskakovanou část, jen bude prostě dlouhé minuty vypadat zaseknutě.

Tento způsob se tedy hodí pouze v případě, že chcete přeskočit jen prvních pár minut (např. úvodní znělku), což nebude trvat tak dlouho je překódovat.

Obejít zdlouhavost převodu vstupního souboru bez výstupu se dá zkombinovat použitím parametru dvakrát: poprvé pro přibližné oříznutí vstupního souboru a podruhé pro přesné oříznutí výstupu. V tomto případě ale budete muset přepočítat čas, protože oříznutí výstupního souboru bude probíhat až po oříznutí vstupního souboru, což změní čas:

> ffmpeg -ss 1:00:00 -i input.mkv -ss 1:16 output.mkv

Pokud video kopírujete, musíte připočítat dřívější začátek (o 13 sekund):

> ffmpeg -ss 1:00:00 -i input.mkv -c:v copy -ss 1:29 output.mkv

Pro oříznutí konce videa můžete použít parametr -to (anglicky do nebo ), který udává koncový čas videa. Pozor na to, že v kombinaci s oříznutím vstupního souboru se čas počítá od začátku výstupu (je tedy potřeba čas začátku odečíst od času konce), zatímco při oříznutí výstupu se počítá od začátku vstupního souboru (tedy pořáteční i koncový čas používají stejný časový rámec):

//uložení prvních 5 minut videa pro oba případy:
> ffmpeg -ss 1:00:00 -i input.mkv -to 0:05:00 output.mkv
> ffmpeg -i input.mkv -ss 1:00:00 -to 1:05:00 output.mkv

Problém s rozdílným časem můžete vyřešit parametrem -t (terminate), který vždy ukončí výstup po uložení určitého počtu sekund:

//uložení prvních 5 minut videa bez rozdílu začátku:
> ffmpeg -ss 1:00:00 -i input.mkv -t 05:00 output.mkv
> ffmpeg -i input.mkv -ss 1:00:00 -t 05:00 output.mkv

V případě, že video kopírujete (parametr -c:v copy), nemusí výstup skončit přesně v daném okamžiku v případě, že vstupní video obsahuje obousměrné (B neboli bi-directional) snímky. Video může skončit pouze na klíčovém (K neboli key), průběžném (P neboli predictive) nebo samostatném (I neboli individual) snímku.

Více stop

Pokud na vstupu uvedete více souborů stejného typu (obvykle audio) nebo soubor s více stopami (obvykle MKV), musíte určit, které stopy se použijí a v jakém pořadí. Bez speciálního parametru převede FFMPEG pouze jednu video a jednu audio stopu, kterou najde. Pravidlo je, že zachová tu nejlepší (tedy video s největším rozlišením, zvuk s nejvyšším datovým tokem, apod.).

Pro použití více stop, nebo případně pro jejich proházení, musíte použít parametr -map, za který zadáte číslo vstupního souboru a číslo stopy. Výstupní soubor pak bude stopy obsahovat v pořadí, v jakém je zadáte do příkazu.

Seznam stop získáte zadáním vstupních souborů bez zadání výstupního souboru:

> ffmpeg -i video.mkv -i czech.ac3

... příklad výstupu:
Input 'video.mkv'
    Stream #0:0 (eng) Video
    Stream #0:1 (eng) Audio DTS
    Stream #0:2 (eng) Audio AC3
Input 'czech.ac3'
    Stream #1:0 AC3

Pokud v tomto případě chcete zachovat anglickou a českou AC3 stopu, použijte příkaz:

> ffmpeg -i video.mkv -i czech.ac3 -c copy
         -map 0:0 -map 0:2 -map 1:0 video.cz.mkv

Pokud máte české czech.DTS a chcete ho přiložit jako DTS a zároveň jako další stopu ve formátu AC3, můžete stejnou stopu použít vícekrát. Následně musíte pro parametry -c:a a -b:a uvést ještě číslo stopy, kde :a:0 je první stopa daného typu, :a:1 je druhá, atd.:

> ffmpeg -i video.mkv -i czech.dts -c copy
         -map 0:0 -map 0:2 -map 1:0 -map 1:0
         -c:a:2 ac3 -b:a:2 448k 
         video.cz.mkv

Pro zjednodušení můžete zkopírovat všechny stopy ze souboru:

> ffmpeg -i video.mkv -i czech.ac3 -c copy -map 0 -map 1 video.cz.mkv

Parametr map můžete použít i pro rozdělení souboru na stopy:

> ffmpeg -i video.mkv -i czech.ac3 -c copy 
         -map 0:0 -map 0:2 video.en.mkv
         -map 0:0 -map 1:0 video.cz.mkv
         -map 0:1 eng.dts

Pokud nevíte, která stopa je která, můžete místo čísla použít v, a, s, atd. FFMPEG pak vybere tu nejlepší:

> ffmpeg -i video.mkv -i czech.ac3 -c copy -map 0:v -map 1:a video.cz.mkv

U streamovaných videí můžete pro označení stopy použít číslo programu:

> ffmpeg -i http://stream.tv -c copy -map 0:p:1234 video.mkv
> ffmpeg -i http://stream.fm -c copy -map 0:0x1234 audio.mka

Pomocí parametru map můžete i vynechat konkrétní stopy nebo typ stopy. Stačí za parametr -map uvést identifikátor stopy začínající mínusem (resp. pomlčkou, protože oba znaky jsou totožné):

> ffmpeg -i video.en+cz.mkv -c copy -map -0:a:0 video.cz.mkv

Nastavení jazyka

Pokud sestavujete soubor z více stop (DTS, AC3, MP3, atd.) s různými jazyky, budete potřebovat specifikovat, která stopa je ve kterém jazyce.

To můžete provést pomocí parametru -metadata:s:a:0, kde :s určuje, že medatada jsou pro specifický stream (stopu), :a určuje typ stopy (v = video, a = zvuk, s = titulky) a :0 určuje její pořadí ve výstupním souboru (0 = první stopa, 1 = druhá stopa, atd.).

Za parametrem pak uveďte jazyk ve formátu language=xxx, kde xxx je tříznakový kód jazyka.

> ffmpeg -i video.en.mkv -i czech.ac3 -c copy -map 0:v -map 1:a -map 0:a -metadata:s:v:0 language=eng -metadata:s:a:0 language=cze -metadata:s:a:1 language=eng video.cz+en.mkv

Pokud načítáte titulky z externího souboru, FFMPEG předpokládá, že jsou uloženy v UTF-8 (UNICODE). Pokud ale máte české SRT titulky, je velká pravděpodobnost, že budou uloženy s kódovou stránkou Windows 1250. V tom případě po připojení dojde k tomu, že se titulky špatně zobrazí – FFMPEG totiž vždy ukládá video s nastavením titulků na UTF-8.

Pro určení, jakou kódovou stránku mají titulky, je potřeba před jejich připojením uvést parametr -sub_charenc se jménem stránky (pro české můžete použít cp1250 nebo Windows-1250). Navíc je potřeba (podobně jako u videa a zvuku) uvést kodek, který má titulky uložit (obvykle srt). Pokud totiž necháte jen -c:copy, FFMPEG nevezme kódovou stránku v úvahu a jen titulky do videa přiloží:

> ffmpeg -i video.mkv -sub_charenc cp1250 -i video.czech.srt 
-c:copy -c:s srt -metadata:s:s:0 language=cze output.mkv

Tento příkaz vezme soubor video.mkv a připojí k němu české titulky, přičemž je převede z Windows 1250 do UTF-8.

FFMPEG můžete dokonce použít i jen k převodu kódové stránky titulků bez jejich připojení do videa:

> ffmpeg -sub_charenc cp1250 -i czech.1250.srt -c:s srt czech.utf8.srt

Nastavení popisu stopy

Stejně jako nastavujete jazyk přes metadata, můžete stopě určit i popisek, který může specifikovat např. odkud zvuk pochází, v jaké je kvalitě, apod.:

> ffmpeg -i video.en.mkv -i czech.ac3 -c copy -map 0:v -map 1:a -map 0:a -metadata:s:v:0 language=eng -metadata:s:v:0 title="BluRay 1080p" -metadata:s:a:0 language=cze -metadata:s:a:0 title="DVB-T2 AC3 2.0 448kbps" -metadata:s:a:1 language=eng -metadata:s:a:1 title="BluRay DTS 7.1" video.cz+en.mkv

Pomocí parametru -metadata title="" můžete nastavit obecný popis videa s názvem filmu nebo podobnou informací pro případ, že soubor (nevhodně) přejmenujete:

> ffmpeg -i big_buck_bunny_1080p_h264.mov -c copy -metadata title="Big Buck Bunny" video_01.mkv

Nastavení typu stopy

Když přidáte více stop stejného typu, můžete určit, kterou stopu bude přehrávač přehrávat, pokud nedostané jiné instrukce (např. některé přehrávače mohou automaticky vybrat zvuk ve vašem rodném jazyce, pokud ho nastavíte).

Typ stopy se určuje parametrem -disposition:a:1 následovaný klíčovým slovem určující typ. Pro určení výchozí stopy použijte default a pro označení ostatních stop (tedy ne výchozí) použijte 0 (číslo nula).

Pro označení tzv. forced titulků (česky vynucené), které obsahují překlady textů ve videu použijte klíčové slovo forced. Pro titulky nebo zvuk obsahující popis nápisů nebo bližší popis můžete použít captions nebo descriptions.

Pro označení zvuku pro slepé (s komentáři) můžete použít visual_impaired a naopak pro titulky pro hluché hearing_impaired. Zvuk obsahující komentáře režiséra nebo herců označte slovem comment.

Pro zvuk obsahující hudbu bez zpěvu je určeno klíčové slovo karaoke a pro text písní pak lyrics.

> ffmpeg -i video.en.mkv -i czech.ac3 -i czech.ass -i czech.forced.ass -c copy -map 0:v -map 1:a -map 0:a -map:2 -map:3 -disposition:v:0 default -disposition:a:0 default -disposition:a:1 0 -disposition:s:0 0 -disposition:s:1 forced video.cz+en.mkv

Tento příklad nastaví video a český zvuk jako výchozí a naopak u anglického zvuk (a českých titulků) příznak výchozí vymaže. Poslední titulky pak označí jako vynucené.

Přidání obrázku videa

MKV soubor může kromě videa obsahovat i obrázek, který se zobrazí jako náhled na podporovaných zařízeních (např. DLNA nebo Miniatury ve Windows).

Obrázek přidejte jako video a pomocí parametru -disposition ho pak označte jako attached_pic:

> ffmpeg -i video.mkv -i thumbnail.jpg -c copy -c:v:1 mjpeg -map 0:v -map 1:v -map 0:a -disposition:v:0 default -disposition:v:1 attached_pic video-out.mkv

Obrázek by měl být ve standardním formátu JPEG, aby byl kompatibilní s co nejvetším množstvím zařízení (DLNA, TV, atd.). Jelikož ale FFMPEG nemá kodek pro uložení JPEG obrázku, je potřeba pro danou stopu specifikovat kodek mjpeg (Motion JPEG), který ukládá video jako sekvenci JPEG obrázků a tudíž pro jeden obrázek uloží jen tenhle daný obrázek.

Obrázek s náhledem je doporučeno vložit jako druhou video stopu, aby přehrávače, které nepochopí nastavení MKV souboru správně (které video je výchozí a které jen obrázek) přehráli první stopu (což je původní video) místo aby jen zobrazovali přiložený obrázek.

V případě MKA souboru, který obsahuje jen zvuk, můžete attached_pic použít jako obrázek, který se zobrazí při přehrávání zvuku.

Více grafických karet

Pokud chcete použít nVidia kodeky, ale máte počítač nebo notebook s více různými grafickými kartami (např. v CPU, na MB, PCI-E), budete potřebovat určit, která karta má video zpracovat – tedy ta nejvýkonnější. Ve výchozím nastavení použije FFMPEG první grafickou kartu, což obvykle bývá ta nejméně výkonná.

Pro změnu použijte parametr -gpu, za který zadáte číslo karty (první karta má číslo 0, druhá číslo 1, atd.). Pro použití druhé, výkonnější karty tedy použijte:

> ffmpeg -i input.mkv -c:v nvenc_hevc -gpu 1 output.mkv

Pokud máte v počítačí více stejných karet (SLI), můžete je použít k souběžnému zpracování více videí:

> ffmpeg -i input-01.mkv -c:v nvenc_hevc -gpu 0 output-01.mkv
> ffmpeg -i input-02.mkv -c:v nvenc_hevc -gpu 1 output-02.mkv

Příkazy budete muset zadat ze dvou různých konzolí, aby FFMPEG mohl spustit dva procesy najednou. Také pamatujte na to, že při převodu více videí ze stejného disku nebo na stejný disk může převod zdržovat rychlost disku. Může být tedy vhodné načítat první video z disku C: a druhé z disku D: a následně je ukládat na disky E: a F: (nebo jakkoliv jinak podle možností vašeho PC).

Kopírování ID3 a Cover Art

FFMPEG se hodí i na práci s hudebnímy soubory jako jsou FLAC, MP3 a M4A. Tyto soubory často obsahují informace o skladbě (ID3) a obrázek alba (cover art). FFMPEG dokáže s těmito daty pracovat a pokud používáte pouze FFMPEG pro konverzi souborů, není potřeba nijak ošetřovat jejich zachování.

Kopírování do jiného souboru

Pokud ale pro konverzi audio souborů používáte jiný nástroj (což doporučuji, např. lame.exe pro MP3, NeroAacEnc.exe pro M4A, flac.exe pro Flac, apod.), které s ID3 a Cover Art neumí pracovat, můžete následně použít FFMPEG pro jejich zkopírování do nového souboru.

Poznámka: obvyklý postup je vstupní soubor pomocí FFMPEG převést na WAV (bez udání kodeku a bitrate, protože WAV má pevný datový tok podle počtu kanálů) a ten pak poslat do externího nástroje:

//Příklad: převede Dolby Digital (AC3 v MKV) do FLAC, MP3 a AAC
> ffmpeg -i input.mkv -map 0:a tmp.wav
> flac --best -o output.flac tmp.wav
> lame -V0 tmp.wav output.mp3
> neroaacenc -q 100 -if tmp.wav -of output.m4a
> del tmp.wav

Ke zkopírování ID3 a obalu je důležité si uvědomit, že ID3 zpracovává FFMPEG jako metadata (podobně jako jména a jazyky stop u MKV) a Cover Art považuje za video stopu. Stačí tedy použít parametry -map a -map_metadata pro jejich zkopírování:

> ffmpeg -i original.mp3 -i new.m4a -c copy
                         -map 0:v -map 1:a -map_metadata 0 new.meta.m4a

Ještě jednou pro objasnění: jako vstupní soubor použijeme ten, který obsahuje ID3 a Cover Art (zde MP3) a jako druhý nový soubor bez nich (zde M4A vytvoření NeroAacEnc). Následně použijeme -map 0:v pro zkopírování Cover Art z prvního souboru a -map_metadata 0 pro zkopírování ID3. Z druhého souboru pak zkopírujeme hudební stopu -map 1:a. Samozřejmě nesmíme zapomenou uvést -c copy, aby FFMPEG nic nepřekódovával a jen data kopíroval.

Uložení Cover Art do folder.jpg

Obrázek alba můžete z hudebního souboru uložit do samostatného souboru. Pokud ho navíc pojmenujete folder.jpg, budou ho moci některé programy (např. Průzkumník Windows) použít jako obrázek složky nebo alba v seznamu alb:

>  ffmpeg -i file.mp3 -q:v 16 folder.jpg 

Při ukládání souboru FFMPEG automaticky podle přípony .jpg pozná, že má zpracovat obrázek ze souboru a uložit ho jako JPEG. Pomocí -q:v můžete zadat kvalitu obrázku. FFMPEG ale nepoužívá klasickou JPEG kompresy (0% – 100%) ale hodnoty 132, kde 1 je maximální kvalita a 32 znamená největší kompresy (tedy nejhorší kvalitu). Hodnota mezi 10 a 20 je nejlepší pro obrázek složky.

Uložení metadat do textového souboru

FFMPEG umí ID3 uložit do textového souboru (ve formátu INI), který pak můžete použít v jiných programech nebo ho později použít jako vstupní soubor pro FFMPEG:

> ffmpeg -i input.mp3 -f ffmetadata output.txt
> ffmpeg -i input.m4a -i output.txt -map_metadata 1 -c:a copy 
                      -id3v2_version 3 -write_id3v1 1 output.m4a

Všimněte si, že při načítání ID3 z textového meta souboru používáme -c:a copy, aby se zkopírovala jen audiostopa a pro zápis ID3 používáme -map_metadata 1 doplněné o parametry -write_id3v1 (starý formát ID3 uložený na začátku souboru) a -id3v2_version 3 (nový formát ID3 uložený na konci souboru). Pomocí těchto parametrů řekneme programu, že druhý soubor (txt) má použít pro načtení metadat a vytáhnout z něj data potřebná pro zápis ID3 tagů.

Odstranění ID3 a Cover Art

Pokud chcete naopak ze souboru odstranit ID3 a/nebo Cover Art, použijte následující příkazy:

>  ffmpeg -i file.mp3 -c copy -map_metadata -1 new.mp3
>  ffmpeg -i file.mp3 -c copy -map 0 -map -0:v new.mp3 
>  ffmpeg -i file.mp3 -c copy -map 0 -map -0:v -map_metadata -1 new.mp3 

Parametrem -map_metadata -1 určíte, že metadata se mají zkopírovat z mínus prvního souboru, který neexistuje a proto se nic nezkopíruje. Parametry -map 0 -map -0:v určují, že se má zkopírovat vše kromě video stop, což v tomto případě znamená vynechat obrázek alba.

Pozor na to, že FFMPEG nedokáže upravovat vstupní soubory a proto je vždy nutné uložit hudební stopu bez metadat do nového souboru!

Video Filtry

Filtry se uvádějí do parametru -vf (video filter), kde následně uvedete jméno filtru a za rovnítko jeho parametry:

> ffmpeg -i input.mkv -vf "filtr=parametry" output.mkv

Parametry je lepší uvést do uvozovek, aby se správně zpracovaly. Pokud chcete použít více filtrů, můžete je oddělit čárkou. Parametry jednotlivých filtrů je pak většinou oddělují dvojtečkou:

> ffmpeg -i input.mkv -vf "filtr=1:2:x=3,filtr=parametr" output.mkv

Některé kombinace filtrů nemusí být v parametru -vf podporovány. Stejně tak nemusí být možné použít parametr -vf, pokud máte několik vstupních souborů nebo více výstupních streamů. V takovém případě ale můžete obdobně použít -filter_complex, kde navíc zadáte před každou sérii filtrů číslo, na které vstupní video se má aplikovat a středníkem oddělíte filtry pro výstupní soubory (a také můžete používat odřádkování pro lepší čitelnost):

> ffmpeg -i 1.mkv -i 2.mkv -filter_complex "
    [0]filter1=parametr, filter2=parameter;
    [0:v][1:v]filter3=parametr
  " out.mkv

Tento (zjednodušený) příkaz použije filter1 a filter2 na soubor 1.mkv a současně použije filter3 na videa 1.mkv a 2.mkv a uloží je jako tři samostatné video streamy do out.mkv společně se zvukem z 1.mkv.

Pokud chcete filtry řetězit v trochu složitějším postupu, můžete výstup filtru pojmenovat a následně použít jako vstup dalšího filtru:

 > ffmpeg -i 1.mkv -i 2.mkv -filter_complex "
    [0]                  filter1=parametr  [0-filtered];
    [0-filtered]         filter2=x=1:y=2   [0-final];
    [0-filtered:v][1:v]  filter3=parametr  [0+1-final]
  " out.mkv 

Důležité je si uvědomit, že filtry je možno použít jen při překódování; pokud byste zadali jen -c copy, buď se filtr nepoužije nebo se přímo vypíše chyba, že je nutno zvolit kodek. Musíte tedy zadat kodek alespoň pro video a ostatní můžete zkopírovat; nebo alternativně neuvést kodek žádný a použít ten výchozí. Filtry mohou být i pro zvuk, ale tato kapitola se zabývá video filtry. Pro zjednodušení a přehlednost ale nebudu kodeky v příkladech uvádět!

Poznámka: některé z dále uvedených filtrů jsem zatím přímo nepoužil a jsou uvedeny pouze pro přehled. Některé jejich funkce nebo parametry tedy nemusí být 100% přesně popsány.

Pro určení barvy tam, kde je to potřeba, se podívejte na seznam podporovaných barev. RGB se zadává ve formátu 0xFFFFFF.

Obrázky z videa

Toto není přímo video filtr, ale schopnost FFMPEG ukládat video jako PNG obrázky. V kombinaci s video filtrem, který umožňuje měnit počet snímků za sekundu (fps), si můžete nechat udělat obrázky z videa např. každých 10 sekund.

To se hodí v případě, že nevíte, jakou kvalitu nastavit pro dané video. V takovém případě zkuste část videa (viz stříhání výše) uložit v různých kvalitách a následně si z ukázek nechte udělat obrázky. Jejich vizuálním porovnáním (nebo programově pomocí DiffImg) pak snadno určíte, při jaké kvalitě je obraz bez chyb.

//Linux a MacOS
> ffmpeg -i input.mkv -vf fps=1 output-%d.png

//Windows
> ffmpeg -i input.mkv -vf fps=1 output-%%d.png

V příkazu nastavujeme filtr fps na hodnotu 1, což znamená, že každou sekundu uloží jeden snímek. Pokud chcete snímek každou minutu, použijte 1/60 (jeden snímek za 60 sekund), pro snímek po 10 minutách pak 1/600, apod. Naopak pokud chcete uložit např. 5 snímků z každé sekundy, použijte hodnotu 5 (tedy 5 snímků za sekundu).

Dále se liší nastavení výstupu, kde určíme, že se mají ukládat obrázky PNG, což FFMPEG správně pochopí a bude dělat obrázky z videa – není tedy již potřeba uvádět parametr -c:v pro určení výstupního kodeku.

Na závěr, abysme nemuseli uvádět jméno pro každý snímek, použijeme proměnnou %d, která do jména souboru vloží číslo snímku. Všimněte si, že na Windows musíte znak procent uvést dvakrát, protože jeden znak procent je rezervován pro použití parametrů z příkazové řádky.

Změna rozlišení

Pro změnu rozlišení můžete použít softwarový filtr scale nebo hardwarové filtry (viz dále). Má dva parametry, které uvádí šířku a výšku videa:

> ffmpeg -i input.mkv -vf "scale=1920:1080" output.mkv

Pokud chcete zachovat poměr stran ze vstupního videa (např. 4:3 nebo 16:9), můžete místo šířky nebo výšky uvést záporné číslo, které udává násobek, na který se rozměr zaokrouhlý. Uvedením -1 použijete libovolný rozměr, pro -2 bude rozměr dělitelný 2, pro -8 bude rozměr dělitelný 8 apod. Některé kodeky vyžadují sudý rozměr, vyšší dělitelnost pak může pomoci některým kodekům (založeným na JPEG kvantizaci; tedy MPEG a H.26x) lépe zkomprimovat jednotlivé snímky).

Zde si dovolím malou vsuvku: hodnoty 480i, 480p, 720p, 1080i a 1080p neudávají šířku, jak se někteří lidé domnívají (protože staré televize měli rozlišení 720×576, což se plete se 720p), ale udávají „počet řádek“, tedy výšku obrazu (u TV to tedy bylo 480i NTSC resp. 576i PAL). Tudíž video 720×400, které často najdete na internetu není 720p, ale pouze 480p (a to ještě s odřenýma ušima). Abyste dosáhli 720p, musíte použít rozlišení 960×720 (4:3) nebo 1280×720. Stejně tak 1080p je rozlišení 1440×1080 (4:3) nebo 1920×1080 (pro 16:9), ale může být i 1920×800 pro kino formát (resp. IMAX). Písmeno „i“ označuje prokládaný (interleaved) signál, který se používá pro televizní vysílání (PAL, NTSC, DVB-T), zatímco „p“ označuje plný (progressive) signál používaný pro digitální média (DVD, BluRay, stream, apod.). Prokládaný signál obsahuje pouze polovinu udaných řádek, ale dvojnásobný počet snímků (tedy 1080i@50Hz odpovídá kvalitou 1080p při 25fps).

Pro 720p nezávisle na rozlišení a poměru použijte:

> ffmpeg -i input.mkv -vf "scale=-2:720" output.mkv

Naopak pro 1080p při 16:9, které může obsahovat kino formát:

> ffmpeg -i input.mkv -vf "scale=1920:-2" output.mkv

Downscale (snížení rozlišení)

Výše uvedené parametry pro změnu rozlišení změní video nezávisle na vstupním rozlišení. Pokud tedy použijete výstupní rozlišení 1280×720 pro snížení rozlišení z 1920×1080, ale následně použijete vstupní video s rozlišením 400×240, FFMPEG provede tzv. upscale, čímž zvýší rozlišení videa a tudíž i velikost výsledného souboru (aniž by zvýšil kvalitu).

Tomu můžete zabránit tím, že zakážete upscale a umožníte pouze downscale (tedy snížení rozlišení za účelem úspory místa na disku nebo zrychlení stažení z internetu). Jako parametry filtru můžete použít několik proměnných a funkcí, kterými dosáhnete požadovaného efektu.

Proměnné iw a ih obsahují hodnotu šířky a výšky vstupního videa (tedy pro výše uvedené video iw=400 a ih=240). Také můžete použít funkce min() a max(), které vrátí nejmenší a největší hodnotu. A případně můžete použít i matematické výpočty jako násobení (např. iw*2) nebo dělení (ih/2). Také podporuje závorky.

Pro downscale tedy potřebujete, aby zadaná velikost nepřesáhla vstupní rozlišení:

> ffmpeg -i input.mkv -vf "scale=-2:min(720,ih)" output.mkv

Nebo pro FullHD:

> ffmpeg -i input.mkv -vf "scale=min(1920,iw):-2" output.mkv

Změna rozlišení hardwarovým filtrem

Pokud pro dekódování videa používáte hardwarový dekodér (nvdec nebo cuvid – viz výše), můžete dekódéru poslat příkaz, aby vstupní video rovnou zmenšil (nebo zvětšil, pokud potřebujete). Hardwarový dekodér je mnohem výkonnější (zhruba 3x až 4x) než softwarový filtr scale:

> ffmpeg -c:v hevc_cuvid -resize 1920x1080 -i 4k_input.mkv hd_output.mkv

Otočení (Transpozice)

Pokud jste omylem nebo nějakým nedopatřením natočili video, které je nesprávně otočeno (např. jste v mobilem nebo fotoaparátem natáčeli na výšku, ale zařízení uložilo video na šířku nebo když jste „černou skříňku“ v autě namontovali opačně), můžete použít filtr transpose. Filtr má jeden parametr definující číslo transpozice, která se má použít.

Čísla 1 a 2 znamenají jednoduché otočení doprava a doleva (ve směru a proti směru hodinových ručiček). Pokud je video navíc (po převodu) zrcadlově převrácené, můžete použít hodnoty 3 (doprava) nebo 0 (doleva), které video navíc vodorovně zrcadlově převrátí.

> ffmpeg -i input.mkv -vf "transpose=1" output.mkv

Pokud je video otočené o 180° (vzhůru nohama), zadejte filtr dvakrát:

> ffmpeg -i input.mkv -vf "transpose=1,transpose=1" output.mkv

Pokud je video jen převrácené aniž by bylo otočené (tzv. zrcadlový záznam), můžete použít filtry hflip (otočené podél svislé osy) nebo vflip (otočené podél vodorovné osy). Filtry nemají žádné parametry.

Pro otočení o libovolný úhel (např. pokud jste drželi kameru nebo mobil nakřivo a chcete srovnat horizont) slouží filtr rotate, který má parametr určující počet radiánů otočení. Kvůli možnosti libovolného otočení tento filtr vypočítává pozice i pro otočení o 90° nebo 180°, takže je výrazně pomalejší než výše uvedené filtry transpose, hflip a vflip, takže pro pravoúhlá otočení používejte tyto filtry.

Pro otočení ve stupních musíte hodnotu vypočítat s použitím konstanty PI, např. pro 45° doprava:

> ffmpeg -i input.mkv -vf "rotate=45*(PI/180)" output.mkv

V kombinaci s otočením může být potřeba zapnout nebo vypnout vyhlazování. To provedete parametrem bilinear a zadáním 0 nebo 1. Pokud je video po převodu rozmazané, vyhlazování vypněte. Pokud jsou naopak ve videu rovné čáry zlámané nebo čtverečkované, vyhlazování zapněte.

Od května 2015 (a od verze 2.7) obsahuje FFMPEG podporu pro automatické otočení. Některé mobilní telefony nebo jiná zařízení mohou do videa přidat informaci (metadata) o fyzickém otočení zařízení a pokud je tato informace ve videu obsažena, není potřeba žádný filtr používat a stačí jen video překódovat:

> ffmpeg -i input.mkv output.mkv

Pokud je ve videu (chybná) informace o natočení a po překódování se vám video otočí a vy to nechcete, můžete přidat parametr noautorotate:

> ffmpeg -i input.mkv -noautorotate output.mkv

Informace o natočení (pokud je ve video) se zobrazí po výpisu informací o videu:

> ffmpeg -i input.mkv

Input video.mkv
    Stream #0:0 Video
    Metadata:
        Rotate: 180

Letterbox (Černé pruhy)

Černé pruhy (anglicky letterbox) pravděpodobně znáte z kinoformátu (IMAX, BluRay), kdy širokoúhlé filmy mají nahoře a dole pruhy, aby vyplnili celý prostor formátu (např. 1920×800 doplněné o pruhy na 1920×1080).

Použít je ale můžete i obráceně, tedy v případě, že máte staré video 4:3, ale chcete ho zobrazit na nové televizi (přes USB nebo DLNA), která ale již neumí zobrazit 4:3 a vždy video roztáhne na 16:9. Přidáním černých pruhů doleva a doprava můžete televizi donutit zobrazit správný poměr stran (tedy 4:3 ukrytý uvnitř 16:9 videa).

Pro doplnění pruhů můžete použít filtr pad (vycpávka), který má 4 parametry. První dva určují požadované rozlišení a další dva umístění vstupního videa zleva a zhora. Pro výpočet pozice můžete použít proměnné iw a ih (vstupní rozlišení) a ow a oh (výstupní rozlišení, tedy první dva parametry filtru pad).

Příklad pro převod na HD s doplněním černých pruhů:

> ffmpeg -i input.mkv -vf "pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mkv

Příklad pro převod 4:3 na 16:9 při zachování stejného rozlišení:

> ffmpeg -i input.mkv -vf "pad=ih/9*16:ih:(ow-iw)/2" output.mkv

Oříznutí

Pokud chcete video naopak oříznou a zbavit se černých pruhů nebo chyb na okrajích analogového záznamu, použijte filtr crop. Ten má čtyři parametry podobné filtru pad. Tedy šířku a výšku výsledného videa a odsazení zleva a zhora.

Pokud má video 1920×800 uvnitř 1920×1080, musíte oříznout 140px zhora (a zdola, což se automaticky spočte z výšky videa):

> ffmpeg -i video.mkv -vf "crop=1920:800:0:140" video.cropped.mkv

Pokud chcete z videa vyříznou středovou část, nemusíte vůbec zadávat třetí a čtvrtý parametr:

> ffmpeg -i video.mkv -vf "crop=1920:800" video.center-cropped.mkv

Pro vyříznutí 720p při zachování poměru stran uveďte:

> ffmpeg -i video.mkv -vf "crop=h=720:keep_aspect=1" video.cropped.mkv

Pro zjistění, jak video oříznout, abyste ho zbavili černých pruhů můžete použít filtr cropdetect:

> ffmpeg -i video.mkv -vf "cropdetect=limit=24:round=8:reset=1500"

Parametr limit určuje podobnost černé barvy (0 = černá, 255 = bílá), pomocí round se rozměr automaticky zaokrouhlí pro lepší zpracování videa a reset určuje, kolik snímků po sobě (1500 je 1 minuta při 25fps) může překročit nalezené oříznutí u zbytku videa, aby se stále ořízlo (např. když je na začátku logo bez černých pruhů nebo reklamy uprostřed filmu).

Oříznutí hardwarovým filtrem

Pokud pro dekódování videa používáte hardwarový dekodér (nvdec nebo cuvid – viz výše), může dekodér video rovnou oříznout:

> ffmpeg -c:v hevc_cuvid -crop 140x140x0x0 -i HD_input.mkv movie_output.mkv
> ffmpeg -c:v hevc_cuvid -crop 0x0x240x240 -i HD_input.mkv 4x3_output.mkv

Pozor na to, že HW crop má parametry obráceně a jako první se uvádí vertikální oříznutí (horní y a dolní y) a pak teprve horizontální (levé x a pravé x). To je proto, že častěji se ořezávají horní a dolní okraje a zápis 140x140x0x0 je čitelnější než 0x0x140x140. Na rozdíl od scale ale není možné použít jen 140x140 a vždy je potřeba uvést všechny 4 hodnoty!

Pokud chcete použít současně crop a resize, pamatujte, že crop se provádí jako první (na původním videu) a teprve výsledek se převede na cílové rozlišení.

Vynucení poměru stran

Někdy můžete narazit na video, které má špatně nastavený poměr stran, např, 4:3 video uložené jako 16:9 nebo obráceně. Pro opravu nemusíte používat filtr scale a zadávat konkrétní rozlišení, ale stačí použít filtr setdar (Display aspect ratio), který má dva parametry udávající poměr stran výstupního videa:

> ffmpeg -i input.mkv -vf "setdar=16/9" output.mkv

Někdy můžete naopak potřebovat vytvořit video, které je uloženo s jiným poměrem stran, než v jakém bude zobrazeno. Např. některé televize (DVB-T) vysílají v rozlišení 1440×1080 (4:3) i širokoúhlé filmy (16:9) a pouze udávají změnu rozlišení. K tomu slouží filtr setsar (Source aspect ratio resp. Sample aspect ratio):

> ffmpeg -i input.mkv -vf "setsar=4/3" output.mkv

Pro správné zobrazení pak musíte uvést oba parametry, aby se video správné uložilo a následně i zobrazilo:

> ffmpeg -i input.mkv -vf "setsar=4/3,setdar=16/9" output.mkv

Pokud chcete vynutit zachování poměru stran vstupního video, můžete použít filtr setsar=1:1 nebo zkráceně setsar=1. Toto je užitečné v kombinaci s filtrem pad, kdy nemusíte uvádět 4. parametr a video se správně roztáhne:

... -vf "scale=1920:1080,setsar=1:1,pad=1920:1080:(ow-iw)/2" ...

Pokud používáte hardwarové dekódování a enkódování, je efektivnější použít hardwarový resize než používat softwarový setsar filtr (použití parametru resize automaticky vypočte SAR podle daných hodnot). Pokud chcete použít jen setdar, který pouze ukládá metadata, je ho možné použít i při hardwarovém zpracování (bez nutnosti dalšího převodu).

Deinterlace

Pokud máte záznam uložený v interlaced formátu (např. z televize nebo DVD), budete potřebovat použít filtr deinterlace, aby se z videa odstranilo nechtěné řádkování.

Interlaced video (česky Prokládané) může být označeno písmenem „i“ za počtem řádek; např. 480i, 720i, 1080i, apod. Pokud tak označeno není a po běžném převodu se ostré svislé hrany jeví zubatě při pohybu do stran (např. pohyb vozidla nebo osoby ze strany na stranu), jde o interlaced video. Nejlépe takové video poznáte, pokud ho otevřete v programu MediaInfo a najdete řádky Scan (česky typ skenování):

Scan type : Interlaced
Scan order : Top Field First

Pokud tyto řádky v MediaInfo nenajdete, nejde o prokládané video ale o progresivní (např. 1080p), kde jsou uložené celé snímky nebo již bylo deinterlacováno.

Pokud máte prokládané video a chcete ho pomocí FFMPEG převést, uveďte filter -vf yadif (což je zkratka „yet another deinterlace filter„, což by se dalo přeložit jako „prostě filtr pro deinterlace“):

> ffmpeg -i input.mkv -vf yadif output.mkv

Deinterlacing hardwarovým filtrem

Po použití hardwarového dekodéru (nvdec nebo cuvid – viz výše) není potřeba převádět video do CPU pro interlacing (viz filtr yadif). Dekódér umí video převést sám pomocí filtru yadif_cuda:

> ffmpeg -c:v hevc_cuvid -i input_50i.mkv -vf "yadif_cuda=0:-1:1" output_50p.mkv

Pozor na to, že filtr funguje tam, kde je uveden – tedy až pro uložení videa do paměti GPU. Není tedy možné kombinovat yadif_cuda s předchozím hardwarovým crop nebo resize, protože použím crop nebo resize by se video již převedlo do progresivního a tudíž by yadif filtr nezafungoval správně.

Hard-code titulky

Pokud chcete titulky přidat přímo do videa, aby šli přehrát i na TV, která titulky nepodporuje, můžete použít filtr subtitles:

> ffmpeg -i video.mkv -vf "subtitles=video.srt" video.sub.mkv

Pro přidání titulků, které jsou již obsaženy ve videu:

> ffmpeg -i video.mkv -vf "subtitles=video.mkv" video.sub.mkv

Zpravidla ale potřebujete přidat tzv. forced titulky, které bývají až jako druhé (použijete tedy parametr stream-index začínající nulou):

> ffmpeg -i video.mkv -vf "subtitles=video.mkv:si=1" video.sub.mkv

Pokud máte titulky v modernějším formátu ASS, můžete místo toho použít filtr, který s nimi umí lépe pracovat (např. vykreslit animace):

> ffmpeg -i video.mkv -vf "ass=video.ass" video.ass.mkv

Pokud jsou titulky špatně umístěné, roztažené nebo příliš malé či velké, můžete přidat parametr original_size=1920x1080. Pokud jsou písma použitá v titulcích uložena přímo ve složce s filmem, použijte fontsdir=c:\...\ nebo fontsdir=/usr/.../. Pro české titulky můžete potřebovat parametr charenc=CP1250 (výchozí kódování je UTF-8). Pro změnu stylu písma pak slouží parametr force_style='FontName=Arial Bold,FontSize=24,PrimaryColor=&HFFFFFF&'.

Pro jednoduchý text ve videu můžete použít filtr drawtext, který vloží do videa text určený parametrem text nebo textfile, pokud chcete načíst text z textového souboru. Text musí být v UTF-8. Kam a jak text vypsat určují parametry x, y, fontfile, fontcolor a fontsize. Kdy se má text zobrazit můžete určit parametry timecode (ve formátu hh:mm:ss.ff) a timecode_rate (fps pro vypočtení snímku z timecode, např. r=25 pro 25fps). Do timecode můžete uvést dva časy pro začátek a konec. Pro streamy můžete použít parametr tc24hmax=1, který způsobí, že se text bude opakovat každých 24 hodin (např. timecode=8:00:00.00 zobrazí text každý den v 8 ráno). Kromě obvyklých proměnných můžete použít text_w a text_h určující velikost textu, line_h určující výšku jedné řádky a max_glyph_w určující šířku jednoho písmene.

Poznámka: na Windows je trochu problém s uvedením cesty k písmu, protože dvojtečka ani lomítko se nemůže v cestě vyskytovat a ffmpeg.exe bohužel nerozumí Linuxovému zápisu. Všechny tyto znaky je potřeba escapovat a pro jistotu ještě uvést do apostrofů: fontfile='c\:\\Windows\\Fonts\\arialbd.ttf'. Pokud ffmpeg voláte z programu, ještě zdvojte každé lomítko (např. c:\\:\\\\Windows...)

Aktuální čas můžete do videa vložit parametrem:

text=%{localtime\:%a %b %d %Y}

Černo

Filtr blackdetect můžete použít pro nalezení scén, které jsou černé nebo téměř černé. To může být užitečné pro hledání chyb nahrávání (např. z DVB-T) nebo nalezení míst, na kterých není nic vidět (např. když jste nahrávali v temné místnosti, jeskyni apod.).

> ... -vf "blackdetect=d=0.2:pix_th=0.8

Tyto parametry určují, že za černo je považována scéna, která trvá alespoň 0,2 sekundy (tedy 5 snímků při 25fps) a obsahuje pouze barvy, která mají max. 20% osvícení (luminiscence) – tedy temné odstíny šedivé (hodnota 1.0 znamená nulové osvícení, výchozí je 0.98).

Pro jednotlivé černé snímky (oddělující kapitoly nebo reklamy) slouží filtr blackframe, který má parametry amount=98 (procento pixelů, které musí být černé) a threshold=32 (odstíny šedé).

Video kodek na MacOS

Stejně jako můžete použít nVidia kartu pro převod videa, můžete na MacOS použít filtr, který video zpracuje pomocí vestavěné grafické karty:

> ffmpeg -vf "coreimage=list_filters=true"
> ffmpeg -i input.mkv -vf "coreimage=filter=..." output.mkv

Odstranění loga

Pokud máte video nahrané z TV, je v něm logo stanice. To můžete odstranit filtrem delogo, které má 4 parametry stejné jako filtr crop. Na rozdíl od crop ale označenou oblast rozmaže (blur), takže logo zdánlivě zmizí. Stejně ho ale můžete použít např. pro nahrávku z kamery v autě, abyste odstranili rychlost a GPS pozici zakódovanou do videa.

> ... -vf "delogo=300:200:10:10" ...

Pro rozmazání se berou v úvahu jen pixely na okraji označené oblasti. Pokud tedy chcete odstranit text s pozadím, musí označení být vně pozadí. Pokud ho naopak umístíte dovnitř, pozadí zůstane a rozmaže se jen text uvnitř.

Tento filtr také může fungovat i jako cenzura pro rozmazání citlivých oblastí videa, například nahoty (známé jako mozaika).

Vložení loga

Pokud chcete do videa naopak vložit vlastní logo, použijte k tomu filtr overlay. Logo si připravte ve formátu PNG s průhledností podle potřeby. Následně ho přiložte jako vstupní soubor:

 > ffmpeg -i video.mkv -i logo.png ...

Nyní již stačí přidat filtr overlay a pomocí parametrů x a y určit souřadnice, kam se logo vloží. Použít můžete proměnné W a H jako šířku a výšku videa a w a h jako šířku a výšku loga. Také můžete použít x a y coby pozici loga, n jako číslo snímku nebo t pro počet sekund od začátku – tyhle hodnoty se dají použít k tomu, že se může logo po obraze pohybovat, čímž zamezíte tomu, aby ho někdo filtrem delogo opět odstranil.

Pokud nepotřebujete logem po obraze pohybovat, přidejte parametr eval=init, čímž převod trochu urychlíte, protože se nebude pozice loga přepočítávat pro každý snímek.

> ... -vf "overlay=x=W-w:y=H-h"     ; vložení do pravého dolního rohu
> ... -vf "overlay=W-w:H-h"         ; totéž ve zkráceném zápisu
> ... -vf "overlay=-w+t*20:0        ; logo jezdící u horního okraje

Pokud místo PNG chcete vložit animované logo z videa, ještě můžete přidat další parametry eof_action=repeat (bude logo opakovat dokud neskončí primární video) nebo repeatlast=1 (poslední snímek loga bude viditelný až do konce primárního videa). Také se může hodit alpha=straight nebo alpha=premultiplied pro vytvoření průhlednosti z černé barvy v logu. Alternativně můžete použít filtry despill a chromakey (viz níže).

Filtr overlay můžete použít i vícekrát, stačí vložit více vstupních PNG nebo video souborů a následně přidat několik filtrů overlay oddělených čárkou. Dejte ale pozor na to, že výpočet průhlednosti výrazně zpomaluje převod a pokud potřebujete real-time výstup, může to omezit kvalitu streamu!

Vytvoření 3D videa

Předchozí filtr overlay lze také použít k vytvoření 3D (stereoskopického) videa tím, že dva vstupní soubory (levý a pravý) překreslíte přes sebe do levé a pravé nebo horní a dolní části.

> ffmpeg -i left.avi -i right.avi -filter_complex "
   nullsrc=size=1920x1080 [background]; 
   [0:v] setpts=PTS-STARTPTS, scale=960x1080 [left];
   [1:v] setpts=PTS-STARTPTS, scale=960x1080 [right]; 
   [background][left]       overlay=shortest=1       [background+left];
   [background+left][right] overlay=shortest=1:x=960 [left+right]"

Tento příkaz vyvoří tzv. half-Side-by-Side video tak, že vytvoří prázdný vstupní snímek (nullsrc) o velikosti 1920×1080 a pojmenuje ho background (pozadí). Následně vstupní soubory sesynchronizuje, aby se spustili současně (setpts), změní jejich šířku na polovinu (960×1080). Nakonec je pomocí dvou overlay filtrů vykreslí na požadované pozice. Pomocí parametru shortest=1 určí, že výstup končí v okamžiku skončení kratšího z obou videí (to jen pro jistotu, aby nevznikl snímek jen s jedním stereoskopickým vstupem).

Stejný postup můžete použít například v případě, že máte 4 kamery snímající stejnou scénu (nebo různá místa ve stejném čase) a chcete vytvořit video přehrávající všechny 4 záznamy najednou.

Stabilizátor

Pro video nahrané kamerou nebo telefonem bez stabilizátoru obrazu použijte filtr deshake.

Parametry x, y, w a h označují oblast, která se vzhledem ke kameře nehýbala (např. při záznamu z auta označte oblast karoserie, která by měla být statická). Pokud parametry neuvedete, použije se celý snímek.

Parametry rx a ry určují maximální pohyb pixelů (0-64), které se ještě považují za otřesy. Např. pokud jste zabírali panorama nebo pohled z boku auta, můžete regulovat otřesy v ose y (svislé) a ignorovat vodorovné: rx=0:ry=64.

Parametr edge určuje, čím se má vyplnit oblast, která se kvůli pohybu nenahrála (0 = černá barva, 1 = původní záznam, 2 a 3 pak různé další efekty).

Odstranění pozadí

Při natáčení proti modrému nebo zelenému pozadí ho můžete odstranit filtrem despill. Parametry type, mix a expand určují, jakým způsobem se pozadí odstraní. Parametry red, green, blue, brithness a alpha pak určují, jakou barvu pozadí mělo a jaké barvy se tedy mají odstranit.

Obdobně funguje i filtr chromakey, který jednoduše zprůhlední určenou barvu, např. -vf chromakey=green zprůhlední zelené pixely.

Označení místa (vložení barevného obdélníku)

Do videa můžete přidat barevný obdélník, abyste označili nějaké zajímavé místo, filtrem drawbox. Parametry x, y, w a h určují, jak se má obdélník nakreslit (viz filtr crop) a parametry c (color) a t (thickness) určují barvu a šířku čáry.

Pro barvu můžete použít slovo invert, které použije opačnou barvu k té, která je ve videu. Barvu též můžete označit slovem (např. red, black, pink, atd.) a průhlednost můžete určit zavináčem (např. c=red@0.5 bude 50% průhledná červená).

Pro thickness můžete použít slovo fill, kterým vyplníte celou zadanou oblast (a může tedy fungovat jako cenzura dané oblasti, tzv. censor bar).

V hodnotách parametrů x, y, w, h a t můžete použít stejnojmenné proměnné (např. h=w nakreslí čtverec) a také proměnné iw a ih (vstupní velikost videa) a sar a dar (poměr stran vstupu a výstupu).

Parametry filtru drawbox lze také uvést za parametrem -i a pak se bude obdélník považovat za vstupní soubor a lze ho tak kombinovat s některými filtry (např. overlay).

Zaostření a rozostření

Video můžete zaostřit nebo rozostřit pomocí filtru unsharp (rozostři), přičemž (nelogicky) kladné hodnoty video zaostřují a záporné rozostřují.

Video můžete roz-/zaostřit buď ve složce luma (světlost neboli černo-bílá složka), ve složce chroma (barvy) nebo v obou.

Parametry můžete zadat podle jména nebo ve tvaru:

-vf unsharp=lx:ly:la:cx:cy:ca

Kde lx, ly, cx a cy určuje velikost zaostření nebo rozostření ve vodorovném a svislém směru pro složky luma a chroma (rozsah 3px až 23px). Hodnoty la a ca určuje sílu zaostření (hodnoty větší než 0) nebo rozostření (záporné hodnoty). Výchozí hodnota pro la je 1 a pro ca 0, takže pro zaostření pouze ve složce luma můžet použít unsharp=3:3 zatímco pro rozostření složky luma použijte unsharp=3:3:-1.

Příklady:

//silnější zaostření luma
-vf unsharp=3:3:2.5
//rozostření luma i chroma
-vf unsharp=3:3:-1:3:3:-1
//zaostření chroma
-vf unsharp=cx=3:cy=3:ca=1

Kontrast, světlost a saturace

Video můžete upravit pomocí filtru eq (equalize). Podporované parametry jsou:

  • contrast – hodnoty 1 až 1000 zvyšují rozdíl mezi světlými a tmavými odstíny; -1 až -1000 snižují rozdíl. Výchozí hodnota je 1, která zachová původní kontrast. Filtr je na tuto hodnotu hodně citlivý, takže pro mírné zvýšení kontrastu běžného videa vám obvykle stačí hodnoty 1.11.2.
  • brightness – mění světlost v rozsahu -1.0 až 1.0. Výchozí hodnota je 0, která světlost nemění.
  • saturation – mění saturaci (sílu barev). Hodnoty 1.1 až 3.0 zvyšují barevnost videa, hodnoty 0.1 až 0.9 snižují barevnost. Hodnota 1 barevnost nemění, hodnota 0 vytvoří z videa černo-bílé video tím, že odstraní všechny barvy.
  • gamma, gamma_r, gamma_g, gamma_b – mění síli gamma kanálu červené, zelené, modré nebo všech. Hodnoty jsou 0.1 až 10, výchozí je 1.
  • gamma_weight redukuje sílu gamma kanálu. Hodnoty 0.0 až 0.99 snižuje sílu gamma, zatímco 1.0 hodnotu nemění.

Parametry můžete zadat ve výše uvedeném pořadí; příklady:

//zvýšení kontrastu
eq=1.5
//zvýšení světlosti
eq=1:1
//zvýšení barevnosti (saturace)
eq=1:0:1.5
//vytvoření černo-bílého videa
eq=1:0:0
//vylepšení "zašedlého" videa (mírně zvedne kontrast a barevnost)
eq=1.2:0:1.2

Místo pevně daných hodnot můžete použít matematické výpočty, kde n je číslo snímku ve videu, r je framerate a t je počet sekund od začátku videa. Pro správný výpočet pro každý snímek je potřeba přidat parametr eval=frame.

//postupně zvyšuje kontrast po 1000 snímcích (cca 40 sekund)
eq=n/999+1:eval=frame
//postupně zvyšuje saturaci o 1% každou sekundu
eq=saturation=t/100+1:eval=frame

Pomocný grid

Do videa můžete doplnit svislé a vodorovné čáry, např. pokud chcete odkazovat na konkrétní oblast. Filtr drawgrid má stejné parametry jako drawbox s tím rozdílem, že šířka a výška (w a h) určují vzdálenost svislých a vodorovných čar. Parametry x a y pak určují jeden z bodů, kde se mají svislé a vodorovné čáry protnout.

Převod snímku mezi GPU a CPU

Pokud používáte softwarové dekódování i enkódování, budou všechny procesy probíhat na CPU (procesor) a snímky budou uloženy v RAM. Pokud naopak použijete hardwarové dekódování cuvid a zároveň hardwarové enkódování nvenc/cuda, bude zpracování probíhat v GPU/CUDA (grafická karta) a snímky budou uloženy v její paměti (MEM).

Pokud ale budete chtít kombinovat softwarové (filtry a enkódování) a hardwarové zpracování (dekódování a hardwarové filtry), budete muset použít speciální filtry pro převod snímků mezi pamětí počítače (RAM) a grafické karty (MEM).

Základní pravidlo je: použujte filtry, které potřebujete, a zkuste to. Pokud vám FFMPEG vrátí chybu „Impossible to convert between the formats supported by the filter ‚…‘ and the filter ‚…‘ „, znamená to (obvykle), že je potřeba snímek převést do jiné paměti.

Pro převod snímku z hardwarové paměti (MEM) do softwarové (RAM) použijte filtr hwdownload doplněný o formát videa: pro 8bitové video použijte format=nv12 (odpovídá yuv420p, ale je lepší pro opětovný převod zpět do MEM), zatímco pro 10bitové video format=p010le.

> ffmpeg -hwaccel cuda ... -i input.mkv -vf "hwdownload,format=nv12,yadif" ... output.mkv

Pokud naopak potřebujete převést snímek do hardwarové paměti pro použití hardwarového filtru, použijte hwupload_cuda.

> ffmpeg -i input_50i.mkv -vf "hwupload_cuda,yadif_cuda" ... output.mkv

Trochu problém je v tom, kdy je potřeba snímek převést a kdy to potřeba není; případně, kdy k tomu dojde automaticky:

  • hardwarový kodek nvdec automaticky uloží snímek do MEM nebo RAM podle toho, jaký je následující krok – není tedy potřeba používat hwdownload nebo hwupload_cuda jako první filtr,
  • hardwarový kodek cuvid ukládá snímek vždy do MEM, takže je potřeba použít hwdownload pro použití filtru, který vyžaduje snímek v RAM,
  • hardwarový enkóder nvenc si automaticky přečte snímek z RAM nebo MEM podle toho, kde je uložen – není tedy potřeba používat hwupload_cuda jako poslední filtr,
  • hardwarový enkóder cuda (parametr -hwaccel_output_format cuda) vyžaduje snímek v MEM, takže je potřeba použít hwupload_cuda jako poslední filtr, pokud byl předtím snímek uložen do RAM,
  • hardwarové filtry jako yadif_cuda vyžadují snímek v MEM, takže je potřeba použít hwupload_cuda před tím, než použijete daný cuda filtr,
  • softwarové filtry pracující se snímkem (např. scale, yadif, eq, apod.) vyžadují snímek v RAM a je potřeba použít hwdownload před použitím daného filtru,
  • pro převod bitové hloubky (parametr -pix_fmt) je potřeba mít snímek v RAM a je tedy potřeba použít hwdownload jako poslední filtr (pokud před tím používáte hardwarové filtry); po převodu bitové hloubky bude snímek automaticky nahrán do MEM, pokud je použit hardwarové encodér,
  • softwarové filtry, které přímo nepracují se snímky a jen mění způsob načtení nebo uložení videa (satsar, setdar, fps, apod.) nevyžadují snímek v RAM a lze je použít ať už je snímek uložen v RAM nebo MEM (není tedy potřeba používat hwdownload ani hwupload_cuda).

Jak už jsem psal výše, pokud si nejste jisti, jestli je potřeba převádět snímek pro použití fitru, zkuste to nejprve bez převodu a pokud dojde k chybě, zkuste použít jeden nebo druhý převod.

Poznámka: kodeky nvdec a nvenc jsou trochu pomalejší právě kvůli tomu, že musí ověřovat kam snímek uložit, ale jsou univerzálnější. Kodeky cuvid a cuda jsou mírně výkonější (řádově jednotky %), ale význam mají jen pokud nepoužijete softwarové zpracování a veškeré výpočty bude provádět jádro CUDA:

> ffmpeg -hwaccel cuvid -c:v h264_cuvid -hwaccel_output_format cuda -crop 140x140x0x0 -resize 1920x800 -i HD_input.mkv -vf yadif_cuda -c hevc_nvenc ... output.mkv

V tomto příkladu má smysl použít cuvid a cuda formáty, protože oříznutí, změna velikosti (vč. nastavení SAR a DAR), deinterlacing i enk´ódování bude probíhat v jádru CUDA a tudíž bude rychlejší.

> ffmpeg -hwaccel cuvid -c:v h264_cuvid -hwaccel_output_format cuda -i HD_input.mkv -vf "hwdownload,format=nv12,yadif,eq=1:0:1.5,hwupload_cuda" -c hevc_nvenc ... output.mkv

V tomto příkladu použití cuvid a cuda příliš smysl nedává, protože použití softwarových filtrů zpracování zpomaluje. Pokud místo toho použijete nvdec nebo softwarové načtění, můžete celé zpracování naopak vylepšit:

> ffmpeg -hwaccel nvdec -c:v h264_cuvid -i HD_input.mkv -vf "yadif,eq=1:0:1.5" -c hevc_nvenc ... output.mkv
> ffmpeg -i HD_input.mkv -vf "yadif,eq=1:0:1.5" -c hevc_nvenc ... output.mkv

Zobrazená rychlost videa (FPS)

FFMPEG používá několik různých údajů pro zobrazení rychlosti videa, resp. celého souboru a používá pro ně různé zkratky.

Hodnota fps (frame per second, tedy počet snímků za sekundu) udává rychlost, s jakou se bude video reálně přehrávat. Dříve byla v FFMPEG označována tbr (time based on real speed, tedy čas podle skutečné rychlosti). Tato hodnota je obvykle 25fps pro evropská a česká videa.

Hodnota tbc (time based on codec, neboli čas podle kodeku) udává, s jakou rychlostí snímků za sekundu video zpracovával kodek, který ho uložil. Tato hodnota se často liší, protože video může pocházet z americké televize vysílající 23,98fps nebo 29,99fps a následně bylo video převedeno na 25fps pro českou verzi. Znamená to tedy, že video se přehrává o něco rychleji nebo pomaleji oproti původnímu fps. Jiný rozdíl může být u prokládaného videa, které se nahrává a zpracovává rychlostí 50fps nebo 60fps a následně se přehrává rychlostí 25fps nebo 30fps tak, že každý snímek je složen ze dvou po sobě jdoucích (tzv. polovičních) snímků.

Třetí hodnota, kterou FFMPEG zobrazuje je tbn (time based on container), který udává hodnotu fps uloženou v souboru, který video obsahuje (AVI, MKV, apod.). Tato hodnota je použita přehrávačem k tomu, aby věděl, jak rychle má číst data ze souboru, aby byl schopen video přehrát a sesynchronizovat se zvukem a příp. titulky. Tato hodnota je obvykle stejná jako tbr (pro progresivní video) nebo tbc (pro prokládané video).

Hodnoty tbc a tbn jsou vždy uloženy v souboru s videem. Hodnota tbr (nově fps) je pak vždy vypočtena z tbc a tbn a dalších parametrů videa.

Převod zvuku do AAC nebo HE-AAC

FFMPEG obsahuje pouze základní verzi AAC enkodéru, který nemá tak dobré výstupní vlastnosti jako ostatní enkodéry.

Pokud tedy chcete zvuk převést do AAC nebo HE-AAC, doporučuji použít Nero AAC Encoder, který je zdarma ke stažení na stránkách https://www.videohelp.com/software/Nero-AAC-Codec. I když je nejnovější verze z roku 2010, pořád jde o jeden z nejlepších enkodérů (které jsou zdarma).

Pro převod zvukové stopy (ať už samostatné nebo v MKV či jiném kontejneru) musíte zvuk nejprve převést to WAV formátu, odeslat do Nero AAC a následně znovu připojit k výslednému souboru.

FFMPEG i Nero AAC podporuje přesměrování výstupu (známé jako pipe), takže je možno přímo převést soubor WAV do AAC bez zápisu na disk (jelikož nekomprimovaný WAV může mít až 2GB na hodinu záznamu, tak by u delších filmů zabíral zbytečně příliš místa na disku). Ve Windows se k tomu používá pomlčka místo jména souboru a svislítko (pipe) pro oddělení příkazů:

> ffmpeg -i in.mkv -map 0:a:0 -f wav - | neroaacenc -ignorelength -q 1.0 -if - -of out.m4a

V příkazu si všimněte několika věcí:

  1. Z kontejneru zvolený zvuk vybereme pomocí -map (jinak by FFMPEG hlásil, že video a titulky nelze vložit do WAV formátu). Pokud je v souboru jen jeden zvuk, stačí -map 0:a. Pokud je vstupem jen zvuk (mka, MP3, AC3, DTS, apod.), není potřeba uvádět.
  2. Místo parametru -c pro volbu kodeku použijeme -f pro volbu výstupního formátu. Formát WAV má pevně daný kodek (LPCM) i bitrate (~700kbps na kanál při 44kHz a 16 bitech), takže FFMPEG je zvolí sám podle vstupního souboru.
  3. Jako výstupní resp. vstupní soubor používáme zmíněnou pomlčku.
  4. Jako první parametr Nero AAC enkodéru musíme uvést -ignorelength, aby se program nesnažil z dat přečíst hlavičku, která ve WAV souborech obsahuje délku a další informace. Díky tomuto parametru enkodér bude převádět zvuk do AAC dokud bude dostávat data z FFMPEG.

Pro určení kvality AAC můžete použít konstantní tok (-cbr 128000), průměrný tok (-br 128000; odpovídá ABR u MP3) nebo řízení kvality (-q 0.5; obdoba CRF u x264 nebo stupni komprese u JPG). Osobně doporučuji používat řízení kvality, protože nabízí nejlepší poměr kvality a velikosti souboru.

Použítí kvality závisí na vašich preferencích (je důležitější čistý zvuk nebo malý soubor?). Pro představu jakou kvalitu použít: pro 128kbps MP3 zkuste -q 0.33, pro AAC nebo AC3 použijte -q 0.55 (a upravte tak, aby zdrojový i cílový bitrate byly zhruba stejné) a pro bezztrátové formáty (WAV, FLAC, DTS, apod.) pak -q 1.0.

Pokud chcete lepší kvalitu zvuku, můžete přidat parametr -he, který vynutí použití vylepšeného HE-AAC. Pro kvalitu pod 0.5 HE-AAC zvětší bitrate cca o 10%, ale získáte lepší zvuk. Pro vyšší kvalitu pak navíc HE-AAC zmenší bitrate (u -q 1.0 až o 50%).

Pokud je vstupní soubor stereo (tedy 2 kanály) můžete místo toho použít parametr -hev2, který navíc přidá data pro „parametrické stereo“ (PS; obdoba joint stereo u MP3). Doporučeno je pro vstupní data z MP3 128kbps a horší (nebo jiných zdrojů obdobné kvality).

Pozor na to, že ne všechna zařízení umí přehrávat AAC a ta která ho umí, nemusí podporovat SBR a PS. Pokud vaše zařízení nepodporuje SBR, bude přehrávat pouze základní verzi AAC (v nižší kvalitě). Pokud nepodporuje PS, bude přehrávat jen jeden kanál (mono) místo sterea. Pokud máte zařízení, které HE-AAC nepodporuje, použijte parametr -lc, čím vynutíte použití pouze základní verze AAC. Pokud ale enkódujete AAC z DTS nebo FLAC s kvalitou q = 1, pak má smysl použít HE-AAC, protože i když vaše zařízení nepoužije SBR složku, pořád budete mít o polovinu menší soubor.

Po té, co převedete zvuk do AAC ho můžete připojit zpět do videa pomocí FFMPEG (nebo MkvToolNix).

> ffmpeg -i in.mkv -i out.m4a -c copy -map 0:v -map 1:a out.mkv

Pokud chcete převést jeden zvuk do AAC a současně převést video a nebo další stopy pomocí FFMPEG, můžete to provést takto:

> ffmpeg -i in.mkv \
    -map 0:v:0 -c hevc -crf 28 out.tmp.hevc
    -map 0:s:0 -c srt out.tmp.srt
    -map 0:a:0 -f wav - | neroaacenc -ignorelength -q 1.0 -he -if - -of out.tmp.m4a
> ffmpeg -i out.hevc -i out.m4a -i out.srt -c copy out.mkv
> del out.tmp.*

Tyto příkazy převedou první video do HEVC, první zvuk do HE-AAC a první titulky do SRT. Následně vše spojí do výsledného souboru. (Nakonec smažeme dočasné soubory). Pokud máte málo místa na disku, můžete parametry -c hevc a -c srt přidat až do druhého příkazu jako -c:v hevc -c:s srt a příslušně upravit -map parametry. Zpracování bude ale obečně pomalejší, protože se zdrojový soubor bude muset projít dvakrát.

11 komentářů u „FFMPEG jako univerzální nástroj pro video, zvuk a titulky“

  1. Dobrý den,
    skvělý článek o FFmpeg a používání různých paramatrů. Děkuji.
    Mám ale dotaz, zda jste se setkal z omezením velikosti výstupního souboru? Já se pokoušel z dlouhého videa extrahovat audio stopu AAC do WAV a dostal hlášku o pádu převodu pro velký soubor?

    1. Dobrý den,
      ano máte pravdu, WAV je starý formát založeý na RIFF formátu (stejně jako AVI, BMP a další), který používá 16 bitová slova a proto je schopen uložit maximálně 4GB do „velikosti“, indexu, apod.

      Nicméně většina moderních nástrojů s tímto počítá a i když FFMPEG nahlásí, že vytvořený WAV je příliš velký a nemusí být přehratelný, stále dokáže uložit i větší soubory (pokud ukládáte na moderní disk jako je NTFS nebo EXT4, který 4+GB soubory zvládne) a ve skutečnosti tak nedojde k „pádu“ a soubor se uloží celý.

      V některých nástrojích je potřeba použít určitý parameter: například u Nero AAC Encoder je to -ignorelength a u Fraunhofer FDK AAC parameter -I nebo --ignorelength, a daný nástroj pak ignorue nesprávnou „velikost“ uloženou v soubory a čte soubor jednoduše jako dlouhý stream až do jeho skutečného konce.
      Díky tomu dokážete klidně vyexportovat několika hodinový 8-kanálový zvuk (který ve WAV může mít 6 a více GB) a bez problémů ho převést a uložit jako několika set megový HE-AAC (nebo cokoli, co potřebujete).

      Pokud byste měl nástroj, který tohle neumí, můžete použít FFMPEG s parametry -ss a -t, pomocí kterých můžete WAV rozdělit na kratší části (viz tento článek), ty zpracovat samostatně a následně je spojit (např. v MKVmerge – viz článek Urychlení dlouho-trvajícího převodu videa)

  2. Děkuji za odpověď.
    Na tento problém jsem narazil při použití programu SubtitleEdit pro synchronizaci a úpravu titulků, který si vnitřně vytváří WAV pro vizuální zobrazení zvuku na Waveform. Mám problémy s přehráváním videí s titulky na mé smartTV z domácího úložiště NAS(z lokální Flesh přímo v TV je to stejné). Po každém začátku další části podle Playlistu musím dát pausu a ručně nastavit znakovou sadu na UTF-8 (i když to má mkv v sobě nastaveno). Spojil jsem si tedy celou sérii do velkého souboru o délce 17:08 hod. Jenže Waveform v SE se vytvořil jen do času 12:29. Po kontaktu a pokusech s autorem SE, jsme společně přišli na to že za to může právě FFmpeg, kterým se Waveform na pozadí vytváří. A tak proto jsem zkusil se zeptat odborníků na FFmpeg. Ani na GitHubu jsem zatím řešení nenalezl.

    1. 1. ověřte si, že máte na disku dostatek místa – WAV se ukládá do složky %tmp%, která je obvykle na systémovém disku (C:), a pokud máte menší SSD nebo rozdělený HDD disk, nemusí na něm být dostatek místa, protože WAV o délce 17 hodin může mít desítky GB.

      2. zkuste aktualizovat ffmpeg, který SE používá – stahuje se do složky %appdata%\Subtitle Edit\ffmpeg\ (buď ho smažte a nechte SE stáhnout nový nebo stáhnětě nejnovější noční build z https://github.com/BtbN/FFmpeg-Builds/releases). FFMPEG neustále zlepšuje podporu, WAV nevyjímaje.

      3. zkuste video rozdělit (viz předchozí odpověď) na kratší část (např. po 10 hodinách) a zpracovat a přehrát samostatně. (Nastavit titulky 2x místo 1 je podle mě stále přijatelné).
      Je dokonce možné, že díky tomu zjistíte, že problém není v tom, že je video (resp. zvuk) příliš dlouhé, ale že došlo k nějaké chybě při spojení a FFMPEG padá kvůli něčemu jinému (např. že část zvuku v jednom díle chybí a proto zvuk skončí na 12:29, protože se domnívá, že již nepokračuje).

      4. zkuste zvuk z videa převést ručně nejnovějším ffmpeg („ffmpeg -report -i video.mkv -map 0:a:0 zvuk.wav“) a ověřit, že dojde ke stejné chybě. Pokud ano, nahlašte chybu vývojářům na https://www.ffmpeg.org/bugreports.html . Parametr -report vytvoří v aktuální složce log, který můžete přiložit k hlášení.

    2. Zkusil jsem to a ffmpeg nemá problém uložit dlouhý nebo velký soubor – bez problémů mi uložil 40 hodinový WAV (testováno na FFMPEG 5, který používá i nejnovější SE).
      Problém je v tom, jak SE generuje své Waveform, protože když do SE nahraju přímo ten 40h WAV, SE skončí s generováním Waveform po 12:25:00.

      Měl byste tedy znovu kontaktovat autora SE, aby ověřil, jak se vytváří Waveform.

      Abyste nemusel posílat dlouhý zvuk, doporučte mu programem YT-DLP (https://github.com/yt-dlp/yt-dlp/releases/) stáhnout 24 hodinové video se zvukem (https://youtu.be/xmGaAjeqaBQ). U něj mi SE skončil na značce 6:12:00.

  3. Ahoj, uvítal bych podrobnější rozebrání přesunů mezi pamětí, tj. hwdownload hwupload a hlavně těch formátů, které se tam používají… jako nv12, u QSV třeba věc jako hwupload=extra_hw_frames=64,format=qsv. Trochu v tom mám chaos. Třeba mě překvapilo, že když jedu výhradně cuvid+nvenc, s CUDA filtry jako třeba „scale_npp“ a najednou jsem nahodil filtr fps, tak mě z nepochopitelného důvodu to sežere i bez hwdownload. A naproti tomu jiný filtr jako třeba crop (na CPU, protože npp neumí), tak tam to logicky musím stýáhnout napřed do RAM, udělat crop a zas to poslat zpět. Prostě v tomto mám dost zmatek. Mám dojem, že někdy si to přesouvá nativně, někdy je třeba to zadat explicitně. Prostě moc nevím, čím se to řídí.

    1. To, zda je potřeba převést snímek do jiné paměti záleží na tom, jak který dekodér, enkodér či fitr funguje. Např. scale nebo eq mění přímo každý snímek a potřebuje ho v RAM. Naproti tomu filtry jako fps nebo setsar pouze mění způsob zpracování videa a nemění jednotlivé snímky a proto není potřeba mít snímek v RAM. Obdobně cuvid ukládá snímek pouze do MEM, zatímco nvdec dokáže snímek uložit i do RAM. Doplnil jsem popis do článku, ale vždy je lepší si to vyzkoušet, než spoléhat na nějaký seznam.
      Hardwarový dekodér podporuje resize i crop, jen je potřeba uvést je jako parametr vstupního kodeku a ne jako filtr (viz filtry v článku).

  4. A ještě řeším takový problém, potřebuji z 50i source videa udělat 25p. A nedaří se mi. Podle mého yadif není úplně vhodný nebo to neumí. Technicky by mělo stačit zkombinovat lichý a sudý půlsnímek vždy do jednoho celého snímku? Všechny mé pokusy s yadif končí s outputem fps=50. Viděl jsem nějakou šílenost přes tinterlace, ale takto základní věc by přeci mohla jít nějak jednoduše ne? 🙂

    1. Ahoj, yadif funguje tak, že snímky dopočítává/dokresluje, takže z 25 + 25 půlsnímků vytvoří 50 celých snímků.
      Důvodem je to, že v prokládaném videu není jednoduše jeden snímek rozdělený na dva, ale každý půlsnímek je posunutý o daný „půl čas“ (u 50i o 20ms) a proto na sebe nesedí. Pokud by se video vytvořilo jen spojením půlsnímků (25 + 25 = 25fps), tak by video v pohybu obsahovalo tzv. „duchy“ (tedy 2 snímky v různých pozicích – tento efekt obvykle vznikne, pokud naopak převedeš prokládané video na progresivní BEZ použití yadif filtru!!! (příklad na Wikipedii)
      Pro převod 50i na 25p můžeš použít kombinaci filtrů pro deinterlace (50i->50p) a následně změnu fps a zahození přebytečných snímků (50p->25p): -vf „yadif,fps=25“. Obvykle je ale lepší zachovat celých 50p pro lepší plynulost a ostrost videa.

Napsat komentář: Milan Čížek Zrušit odpověď na komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..