2

I'm trying to replicate Handbrake settings with ffmpeg, because I'd like to add some metadata and some other things with ffmpeg that Handbrake can not do.

What I've done seems to be close, the resulting file size and encoding time is similar, but Handbrake just produces visibly (but not drastically) better image.

Here's an example, ORIGINAL HANDBRAKE FFMPEG

These are cropped and zoomed in 300%. Here for example handbrake preserves more color in one of butterflies legs, more detail between the yellow parts of its wings, and in general seems more sharp. May be hard to notice what I'm talking about but the differences are there and more obvious on some other videos.

The x265 encoder versions are slightly different, but I believe that is not the reason for the difference. Handbrake has "x265 3.5+1-f0c1022b6" and ffmpeg has "x265 3.5+37-07b011400" but I've tried with ffmpeg with older x265 and the result was identical to the latest x265. And they are both inferior in my view to the Hanbrake.

Here are the screenshots of Handbrake Summary Dimensions Video

and the ffmpeg command

ffmpeg -i "in.mp4" -map_metadata -1 -vf scale=1280:720 -c:a copy -c:v libx265 -crf 27 -preset fast "out.mp4"

Here are the Mediainfos of all 3 files, including the original, the encoding logs, the Handbrake preset and the ffmpeg command: Pastebin Folder

Also for some reason the keyframes are in different places.

My question is, what can I change in my ffmpeg command to make the result identical to Handbrake?

DD3R
  • 95

1 Answers1

4

In the logs, there are few differences: The input is a 4k 10bit video, output is 720p. ffmpeg chose to encode x265 using the main10 profile to keep 720p-10bit. In HandBrake you must select H.265 10-bit as the encoder so in this case its output was 8bit. I prefer 10 bit output since this reduces banding on lower bit rate sources.

The keyint min/max (aka Keyframe or GOP). ffmpeg uses the defaults, 25/250 whereas handbrake tweaks this to 1 second / 10 seconds (* ~60 fps in this case) for parameters of 60 /600. I would also recommend deblock=-1 as the x265 encoder is a bit soft.

There could be a problem with the output video with colors appearing washed out or dark on non HDR displays. In that case you will need to tone map the bt2020 to bt709. A discussion can be found here https://github.com/jellyfin/jellyfin/issues/415

So to get close to handbrake use:

ffmpeg -i "in.mp4" -map_metadata -1 -vf scale=1280:720 -c:a copy -c:v libx265 -crf 27 -preset fast -x265-params "deblock=-1:min-keyint=60:keyint=600" out.mp4"

If you want to force 8 bit (like your handbrake output)

ffmpeg -i "in.mp4" -map_metadata -1 -vf scale=1280:720,format=yuv420p -c:a copy -c:v libx265 -crf 27 -preset fast -x265-params "deblock=-1:min-keyint=60:keyint=600" out.mp4"

To force 10bit from an 8bit source, use format=yuv420p10le.

To improve quality even more, change the crf from 27 to 25 or 23 (lower is better).

If you're not stuck on mp4 and ffmpeg, you can use the handbrake gui or cli to encode, and follow with mkvmerge gui or cli to output to an mkv with meta data.

at2010
  • 134
  • 6