<< Root
Profile Picture

My FFMPEG collection of usefulness!

Requires ffmpeg CLI and optionally mkvtoolnix CLI.

This list contains first VAAPI commands for AMD and INTEL hardware accelerated encoding. If you scroll down or Ctrl+F to the NVENC section you will see the same commands but for NVIDIA cards.

If there are any issues you can let me know. And if you've fixed them then even better, I will just update them here too.

Notes READ THEM IF U DARE

Open Terminal in the folder where the videos you want to convert are are so that you won't have to enter their entire path in the input.

-c:v means "codec video".

-c:a means "codec audio".

-b:v means "bitrate video".

-b:a means "bitrate audio".

-an drops the audio track "audio none".

Common video codecs to convert to are av1_vaapi h265_vaapi h264_vaapi for AMD and av1_nvenc h265_nvenc h264_nvenc for Nvidia.

Common audio codecs to convert to are libopus mp3 aac.

-map 0 preserves all audio, video, subtitle etc tracks. If you don't use that it will only take the 1st video track and 1st audio track.

-map 0 can rarely cause an error -"Automatic encoder selection failed Default encoder for format mp4 (codec none) is probably disabled. Please choose an encoder manually."- this means that one of the tracks can't be processed and for now the only solution I have is to just not use it if that occurs.

-hide_banner hides the info dump which you most likely won't need to view.

Add bitrate metadata to an mkv file (unlike mp4, mkv needs this done manually).

mkvpropedit --add-track-statistics-tags "video.mkv"

You can check what kind of vaapi hardware acceleration you have with vainfo.

Use hardware decoding (helped on github by RushingAlien)

Quick (change parameters for desired output)

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "input.mp4" -map 0 -c:v av1_vaapi -b:v 8000k -c:a libopus -b:a 256k "output.mp4" -hide_banner

If hardware decoding fails, try adding -vf 'format=nv12,hwupload' after the input file. If it still fails then use a command from the tab below - "Don't use hardware decoding".

Long version with an "if" statement and variables.

The "if" statement is for adding bitrate metadata if you're outputting to mkv. It needs mkvtoolnix CLI.

