Guides · FFmpeg delivery encode

FFmpeg delivery-encode checklist: pick veryfast CRF, CRF+VBV, or 2-pass, then verify with ffprobe

Published

By ToolBrivio Editorial

FFmpeg delivery encode checklist cover: yellow 1–3 intent steps beside three measured path strips — veryfast CRF 24, CRF 22+VBV, and 2-pass 6000k
Cover, October 17, 2026: Guides checklist layout — numbered intent → command → ffprobe steps beside three measured path strips (veryfast CRF 24, CRF 22 + VBV, 2-pass 6000k) from real encode frames. Distinct from the companion Reviews cover (dark terminal MEASURED summary), not a second terminal crop.

Your cut interview is still too big for the portal or client, and you need a pasteable FFmpeg line — not another preset click. Write the intent first (fast delivery, peak-rate / capped CRF, or hard byte class), run one of the libx264 commands below, then accept or reject with ffprobe. This Guide is that checklist.

This is the delivery-encode checklist. The same-day FFmpeg delivery-encode review explains what those four lines did on our Seattle fixture. Prefer named GUI presets? Use the HandBrake delivery-encode checklist. Still have dead air in the keep merge? Audit the cut first: LosslessCut export duration audit.

Test note: October 17, 2026, Asia/Shanghai, Debian GNU/Linux 13 (trixie). Tools: FFmpeg / ffprobe 7.1.5-0+deb13u1, encoder tag Lavc61.19.101 libx264. Software x264 only on this box (no NVENC/QSV). Fixture: seattle_interview_delivery_src.mp4 — 30.000 s, 1920×1080@30, 1,102,887,801 bytes (1051.80 MiB). Shared delivery flags on every run: -c:a aac -b:a 160k -movflags +faststart -pix_fmt yuv420p -r 30.

Accept criteria before you upload

Persona: a creator who already cut the interview and needs a binary go / no-go on the delivery MP4. Minimum checks:

CheckPASSFAILHOLD
Byte size vs targetFile ≤ named portal/client cap (e.g. 2-pass path < 25 MB on our 30 s clip)Bytes over the hard capNo written size or peak-rate target
DurationVideo duration matches source class (ours: 30.000 s video; container ≈30.016 s OK)Multi-second shorten/lengthen you did not intendUnknown expected duration
ResolutionMatches intended delivery class (ours: stayed 1920×1080)Unexpected scale/crop—
Codecs / containerH.264 + AAC in MP4 (what we produced)Wrong container for the portalPortal codec rules not known
Command documentedFull ffmpeg line recorded on the checklist—You cannot reproduce the encode

1. Write down the intent

Record the portal/client limit in MiB or MB, or a peak-rate brief, before you encode. Our measured map on this fixture:

  • Fast delivery — small + quick, no hard MB label → veryfast CRF 24
  • Capped CRF / peak — quality number in writing and a Level-style peak → CRF + -maxrate + -bufsize
  • Hard byte class — e.g. under ~25 MB for 30 s → 2-pass ABR

Source we started from: 1051.80 MiB, 30.000 s, 1920×1080@30. Public rate-control guides split the same way (CRF vs capped CRF/VBV vs 2-pass); we used that structure to pick commands — not their sample bitrates.

2. Choose the control: veryfast CRF vs CRF+VBV vs 2-pass

Terminal-style summary of FFmpeg 7.1.5 and four measured delivery encode sizes and wall times
Command-output summary from this box’s measured results (October 17, 2026). CLI evidence only — no fake GUI.
  • veryfast + CRF 24 + Main@L4.0 — fast delivery. On our fixture: 11.98 MiB (12,562,019 B) in 10.111 s.
  • medium + CRF 22 + High@L4.0 bare — teaching uncapped only. 180.90 MiB in 32.337 s. Stills look fine; not a platform size promise.
  • same + VBV 25M / 31.25M — capped CRF. 86.34 MiB (90,534,405 B) in 27.893 s. Need both -maxrate and -bufsize.
  • 2-pass 6000k High@L4.2 — size-cap intent. 21.96 MiB (23,021,560 B) in 19.689 s — under ~25 MB on this 30 s clip.

