fqmpeg's C1 cluster is seven verbs that cover the entire compression and encoding workflow: compress for everyday H.264, encode-h265 / encode-av1 / encode-vp9 for modern codecs, encode-prores and encode-dnxhd for editing-grade intermediates, and bitrate for targeted file-size control. Every command has source-verified defaults, prints the underlying FFmpeg invocation under --dry-run, and rejects bad input before FFmpeg starts.
This guide walks through each command — what it does, the FFmpeg flags it produces, the defaults, and the output naming rule — then shows real multi-step recipes that combine them into actual delivery workflows. Everything below is verified against the source in src/commands/ of fqmpeg 3.0.1.
What you'll get out of this guide
- Which of the 7 verbs to pick for which job (decision matrix)
- Default values, ranges, and output filenames for every command
- The exact FFmpeg command each verb generates (verified
--dry-runoutput) - Four end-to-end recipes that chain compression with other clusters
Codec Selection: Which Verb for Which Job
Codec choice is a delivery question first, a quality question second, and a CPU-time question third. The mental shortcut:
| Goal | Verb | Codec | Container |
|---|---|---|---|
| Default delivery / max compatibility | compress | H.264 | .mp4 |
| Stream to YouTube / modern platforms | encode-av1 | AV1 | .mkv |
| Archive / 4K phone backups | encode-h265 | H.265 (HEVC) | .mkv |
| Open-web embed (no licensing fees) | encode-vp9 | VP9 | .webm |
| Edit in Final Cut / Premiere / Resolve | encode-prores | ProRes | .mov |
| Edit in Avid Media Composer | encode-dnxhd | DNxHR | .mxf |
| Hit a hard file-size limit | bitrate | H.264 (target bps) | .mp4 |
For a deeper background on the trade-offs between AV1, H.265, and H.264 — encoding speed, hardware support, licensing — see the AV1 vs H.265 vs H.264 comparison and the video compression guide.
The two big practical splits:
- Delivery codecs vs. editing codecs. Delivery codecs (H.264, H.265, AV1, VP9) maximize compression — small files, slow seeking, decode-heavy. Editing codecs (ProRes, DNxHR) do the opposite — large files, frame-accurate scrubbing, near-lossless quality. You don't pick "the best codec." You pick the right codec for the next step in the pipeline.
- CRF vs. bitrate. All four delivery encoders default to CRF (constant-quality), which lets the encoder spend more bits on hard scenes. Use
bitrateonly when you genuinely have a fixed budget — Discord's 25 MB cap, an embed in a size-constrained CMS, a fixed-bandwidth streaming target.
Delivery Codecs: H.264, H.265, AV1, VP9
compress — H.264 / x264 (default delivery)
The everyday verb. H.264 is the codec that every device made in the last decade can play, including iPhones from 2012 and Smart TVs that haven't seen a firmware update since.
- Source:
src/commands/compress.js - FFmpeg encoder:
libx264 - Audio: re-encoded to AAC (recommended for
.mp4containers) - Container flag:
-movflags +faststart(moves the moov atom to the front so the file streams without buffering the trailer)
Options:
| Option | Default | Range | Notes |
|---|---|---|---|
--crf <n> | 23 | 0–51 | Lower = better quality, larger file. 18 is "visually lossless"; 28 is aggressive |
--preset <name> | medium | x264 enum¹ | Slower preset = same CRF but smaller file (more CPU per frame) |
¹ Allowed presets: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo.
Default output filename: input-compressed.mp4 (extension preserved from input).
$ npx fqmpeg compress input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart input-compressed.mp4
Override examples:
# Higher quality, slower encode
npx fqmpeg compress input.mp4 --crf 18 --preset slow
# Quick draft for review
npx fqmpeg compress input.mp4 --crf 28 --preset veryfast
encode-h265 — H.265 / HEVC
Same x265 family as H.264's libx264, but produces files roughly 30–50 % smaller at the same quality. The trade-off is encoding speed (substantially slower than x264 at matching presets) and licensing — H.265 patents are still active, which is why most browser-native playback paths skip it. Use it for archives, 4K phone backup, and Apple-ecosystem distribution where HEVC plays natively.
- Source:
src/commands/encode-h265.js - FFmpeg encoder:
libx265 - Audio: copied (
-c:a copy) — keeps the original audio stream untouched - Container: Matroska (
.mkv) — supports HEVC without container-level fuss
| Option | Default | Range | Notes |
|---|---|---|---|
--crf <n> | 28 | 0–51 | x265's perceptual scale runs higher than x264 — CRF 28 in x265 ≈ CRF 23 in x264 |
--preset <p> | medium | same 10-step enum as x264 |
Default output filename: input-h265.mkv.
$ npx fqmpeg encode-h265 input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a copy input-h265.mkv
encode-av1 — AV1 (libaom)
AV1 is the modern royalty-free codec backed by Google, Netflix, Apple, and the rest of the Alliance for Open Media. At equal quality it's roughly 30 % smaller than H.265 and 50 % smaller than H.264. The catch: libaom-av1 is very slow. A 10-minute 1080p clip can take an hour on a typical laptop. For production use, the SVT-AV1 encoder is faster — see the FFmpeg 8 SVT-AV1 optimal settings guide for that path.
- Source:
src/commands/encode-av1.js - FFmpeg encoder:
libaom-av1 - Audio: copied (
-c:a copy) - Container: Matroska (
.mkv)
| Option | Default | Range | Notes |
|---|---|---|---|
--crf <n> | 30 | 0–63 | AV1 uses a 0–63 scale, not 0–51. Quality at 30 ≈ x264 CRF 23 |
--speed <n> | 6 | 0–8 | Higher = faster, lower quality. 0 is reference-quality; 8 is real-time draft |
Note the encoder also gets -b:v 0 automatically — this signals libaom-av1 to honor the CRF value instead of treating it as a soft cap on top of an implicit bitrate.
Default output filename: input-av1.mkv.
$ npx fqmpeg encode-av1 input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 0 -cpu-used 6 -c:a copy input-av1.mkv
For a long-form encode you'll usually drop --speed to 4 or 5 and walk away. Speed 6 is fqmpeg's default because it strikes a reasonable wall-clock balance for short clips.
encode-vp9 — VP9 / WebM
VP9 is Google's pre-AV1 codec. AV1 has eclipsed it for new pipelines, but VP9 still matters in two cases: (1) older browsers and embeds where AV1 hardware decode isn't there yet, and (2) WebM containers, which most browsers prefer for <video> tags when MP4 isn't an option.
- Source:
src/commands/encode-vp9.js - FFmpeg encoder:
libvpx-vp9 - Audio: re-encoded to Opus (
-c:a libopus) — Opus is the canonical audio pairing for VP9 in WebM - Container: WebM (
.webm)
| Option | Default | Range | Notes |
|---|---|---|---|
--crf <n> | 31 | 0–63 | VP9 also uses 0–63. 31 is the libvpx-vp9 documentation's recommended "good" starting point |
--speed <n> | 1 | 0–5 | Lower = better quality in libvpx-vp9. The default 1 is slower but produces better output than 0 (which has known bugs at certain resolutions) |
Like AV1, the command sets -b:v 0 so CRF is the only quality knob.
Default output filename: input-vp9.webm.
$ npx fqmpeg encode-vp9 input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 31 -b:v 0 -cpu-used 1 -c:a libopus input-vp9.webm
Bitrate-Targeted Encoding
bitrate — H.264 with target bitrate (file size control)
When you have a hard size cap — Discord's 25 MB free-tier limit, a CMS that rejects files over X MB, an SLA on bandwidth — CRF doesn't help, because CRF doesn't know about your cap. bitrate lets you pin the video and audio rates explicitly, in normal FFmpeg bitrate notation.
- Source:
src/commands/bitrate.js - FFmpeg encoder:
libx264(same ascompress, just bitrate-mode instead of CRF-mode) - Audio: re-encoded to AAC at the audio bitrate
- Container flag:
-movflags +faststart
| Argument | Default | Notes |
|---|---|---|
<rate> (positional) | required | Target video bitrate. Format: digits + optional k/K/m/M (e.g., 1M, 2500k, 500k, 1000000) |
--audio-bitrate <rate> | 128k | Same format as video bitrate |
The validator rejects malformed rates with a clear error: Error: video bitrate must be a number with optional k/K/m/M suffix (e.g. 1M, 2500k, 500000), got "...".
Default output filename uses the rate as the suffix: input-2M.mp4 for 2M, input-2500k.mp4 for 2500k.
$ npx fqmpeg bitrate input.mp4 2M --dry-run
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -c:a aac -b:a 128k -movflags +faststart input-2M.mp4
To compute the right rate for a given file size cap: size_bits / duration_seconds = total_bitrate. Subtract your audio bitrate, and that's your --video-bitrate. Recipe 2 below shows this in practice.
Editing Codecs: ProRes and DNxHR
These two are different from everything above. They're intermediate codecs — meant for editing on a timeline, not delivery to viewers. Files are 5–10× larger than H.264 at equivalent visual quality, but the encoder is optimized for frame-accurate scrubbing and near-lossless re-encoding across multiple edit passes. If you've ever tried to edit H.264 in Premiere and watched the timeline stutter, this is the fix.
encode-prores — Apple ProRes (Final Cut, Premiere, Resolve)
ProRes is Apple's intermediate codec, and the de-facto standard for Final Cut Pro and DaVinci Resolve workflows. Premiere and Avid handle it well too.
- Source:
src/commands/encode-prores.js - FFmpeg encoder:
prores_ks(the kostya-sampler variant, which produces the most compatible files) - Audio: PCM 16-bit (
-c:a pcm_s16le) — uncompressed, the editing-codec convention - Container: QuickTime (
.mov)
| Option | Default | Allowed | Notes |
|---|---|---|---|
--profile <p> | hq | proxy, lt, standard, hq, 4444 | Internal mapping: proxy → 0, lt → 1, standard → 2, hq → 3, 4444 → 4 |
Profile cheat sheet:
proxy(~45 Mbps at 1080p) — small, fast, draft-edit onlylt(~102 Mbps) — "light," good for offline editstandard(~147 Mbps) — broadcast qualityhq(~220 Mbps) — fqmpeg's default, the typical finishing master4444(~330 Mbps) — adds alpha channel, used for VFX compositing
Default output filename: input-prores.mov.
$ npx fqmpeg encode-prores input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v prores_ks -profile:v 3 -c:a pcm_s16le input-prores.mov
encode-dnxhd — Avid DNxHR (Avid Media Composer workflows)
DNxHR is Avid's intermediate codec — the equivalent of ProRes in the Avid ecosystem. Note the verb name says dnxhd but the codec produced is DNxHR (the resolution-independent successor to legacy DNxHD). The output filename suffix is dnxhr to reflect this.
- Source:
src/commands/encode-dnxhd.js - FFmpeg encoder:
dnxhd(writesdnxhr_*profile via-profile:v) - Audio: PCM 16-bit at 48 kHz mandatory (
-c:a pcm_s16le -ar 48000) — DNxHR/MXF spec doesn't accept 44.1 kHz audio - Container: MXF (
.mxf) — the broadcast professional container
| Option | Default | Allowed | Notes |
|---|---|---|---|
--profile <p> | hq | lb, sq, hq, hqx, 444 | Maps to dnxhr_<profile> on the FFmpeg side |
Profile cheat sheet:
lb(low bandwidth) — proxy / offline editsq(standard quality) — broadcast online edithq(high quality) — fqmpeg's default, finishing master at 8-bit 4:2:2hqx(high quality extended) — 10-bit 4:2:2 for grade-friendly masters444(4:4:4) — adds alpha for compositing, similar to ProRes 4444
Default output filename: input-dnxhr.mxf.
$ npx fqmpeg encode-dnxhd input.mp4 --dry-run
ffmpeg -i input.mp4 -c:v dnxhd -profile:v dnxhr_hq -c:a pcm_s16le -ar 48000 input-dnxhr.mxf
Real-World Recipes
Each of these chains multiple fqmpeg verbs (across clusters) into a real delivery workflow.
Recipe 1: Multi-platform delivery from one master
You have a finished 4K master and need three distribution formats: H.264 for compatibility (web embed, email, Discord paste), AV1 for YouTube (smaller upload, better adaptive bitrate ladder on YouTube's side), and VP9/WebM for a self-hosted <video> tag on a static site.
# Compatibility delivery (H.264 .mp4)
npx fqmpeg compress master-4k.mp4 --crf 22 --preset slow
# YouTube upload candidate (AV1 .mkv) — slow but worth it
npx fqmpeg encode-av1 master-4k.mp4 --crf 28 --speed 4
# Self-hosted web embed (VP9 .webm)
npx fqmpeg encode-vp9 master-4k.mp4 --crf 31
Run all three from the same master and you get master-4k-compressed.mp4, master-4k-av1.mkv, and master-4k-vp9.webm side by side. The slow AV1 encode runs in the background while you do the rest.
Recipe 2: Hit a Discord 25 MB cap
Discord rejects file uploads over 25 MB on the free tier. Goal: encode a 90-second clip to fit under the cap, with 128 kbps audio.
# Step 1: probe the source for duration
npx fqmpeg duration input.mp4
# 0:01:30.000000 → 90 seconds
# Step 2: math
# Budget: 25 MB = 200,000,000 bits = 200,000 kbits
# Reserve audio: 128 kbps × 90 s = 11,520 kbits
# Video budget: 200,000 - 11,520 = 188,480 kbits ÷ 90 s ≈ 2090 kbps
# Round down for safety margin → 1900k
# Step 3: encode
npx fqmpeg bitrate input.mp4 1900k
The duration command is from C12 (Inspection — also available via the hub article). The pattern is general: probe → calculate → encode. For long batches, wrap the math in a shell script.
Recipe 3: Edit-then-deliver pipeline
You have raw 4K phone footage. You want to edit it in Final Cut, then deliver an H.264 .mp4 for YouTube. Direct H.264 → editor → re-encode loses quality on every pass; ProRes intermediate fixes that.
# Step 1: convert raw footage to ProRes for editing
npx fqmpeg encode-prores raw-phone.mp4 --profile lt
# → raw-phone-prores.mov (edit this in Final Cut)
# (Edit in Final Cut, export ProRes timeline as final-edit.mov)
# Step 2: compress the edited timeline export to H.264 for YouTube
npx fqmpeg compress final-edit.mov --crf 20 --preset slow
# → final-edit-compressed.mp4
--profile lt for the proxy keeps file sizes manageable. If you have 4444 footage with alpha (e.g., chroma-key shots), use --profile 4444 instead.
Recipe 4: HDR archive → SDR delivery
Your source is HDR (HLG or HDR10) but you need an SDR delivery for general viewers. Tone-map first, then encode with H.265 for the smaller archive.
# Step 1: tone-map HDR → SDR (C6 cluster, separate verb)
npx fqmpeg hdr-to-sdr hdr-source.mp4
# → hdr-source-sdr.mp4
# Step 2: encode H.265 for archive
npx fqmpeg encode-h265 hdr-source-sdr.mp4 --crf 26 --preset slow
# → hdr-source-sdr-h265.mkv
The hdr-to-sdr verb lives in the C6 color cluster. For the underlying tone-mapping math, see HDR to SDR tonemapping with FFmpeg.
A Note on Hardware Acceleration
All seven verbs default to software encoders (libx264, libx265, libaom-av1, libvpx-vp9, prores_ks, dnxhd). Hardware-accelerated equivalents (NVENC for NVIDIA, QSV for Intel, VideoToolbox for macOS) are dramatically faster but not on the default path because:
- They produce different (often worse) output at matching bitrates than software encoders
- They require a specific GPU + driver match
- Quality knobs aren't 1:1 — NVENC has its own preset/quality scale
If you do need NVENC/QSV, run --dry-run on the verb you want, copy the printed command, and substitute the hardware encoder name (h264_nvenc, hevc_nvenc, h264_qsv, etc.). The GPU encoding guide covers what to add for each vendor.
Frequently Asked Questions
Which codec should I pick for YouTube?
YouTube re-encodes everything you upload, so the goal is to give it the cleanest possible source. AV1 (encode-av1) is currently the best upload format if you have the CPU time — YouTube preserves more quality on AV1 ingest than on H.264. H.264 with CRF 18 and --preset slow is the practical fallback if AV1 takes too long. Avoid uploading bitrate-capped files; YouTube's encoder will compound the loss.
Why does fqmpeg default to CRF instead of bitrate?
CRF lets the encoder allocate bits where they're needed (action scenes get more, static scenes get less), which produces better visual quality at a smaller average size than fixed bitrate for the same content. You only want bitrate mode when you have an external constraint — file size cap, streaming bandwidth — that CRF can't account for. That's exactly what bitrate is for.
Are these commands hardware-accelerated?
No, they default to software encoders. See "A Note on Hardware Acceleration" above for how to drop in NVENC/QSV manually using --dry-run.
Why does encode-h265 default to CRF 28 but compress defaults to CRF 23?
x264 and x265 use different perceptual quality scales — they are not the same number. As a rough rule, CRF 23 in x264 ≈ CRF 28 in x265 for similar visual quality. fqmpeg's defaults match each encoder's documented "good quality" recommendation, not a uniform number across encoders.
Do I need both ProRes and DNxHR?
Pick one based on the editor: ProRes if you're in Final Cut, Premiere, or DaVinci Resolve; DNxHR if you're in Avid Media Composer. They're functionally equivalent intermediate codecs; the choice is ecosystem-driven, not technical.
Can I two-pass encode with bitrate?
bitrate itself is single-pass. For two-pass, use --dry-run to print the command, then run two passes manually: ffmpeg ... -pass 1 -f null /dev/null followed by the same command with -pass 2 output.mp4. For most file-size-cap cases, single-pass is close enough that the extra 30–60 seconds of two-pass aren't worth it.
Why is encode-av1 so slow? Is there a faster path?
libaom-av1 is the reference encoder — correct but slow. The faster production path is SVT-AV1, which is 5–10× quicker at comparable quality. SVT-AV1 isn't a fqmpeg verb yet; for the underlying flags, see FFmpeg 8 SVT-AV1 optimal settings.
Can I batch-process a folder of videos?
Yes — fqmpeg is shell-friendly. The standard pattern is a for loop in bash:
for f in *.mp4; do npx fqmpeg compress "$f" --crf 22; done
Or the equivalent find -exec for nested directories. Each invocation exits with FFmpeg's exit code, so you can chain && or pipe into xargs -P for parallel encoding. For a more structured pipeline (manifests, retries, S3 uploads), the FFmpeg + Python batch automation guide covers a Python-side approach.
Wrapping Up
The seven C1 verbs cover the realistic compression and encoding decisions you'll make:
compressfor "just compress this" — H.264 defaultencode-h265/encode-av1/encode-vp9for codec-specific deliveryencode-prores/encode-dnxhdfor editing intermediatesbitratefor fixed file-size caps
Every verb prints its underlying FFmpeg invocation under --dry-run, so you can copy the command to learn the syntax, drop it into a CI step, or modify it (e.g., swap to NVENC) without re-deriving everything from scratch. For the broader fqmpeg map, return to the fqmpeg complete guide hub.