i="input.mp4"
o="output.mkv"
vidbitr="20000k"
audbitr="256k"
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "$i" -map 0 -c:v av1_vaapi -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" "$o" -hide_banner;
if [ ${o##*.} = "mkv" ]; then
    mkvpropedit --add-track-statistics-tags "$o"
fi

Don't use hardware decoding

For codecs that don't have hardware accelerated decoding for example MPEG4 codec.

Quick (change parameters for desired output)

ffmpeg -init_hw_device vaapi=amd0:${render_dev} -filter_hw_device amd0 -i "Editor.mov" -vf 'format=nv12,hwupload' -c:v av1_vaapi -b:v 10000k -c:a libopus -b:a 256k "out.mp4" -hide_banner

Long version with an "if" statement and variables.

The "if" statement is for adding bitrate metadata if you're outputting to mkv. It needs mkvtoolnix CLI.

i="input.mov"
o="output.mkv"
vidbitr="10000k"
audbitr="256k"
ffmpeg -init_hw_device vaapi=amd0:${render_dev} -filter_hw_device amd0 -i "$i" -vf 'format=nv12,hwupload' -c:v av1_vaapi -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" "$o" -hide_banner;
mkvpropedit --add-track-statistics-tags "$o"

instagram preset

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "input.mkv" -map 0 -c:v h264_vaapi -b:v 15000k -c:a aac -b:a 192k "output.mp4" -hide_banner

twitter preset

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "input.mkv" -map 0 -c:v h264_vaapi -vf "scale_vaapi=iw*0.75:ih*0.75" -b:v 8000k -c:a aac -b:a 192k "output.mp4" -hide_banner

bluesky/mastodon preset

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "input.mkv" -map 0 -c:v av1_vaapi -vf "scale_vaapi=iw*0.75:ih*0.75" -b:v 10000k -c:a libopus -b:a 128k "output.mp4" -hide_banner

BATCH

Convert all videos (with the same container) in the current folder. This WILL PUT THEM IN A NEW FOLDER "ffmpeg".

Replace *.mkv with *.mp4 or whatever container you want to be converted. You can run this multiple times if you have multiple containers in the folder.

for mp4
mkdir -p "ffmpeg";
for i in *.mp4; do ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "$i" -map 0 -c:v av1_vaapi -b:v "20000k" -c:a libopus -b:a "256k" ffmpeg/"$i" -hide_banner; done
for mkv
vidbitr="20000k"
audbitr="256k"
mkdir -p "ffmpeg";
for i in *.mkv; do ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "$i" -map 0 -c:v av1_vaapi -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" ffmpeg/"$i" -hide_banner; mkvpropedit --add-track-statistics-tags ffmpeg/"$i"; done

For video proxies that I use in Blender Video Editor

This command checks if proxies already exist in the target folder and it will not redo them.

Don't forget that the inputs are checked BY EXTENSION .mp4/.mkv If you have multiple ones, run the command multiple times after modifying the extension in the command.

TARGET="/path/to/blender/proxies"
for i in *.mkv; do 
echo $i
if [ -d "$TARGET/$i" ]; then
    echo "Proxy $TARGET exists. Skipping..."
    continue
else
    mkdir -p "$TARGET/$i"
    ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i "$i" -c:v h264_vaapi -profile:v constrained_baseline -vf "scale_vaapi=iw*0.5:ih*0.5" -rc_mode VBR -b:v 5000k -an "$TARGET/$i/proxy_50.avi" -hide_banner
fi 
done

-vf "scale_vaapi=iw*0.5:ih*0.5" this means 50% resolution. You can change it to 0.25 or 0.75 if you want but remember to also change "$TARGET/$i/proxy_50.avi". 25% would be proxy_25.avi and 75% would be proxy_75.avi.

Split into multiple files by amount of time

If you're editing a video and your input VODs are like over an hour long you should definitely split it so that your editing software doesn't explode your house.

This does not re-encode anything, it only splits the input file by a set amount, creating multiple files.

ffmpeg -i "input.mp4" -c:v copy -c:a copy -segment_time 00:30:00 -f segment -reset_timestamps 1 "output-%03d.mp4" -hide_banner

-map 0 can cause timestamps to not cut.

NVIDIA (NVENC)

These are the same commands as above but modified to work on Nvidia cards.

Basically anything that is vaapi in the command now has to be cuda except for the video codecs which can only be av1_nvenc h265_nvenc h264_nvenc

Use hardware decoding (helped on github by RushingAlien).

Quick (change parameters for desired output)

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "input.mp4" -map 0 -c:v av1_nvenc -b:v 8000k -c:a libopus -b:a 256k "output.mp4" -hide_banner

If hardware decoding fails, try adding -vf 'format=nv12,hwupload' after the input file. If it still fails then use a command from the tab below - "Don't use hardware decoding".

Long version with an "if" statement and variables.

The "if" statement is for adding bitrate metadata if you're outputting to mkv. It needs mkvtoolnix CLI.

i="input.mp4"
o="output.mkv"
vidbitr="20000k"
audbitr="256k"
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "$i" -map 0 -c:v av1_nvenc -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" "$o" -hide_banner;
if [ ${o##*.} = "mkv" ]; then
    mkvpropedit --add-track-statistics-tags "$o"
fi

Don't use hardware decoding

For codecs that don't have hardware accelerated decoding for example MPEG4 codec.

Quick (change parameters for desired output)

ffmpeg -init_hw_device cuda=cuda0:${render_dev} -filter_hw_device cuda0 -i "Editor.mov" -vf 'format=nv12,hwupload' -c:v av1_nvenc -b:v 10000k -c:a libopus -b:a 256k "out.mp4" -hide_banner

Long version with an "if" statement and variables.

The "if" statement is for adding bitrate metadata if you're outputting to mkv. It needs mkvtoolnix CLI.

i="input.mov"
o="output.mkv"
vidbitr="10000k"
audbitr="256k"
ffmpeg -init_hw_device cuda=cuda0:${render_dev} -filter_hw_device cuda0 -i "$i" -vf 'format=nv12,hwupload' -c:v av1_nvenc -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" "$o" -hide_banner;
mkvpropedit --add-track-statistics-tags "$o"

instagram preset

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "input.mkv" -map 0 -c:v h264_nvenc -b:v 15000k -c:a aac -b:a 192k "output.mp4" -hide_banner

twitter preset

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "input.mkv" -map 0 -c:v h264_nvenc -vf "scale_cuda=iw*0.75:ih*0.75" -b:v 8000k -c:a aac -b:a 192k "output.mp4" -hide_banner

bluesky/mastodon preset

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "input.mkv" -map 0 -c:v av1_nvenc -vf "scale_cuda=iw*0.75:ih*0.75" -b:v 10000k -c:a libopus -b:a 128k "output.mp4" -hide_banner

BATCH

Convert all videos (with the same container) in the current folder. This WILL PUT THEM IN A NEW FOLDER "ffmpeg".

Replace *.mkv with *.mp4 or whatever container you want to be converted. You can run this multiple times if you have multiple containers in the folder.

for mp4
mkdir -p "ffmpeg";
for i in *.mp4; do ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "$i" -map 0 -c:v av1_nvenc -b:v "20000k" -c:a libopus -b:a "256k" ffmpeg/"$i" -hide_banner; done
for mkv
vidbitr="20000k"
audbitr="256k"
mkdir -p "ffmpeg";
for i in *.mkv; do ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "$i" -map 0 -c:v av1_nvenc -b:v "$vidbitr" -c:a libopus -b:a "$audbitr" ffmpeg/"$i" -hide_banner; mkvpropedit --add-track-statistics-tags ffmpeg/"$i"; done

For video proxies that I use in Blender Video Editor

This command checks if proxies already exist in the target folder and it will not redo them.

Don't forget that the inputs are checked BY EXTENSION .mp4/.mkv If you have multiple ones, run the command multiple times after modifying the extension in the command.

TARGET="/path/to/blender/proxies"
for i in *.mkv; do 
echo $i
if [ -d "$TARGET/$i" ]; then
    echo "Proxy $TARGET exists. Skipping..."
    continue
else
    mkdir -p "$TARGET/$i"
    ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i "$i" -c:v h264_nvenc -profile:v constrained_baseline -vf "scale_cuda=iw*0.5:ih*0.5" -rc_mode VBR -b:v 5000k -an "$TARGET/$i/proxy_50.avi" -hide_banner
fi 
done

-vf "scale_cuda=iw*0.5:ih*0.5" this means 50% resolution. You can change it to 0.25 or 0.75 if you want but remember to also change "$TARGET/$i/proxy_50.avi". 25% would be proxy_25.avi and 75% would be proxy_75.avi.

Split into multiple files by amount of time

If you're editing a video and your input VODs are like over an hour long you should definitely split it so that your editing software doesn't explode your house.

This does not re-encode anything, it only splits the input file by a set amount, creating multiple files.

ffmpeg -i "input.mp4" -c:v copy -c:a copy -segment_time 00:30:00 -f segment -reset_timestamps 1 "output-%03d.mp4" -hide_banner

-map 0 can cause timestamps to not cut.

Mastodon (link used for site verification on Mastodon)