Mav-Tek
Mav-Tek

Reputation: 11

What ffmpeg output format (-f) do I use for two-pass encoding of mkv files

I recently backed up one of my Blu-ray movies and it is about 36 GB. Using ffmpeg to get info from the video, it is in h.264 in an mkv container. I want to shrink the file size using h.265 compression and targeting a bitrate of 4 Mbits/s so that I can stream it while I am away from my home over my Plex server. My upload speed is limited to 5 Mb/s.

Although I could easily do this with simple software, I want to learn more coding. I have found the proper ffmpeg code two do a two-pass encoding, but in all examples I have found, they use an output format of mp4 but state that "you need to specify an output format (with -f) that matches the output format you will use in pass 2." I assume my "output format" is mkv, but that does not allow my code to run. Can someone explain to me what is meant by output format and what I should be using to encode this from h264 to h265 in a mkv container?

ffmpeg -y -i input.mkv -c:v libx265 -b:v 4M -x265-params pass=1 -an -f mkv /dev/null && \ ffmpeg -i "Arrival (2016).mkv" -c:v libx265 -b:v 4M -x265-params pass=2 -c:a copy output.mkv 

Also, in order to make this work on my windows PC, I am trying to learn how to edit some of the arguments to allow it to work in Powershell. I believe this is how I would do that:

(ffmpeg -y -i input.mkv -c:v libx265 -b:v 4M -x265-params pass=1 -an -f mkv NUL) -AND (^ ffmpeg -i "Arrival (2016).mkv" -c:v libx265 -b:v 4M -x265-params pass=2 -c:a copy  output.mkv)

Upvotes: 1

Views: 5397

Answers (2)

somebadhat
somebadhat

Reputation: 779

How to choose ffmpeg codec and container for low bandwidth video server:

You might want to download, install and use Handbrake for Windows 64-bit and WinFF to learn what settings to use.

Windows users use NUL instead of /dev/null and ^ instead of \
Non-Windows users use /dev/null instead of NUL and \ instead of ^

ffmpeg -y -i "1.mkv" -c:v libx265 -b:v 4M -pass 1 -an -f matroska NUL &&^
ffmpeg -i "1.mkv" -c:v libx265 -b:v 4M -pass 2 -c:a aac -b:a 128k "output.mkv" 
rem 

is the same as

ffmpeg -y -i "1.mkv" -c:v libx265 -b:v 4M -pass 1 -an -f matroska NUL && ffmpeg -i "1.mkv" -c:v libx265 -b:v 4M -pass 2 -c:a aac -b:a 128k "output.mkv" 
rem 

You might want to compare Constant Rate Factor (CRF) versus Two-Pass ABR and 265 versus 264. 720p in a mp4 container, H264 w/ max bitrate of 4Mbps, and AAC audio might be your best choice. CRF265 makes the smallest file.

Make a 15 second video starting at 1 minute in:

ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -filter:v scale=1280:720 -preset slow -c:a copy -t 00:00:15 "outputSlow264720p.mp4" &&^
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -f matroska -c:a copy -t 00:00:15 "outputSlow264.mkv" &&^
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx265 -crf 28 -f matroska -c:a copy -t 00:00:15 "outputCRF265.mkv" &^
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx265 -b:v 4M -f matroska -c:a copy -t 00:00:15 "output4M265.mkv" &^
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -preset slow -crf 22 -f matroska -c:a copy -t 00:00:15 "outputCRF264Slow.mkv" &^
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -f matroska -c:a copy -t 00:00:15 "output4M264.mkv"
rem   

See https://trac.ffmpeg.org/wiki/Encode/H.265 These gains will be most pronounced at resolutions of 1080p and higher.
See https://trac.ffmpeg.org/wiki/Encode/H.264 CRF: This is the recommended rate control mode for most uses.
See https://programminghistorian.org/en/lessons/introduction-to-ffmpeg
See https://opensource.com/article/17/6/ffmpeg-convert-media-file-formats
See https://davidhide.com/2019/02/03/compressing-audio-with-ffmpeg-and-powershell/

See https://slhck.info/video/2017/02/24/crf-guide.html

PowerShell in one line with replacement for ^ and && : 2-pass both h265.mkv and h264.mp4 output

ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx265 -b:v 4M -pass 1 -an -f matroska -t 00:00:15 NUL; if($?) {ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx265 -b:v 4M -pass 2 -c:a copy -t 00:00:15 "output.mkv"}
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -pass 1 -an -f mp4 -t 00:00:15 NUL; if($?) {ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -pass 2 -c:a copy -t 00:00:15 "output.mp4"}
rem 

PowerShell in two lines: 720p h264.mp4 2-pass output

ffmpeg -ss 00:01:00 -i "1.mkv" -c:v libx264 -b:v 4M -filter:v scale=1280:720 -preset slow -c:a copy -t 00:00:15 -pass 1 output.mp4
ffmpeg -ss 00:01:00 -y -i "1.mkv" -c:v libx264 -b:v 4M -filter:v scale=1280:720 -preset slow -c:a copy -t 00:00:15 -pass 2 output.mp4
rem 

Preset - See https://trac.ffmpeg.org/wiki/Encode/H.264

A preset is a collection of options that will provide a certain encoding speed to compression ratio. A slower preset will provide better compression (compression is quality per filesize). This means that, for example, if you target a certain file size or constant bit rate, you will achieve better quality with a slower preset. Similarly, for constant quality encoding, you will simply save bitrate by choosing a slower preset.

Use the slowest preset that you have patience for. The available presets in descending order of speed are:

ultrafast
superfast
veryfast
faster
fast
medium – default preset
slow
slower
veryslow

Upvotes: 1

user13553086
user13553086

Reputation:

Use -f matroska. mkv is a common file extension for the matroska container format. Normally, ffmpeg uses the output filename to guess output format (e.g. *.ts -> mpegts, *.mp4 -> mp4, etc.). See output of ffmpeg -formats for a list of valid muxers and demuxers.

Upvotes: 4

Related Questions