How to batch-convert videos with ffmpeg including all audio and subtitles

Since I spend quite a bit of time tinkering with this I though it might be interesting to others.

The following can be executed on a folder with a bunch of videos which ffmpeg will convert including all audio and subtitle streams and put in a subfolder (not very) originally called „Done“ (not sure if you need to create that folder or if ffmpeg will do that*):

for i in *.*; do ffmpeg -hwaccel_output_format cuda -i "$i" -map 0:v:0 -map 0:a? -map 0:s? -c:v hevc_nvenc -b:v 2000k -preset slow -c:a aac -b:a 128k -c:s copy "Done/${i%.*}.mkv"; done

All the for i in for the batch-conversion is way above my tiny „I can’t learn programming“ brain and is taken from this StackExchange thread (among other things I can’t find now). You could do *.mp4 or *.mkv if you only want those types of videos to be converted.

-hwaccel_output_format cuda and -c:v hevc_nvenc? tells ffmpeg to use the GPU with Cuda (so will probably only work with NVIDIA) and use HEVC (x265) as the video-codec.

The interesting bits are -map 0:v:0 -map 0:a? -map 0:s? which selects all video(?), audio streams and subtitles. I was using -map 0 before but this sometimes created empty video or audio streams which caused all video players I tried to crash (except for good old VLC who did not care). Not ideal.

-c:v and -c:a select the audio and video codecs (c = codec) with slow preset in this case, whereas

-b:v and -b:a tells ffmpeg the bitrate (b = bitrate).

-c:s copy copies the subtitles.

* Edit: You do need to have a folder withe name you specify there in the folder where you run the script. If someone knows how to automate that I’d be happy to hear how ^__^