tl;dr - Just use -crf with 1-pass unless you need a specific file size
- 1 pass is faster than 2 passes.
- 2-pass does not make a better quality or smaller file: it only lets you set the output file size (but not the quality), whereas
-crf lets you choose the quality (but not the file size).
Questions
I learned that 2 Pass encoding will do the job better.
Two-passes will to a better job targeting a specific output file size. Otherwise, just do a single pass with -crf.
I know that this command will give the output for the first pass also. That's fine. I will delete them.
You could output to /dev/null (Linux & macOS) or NUL (Windows) instead and avoid making a temporary file:
ffmpeg -y -i input.mkv -c:v libx264 -vf "scale=1920:1080" -b:v 3.5M -pass 1 -an -f mp4 /dev/null
ffmpeg -y -i input.mkv -c:v libx264 -vf "scale=1920:1080" -b:v 3.5M -pass 2 -c:a aac output.mp4
See FFmpeg Wiki: H.264 - Two-Pass for more info and examples.
What does -y and -passlogfile do?
-y Overwrite output files without asking for confirmation. Makes sense for the first pass, otherwise it will ask you File '/dev/null' already exists. Overwrite ? [y/N]. Yes, you can "overwrite" /dev/null.
-passlogfile Sets the two-pass log file name. You don't need to use this option unless you want to use a custom log file name instead of the default (ffmpeg2pass-0.log).
See the ffmpeg documentation for more info on these options.
Also is there any other setting can I add to improve the quality?
- Use the slowest preset you have patience for. See FFmpeg Wiki: H.264.
- Increase the bitrate.
- Use a more efficient encoder, such as libx265. See FFmpeg Wiki: H.265. Be aware that it is slow.
- Avoid upscaling. Experiment with different scaling algorithms to see what looks best to you:
"scale=1920:-2:flags=lanczos".
- Buy another drive and don't re-encode.