====== Zrychlení renderování v Blenderu pomocí příkazové řádky a FFmpeg ======
> **Poznámka k datu vzniku:** Tento článek vychází z původního textu z 19. 6. 2021. Jde o dobovou zkušenost a uvedené postupy, výkonové závěry i chování nástrojů nemusí odpovídat aktuálnímu stavu Blenderu, BPSRenderu ani FFmpegu.
Před nějakou dobou jsem se začal seznamovat s Blenderem. Osobně se mi moc líbí a vřele rád bych ho používal na editaci všech videí. Bohužel jsem na notebooku neměl moc výkonnou grafickou kartu, a tak byla editace či renderování videí rychlejší v jiných nástrojích, například v Kdenlive. Hledal jsem proto možnosti, jak renderování v Blenderu zrychlit, a tady jsou tipy, které se mi hodily z příkazové řádky.
===== Blender a spuštění renderování z příkazové řádky =====
Renderování videí jsem začal spouštět přes příkazovou řádku. Nepotřebuji vidět, jak se renderuje snímek po snímku, a mít kvůli tomu spuštěné grafické prostředí Blenderu. V grafickém prostředí si nachystám, co se má renderovat, a samotné spuštění dělám z příkazové řádky. Nejprve testuji pár prvních snímků, abych se ujistil, že jsem na nic nezapomněl. Když to vypadá dobře, spustím renderování celé.
Pro mě to přinášelo hlavně pohodlnost a efektivitu. Přes den jsem si nachystal několik souborů ''.blend'' a večer je zařadil v jednoduchém skriptu do fronty. Ráno bylo hotovo. Nemusel jsem nic obsluhovat ani spouštět grafické rozhraní kvůli dalšímu renderování. Pokud bych chtěl paralelizovat svépomocí, spustil bych dvě instance Blenderu, v jedné vyrenderoval polovinu snímků a ve druhé druhou polovinu. Nakonec bych výstup spojil pomocí FFmpegu do jednoho souboru.
Základní použití příkazové řádky je jednoduché. Tohle spustí renderování na pozadí a použije všechno, co bylo nastavené v grafickém režimu:
blender -b movie.blend -a
Další variantou je renderovat pouze část snímků, například prvních deset:
blender -b movie.blend -s 1 -e 10 -a
Nápověda, jak si dobře zapamatovat přepínače:
* **b** = background (na pozadí)
* **s** = start frame
* **e** = end frame
* **a** = já jsem si to pamatoval jako all, ale ve skutečnosti jde o ''render anim'', tedy renderování animace od začátku do konce
===== Blender Power Sequencer Render: bpsrender =====
Instalace nástroje je jednoduchá a je popsaná v [[https://github.com/GDQuest/blender-sequencer-multithreaded-render|repozitáři projektu]]. Nástroj slouží k paralelizaci renderování. V zásadě rozseká celé renderované video na několik částí, nad každou spustí renderování zvlášť a na konci výstup spojí do jednoho videa.
Párkrát jsem nástroj vyzkoušel a ještě jsem zvažoval další testování. Když pracuji s vystřiháváním videa z green screenu, tak tento nástroj nevyužívám, protože procesor je maximálně vytížený už při klasickém renderování. Od BPSRenderu jsem čekal zrychlení spíš při jednoduché editaci videí. Nicméně ani u klasické editace videí jsem nástroj nevyužíval tak, jak jsem původně očekával. Bylo to dáno tím, že i tak byl procesor vytížený na 60 až 70 % a ani při paralelním zpracování nedosahovala rychlost takových výsledků jako v Kdenlive. Nápověda použití ale prakticky stačí k jednoduchému nasazení. Většinou jsem používal jen parametr ''-w'' pro určení počtu instancí, které mají běžet paralelně.
usage: bpsrender [-h] [-o OUTPUT] [-w WORKERS] [-v] [--dry-run] [-s START]
[-e END] [-m] [-c] [-d] [-j]
blendfile
Multi-process Blender VSE rendering - will attempt to create a folder called
`render` inside of the folder containing `blendfile`. Inside `render` another
folder called `parts` will be created for storing temporary files. These files
will be joined together as the last step to produce the final render which
will be stored inside `render` and it will have the same name as `blendfile`
positional arguments:
blendfile Blender project file to render.
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Output folder (will contain a `bpsrender` temp folder
for rendering parts).
-w WORKERS, --workers WORKERS
Number of workers in the pool (for video rendering).
-v, --verbose Increase verbosity level (eg. -vvv).
--dry-run Run the script without actual rendering or creating
files and folders. For debugging purposes.
-s START, --start START
Start frame
-e END, --end END End frame
-m, --mixdown-only ONLY render the audio MIXDOWN
-c, --concatenate-only
ONLY CONCATENATE the (already) available video chunks
-d, --video-only ONLY render the VIDEO (implies --concatenate-only).
-j, --join-only ONLY JOIN the mixdown with the video. This will
produce the final render
===== FFmpeg =====
FFmpeg je velmi užitečný nástroj. Má mnoho přepínačů a rozhodně není mým cílem všechny explicitně zdokumentovat. Sepíšu však to, co se mi hodilo pro konkrétní úkony, protože se k těmto příkladům sám rád vracím.
==== FFmpeg a spojování více videí do jednoho ====
Pro spojení videí dohromady nejprve potřebuju vytvořit soubor, ve kterém bude pořadí a cesty jednotlivých videí. Soubor pojmenujme například ''videoList.txt'' a jeho obsah může vypadat takto:
file 'path/video1.mp4'
file 'path/video2.mp4'
Pak už stačí tento příkaz:
ffmpeg -f concat -safe 0 -i videoList.txt -c copy finalVideo.mp4
Video se nepřekóduje, pouze se zkopíruje a spojí dohromady. Z povahy věci předpokládám, že ''video1'' a ''video2'' by měly být ve stejném formátu a kodeku. Více příkladů pro spojování videí pomocí FFmpegu je v [[https://trac.ffmpeg.org/wiki/Concatenate|dokumentaci projektu]]. Soubor ''videoList.txt'' může obsahovat relativní i absolutní cesty. Pokud jsou cesty relativní, není potřeba parametr ''-safe 0''. Při generování souboru ''videoList.txt'' se může hodit i automatické vytvoření, pokud chci spojit větší množství videí:
for f in *.mp4; do echo "file '$f'" >> videoList.txt; done
==== Vyexportování zvuku z videa ====
Tato varianta vyexportuje zvuk z videa z mobilu bez rekomprese audia:
ffmpeg -i video.mp4 -vn -acodec copy vystupni-audio.aac
Vysvětlení parametrů:
* ''-vn'' = bez videa
* ''-acodec copy'' = překopíruj existující audio stream
Alternativní příkaz je:
ffmpeg -i video.mp4 -vn -c:a copy output.aac
Exportování zvuku s překódováním do jiného formátu:
ffmpeg -i video.mp4 -vn -c:a mp3 output.mp3
==== Výměna zvukové stopy ve videu za jinou ====
Dostal jsem se k videozáznamu, ve kterém byla zvuková stopa plná šumu. Nemělo smysl kvůli tomu renderovat celé video znovu. Vyexportoval jsem zvukovou stopu, vyčistil šum pomocí [[https://www.audacityteam.org/|Audacity]] a následně chtěl v původním videu nahradit původní zvukovou stopu novou.
ffmpeg -i video-se-spatnym-zvukem.mp4 -i audio-opraveny-zvuk.aac -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 new.mp4
Vysvětlení příkazu:
* ''-map 0:v:0'' mapuje první vstupní soubor (index ''0'') a jeho video stream na první video stream výstupního souboru
* ''-map 1:a:0'' mapuje druhý vstupní soubor (index ''1'') a jeho audio stream na první audio stream výstupního souboru
* ''-shortest'' je možné použít, pokud by audio bylo delší než video a chtěl bych audio zkrátit podle obrazu
* ''-c copy'' zajistí překopírování video stopy i audio stopy bez rekomprese; v ukázce je to rozepsané pro audio a video zvlášť
A proč tento způsob? Důvod je rychlost. Renderování a překódování videa ve videoeditoru by zabralo víc času než prosté vykopírování video stopy a spojení s novou zvukovou.
==== Překódování rozlišení videa ze 4K do HD ====
Začal jsem renderovat videa ve 4K rozlišení a někdy je potřebuju převést do HD (1920x1080). Nemá kvůli tomu smysl otevírat a nastavovat videoeditor, protože postačí FFmpeg.
ffmpeg -i video4k.mp4 -c:a copy -c:v libx264 -s:v 1920x1080 output.mp4
Vysvětlení parametrů:
* ''-c:a copy'' překopíruje audio, které není potřeba rekomprimovat
* ''-c:v libx264'' určuje kodek pro nové video; v tomto případě H.264 (MPEG-4 AVC)
* ''-s:v 1920x1080'' změní rozlišení vstupního videa na 1920x1080; alternativně lze použít i ''-s hd1080''
==== Překódování videa pro web a WhatsApp ====
Při jednom nahrávání videomanuálu jsem narazil na to, že jsem výsledné video nemohl poslat přes WhatsApp. Když jsem hledal příčinu, problém byl v tom, že obrazové snímky byly uložené ve formátu Planar 4:4:4 YUV a na web se lépe hodil komprimovanější formát Planar 4:2:2 YUV. Pomohl mi tento příkaz, který video zároveň zmenšil o více než 75 %:
ffmpeg -i video4k.mp4 -c:v libx264 -c:a aac -pix_fmt yuv422p output.mp4
===== Užitečné zdroje =====
* [[https://hitokageproduction.com/article/16|Renderování Blender VSE přes více procesů]]
* [[https://trac.ffmpeg.org/wiki/Concatenate|FFmpeg Concatenate]]
* [[https://stackoverflow.com/questions/44642227/ffmpeg-concat-command-error|FFmpeg concat command error]]
* [[https://github.com/GDQuest/blender-sequencer-multithreaded-render|GDQuest / blender-sequencer-multithreaded-render]]
* [[https://stackoverflow.com/questions/9913032/how-can-i-extract-audio-from-video-with-ffmpeg|How can I extract audio from video with FFmpeg?]]
* [[https://superuser.com/questions/1137612/ffmpeg-replace-audio-in-video|FFmpeg: replace audio in video]]
* [[https://stackoverflow.com/questions/37967120/ffmpeg-convert-from-h-264-high-444-profile-to-h-264-main-profile|FFmpeg convert from H.264 High 4:4:4 profile to Main profile]]