Teaching point: bare CRF ≠ size or peak-rate guarantee. Preset (veryfast / medium) is orthogonal to CRF — speed vs efficiency, not a substitute for maxrate or a bitrate target.

3. Encode with pasteable commands

Swap in your cut file and output name. Paths match our evidence tree.

# A) Fast delivery
ffmpeg -y -i seattle_interview_delivery_src.mp4 \
  -c:v libx264 -preset veryfast -crf 24 -profile:v main -level 4.0 \
  -pix_fmt yuv420p -r 30 -c:a aac -b:a 160k -movflags +faststart \
  ff_veryfast_crf24.mp4

# B) Teaching: uncapped CRF (do not treat as a size promise)
ffmpeg -y -i seattle_interview_delivery_src.mp4 \
  -c:v libx264 -preset medium -crf 22 -profile:v high -level 4.0 \
  -pix_fmt yuv420p -r 30 -c:a aac -b:a 160k -movflags +faststart \
  ff_medium_crf22.mp4

# C) Capped CRF / VBV (Level 4.0-style peak)
ffmpeg -y -i seattle_interview_delivery_src.mp4 \
  -c:v libx264 -preset medium -crf 22 -profile:v high -level 4.0 \
  -maxrate 25000k -bufsize 31250k \
  -pix_fmt yuv420p -r 30 -c:a aac -b:a 160k -movflags +faststart \
  ff_medium_crf22_vbv25.mp4

# D) Hard ~25 MB / 30 s class on our fixture
ffmpeg -y -i seattle_interview_delivery_src.mp4 \
  -c:v libx264 -preset medium -b:v 6000k -pass 1 -profile:v high -level 4.2 \
  -pix_fmt yuv420p -r 30 -an -f null /dev/null
ffmpeg -y -i seattle_interview_delivery_src.mp4 \
  -c:v libx264 -preset medium -b:v 6000k -pass 2 -profile:v high -level 4.2 \
  -pix_fmt yuv420p -r 30 -c:a aac -b:a 160k -movflags +faststart \
  ff_social_2pass_6000k.mp4

Write the exact command on the checklist before you move on. Do not upload on hope.

4. Verify with ffprobe before upload

# Size + container duration
ffprobe -hide_banner -show_entries format=size,duration \
  -of default=noprint_wrappers=1 delivery.mp4

# Resolution + video duration + fps
ffprobe -hide_banner -select_streams v:0 \
  -show_entries stream=width,height,duration,r_frame_rate,codec_name \
  -of default=noprint_wrappers=1 delivery.mp4

# Audio codec (expect aac on our MP4s)
ffprobe -hide_banner -select_streams a:0 \
  -show_entries stream=codec_name,duration \
  -of default=noprint_wrappers=1 delivery.mp4

On our 2-pass output we measured size=23021560 (21.96 MiB), video width=1920 height=1080 duration=30.000000, codec_name=h264 + AAC. Same duration/resolution class on the other three paths.

Optional frame spot-check (readable titles on our fixture; not a perceptual metric):

ffmpeg -ss 5 -i delivery.mp4 -frames:v 1 check_t5s.jpg

5. Worked example: 2-pass 6000k (measured)

Goal: stay under 25 MB for a 30-second 1080p clip. Control: 2-pass -b:v 6000k High@L4.2.

MetricMeasured
Output bytes23,021,560 (21.96 MiB) — under 25 MB on this clip
Wall time19.689 s (pass 1: 8.844 s; pass 2: 10.846 s)
Video duration30.000 s (container ≈30.016 s)
Resolution / fps1920×1080 @ 30 fps
Video bitrate (approx)~6.0 Mbps
FFmpeg 2-pass 6000k output frame at about 5 seconds: KEEP A text still readable
2-pass 6000k at t≈5 s. KEEP A title still readable after the size-cap encode — spot-check only, not VMAF.

