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 ^__^