Verdict on this fixture: PASS for a 25 MB hard cap (21.96 MiB), duration/resolution match, H.264+AAC MP4. Not a guarantee that every different source at 6000k lands under 25 MB — re-probe yours.

6. Compare the four paths (pick by goal)

PathBytesMiBWallControlPick when…
veryfast CRF 2412,562,01911.9810.111 sMain@L4.0Fast + small, no hard MB label
medium CRF 22 bare189,687,049180.9032.337 sHigh@L4.0 uncappedTeaching only — shows CRF drift
CRF 22 + VBV 25M90,534,40586.3427.893 smaxrate 25M / buf 31.25MCRF-in-writing plus a peak brief
2-pass 6000k23,021,56021.96 (<25 MB)19.689 sHigh@L4.2 ABRHard byte class on a short clip

All four: video duration 30.000 s, 1920×1080. Source was 1051.80 MiB.

Download the checklist

Download the FFmpeg delivery-encode checklist (Markdown). Fill intent and the full command before you encode, paste ffprobe size/duration/resolution on rejects, and keep the cut master untouched when you upload the encode copy.

FAQ

Which FFmpeg path should I pick for a hard ~25 MB / 30 s class?

On our October 17, 2026 fixture (FFmpeg 7.1.5 libx264), a 2-pass -b:v 6000k High@L4.2 encode wrote 23,021,560 bytes (21.96 MiB) — under 25 MB on that 30 s clip — in 19.689 s. veryfast CRF 24 was smaller and faster (11.98 MiB / 10.111 s) but is a quality/speed path, not a named byte cap.

Why did bare CRF 22 write 180.90 MiB while the same CRF with VBV wrote 86.34 MiB?

CRF aims at a quality level and lets bitrate float with content. On our noisy Seattle stand-in, medium CRF 22 without a peak cap wrote 189,687,049 bytes (180.90 MiB). Adding -maxrate 25000k and -bufsize 31250k (Level 4.0-style VBV) dropped the same CRF/preset to 90,534,405 bytes (86.34 MiB). You need both maxrate and bufsize together.

Do I need -movflags +faststart and -pix_fmt yuv420p on every delivery MP4?

We used both on every measured output: yuv420p for common player compatibility, +faststart so the moov atom sits up front for progressive download. Skip them only when a deliberate workflow says otherwise — and document that choice on the checklist.

What do I verify with ffprobe before upload?

Check format size and duration, video stream width/height/duration, and codecs (H.264 + AAC in MP4 on our runs). All four of our outputs kept 1920×1080 and video duration 30.000 s (container ≈30.016 s). FAIL if bytes exceed your target or duration/resolution diverge from the source you intended to deliver.

Honest limits

  • Synthetic Seattle interview stand-in (color + noise panels) — not a real client face shoot; no VMAF / perceptual ranking.
  • Software x264 only on this box — NVENC / QSV / SVT-AV1 / HEVC not tested.
  • Windows and macOS FFmpeg builds not tested.
  • Hour-long / multi-GB camera files not tested (30 s fixture only).
  • HandBrake GUI presets out of scope here — use the HandBrake delivery-encode checklist for named presets.
  • FFmpeg re-encodes — wrong tool for “just cut dead air” (use LosslessCut, then this checklist).

When size fails the cap, change intent (add VBV, or switch to 2-pass) and re-probe — do not upload on hope. When it passes, upload the encode copy and keep the cut master bit-identical for disputes.

Test basis: CLI sizes, wall times, and ffprobe dumps on October 17, 2026 under evidence/ffmpeg/. Related: HandBrake delivery-encode checklist · LosslessCut export duration audit.

The ToolBrivio digest

Better software choices, in your inbox.

A weekly selection of software reviews and practical guides. Launching soon — leave your email to join the waitlist.