FFmpeg CLI Cheat Sheet¶
This page is for users who already know the ffmpeg command line and want to
find the equivalent SPDL knob quickly.
It assumes you know the basics of spdl.io — that demuxing is done with
spdl.io.demux_audio() / spdl.io.demux_video() /
spdl.io.demux_image(), decoding with spdl.io.decode_packets(),
and encoding/muxing with spdl.io.Muxer. Rather than re-explaining the
pipeline, this page maps the customization surfaces — the configuration
objects and the filter-description builders — onto the ffmpeg flags you
already know.
The page is a sequence of per-config tables. In each table:
Attribute shows the config attribute with a representative non-default value (this page is about non-default behavior).
FFmpeg shows the matching
ffmpegflag, with the same value.Note appears only when the mapping is non-obvious.
Each table is followed by a worked example: a partial ffmpeg command and the
equivalent spdl.io snippet. All snippets assume import spdl.io and use
the factory functions directly.
DemuxConfig — demux_config(...)¶
Pass the result as demux_config= to a demux_* function.
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Input format override (e.g. for headerless raw PCM). |
|
|
Dict of demuxer / |
|
(no CLI equivalent) |
SPDL I/O buffer tuning. |
Example
ffmpeg -f s16le -probesize 1M -i sample.raw ...
packets = spdl.io.demux_audio(
"sample.raw",
demux_config=spdl.io.demux_config(
format="s16le",
format_options={"probesize": "1M"},
),
)
DecodeConfig — decode_config(...)¶
Pass the result as decode_config= to spdl.io.decode_packets().
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Software decoder name. |
|
|
Codec-private options; values must be strings. |
Example
ffmpeg -c:v libopenh264 -threads 0 -i input.mp4 ...
packets = spdl.io.demux_video("input.mp4")
frames = spdl.io.decode_packets(
packets,
decode_config=spdl.io.decode_config(
decoder="libopenh264",
decoder_options={"threads": "0"},
)
)
VideoEncodeConfig — video_encode_config(...)¶
Pass the result to
Muxer.add_encode_stream.
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Required. |
|
|
Pixel format of the frames fed to the encoder. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example
ffmpeg ... \
-s 1280x720 \
-pix_fmt yuv420p \
-r 30 \
-b:v 4M \
-g 60 \
-bf 2 \
-colorspace bt709 \
-color_primaries bt709 \
-color_trc bt709 \
out.mp4
cfg = spdl.io.video_encode_config(
width=1280, height=720,
pix_fmt="yuv420p",
frame_rate=(30, 1),
bit_rate=4_000_000,
gop_size=60,
max_b_frames=2,
colorspace="bt709",
color_primaries="bt709",
color_trc="bt709",
)
AudioEncodeConfig — audio_encode_config(...)¶
Pass the result to
Muxer.add_encode_stream.
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Required. |
|
|
Required. |
|
|
|
|
|
|
|
|
|
|
|
Example
ffmpeg ... -ac 2 -ar 48000 -sample_fmt fltp -b:a 192k out.m4a
cfg = spdl.io.audio_encode_config(
num_channels=2,
sample_rate=48000,
sample_fmt="fltp",
bit_rate=192_000,
)
Encoder selection — Muxer.add_encode_stream(...)¶
The encode config above describes what to produce; the encoder and its private
options are chosen on Muxer.add_encode_stream.
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
See |
|
|
Encoder-private options; see |
Example
ffmpeg ... -c:v libx264 -preset fast -crf 23 out.mp4
muxer.add_encode_stream(
spdl.io.video_encode_config(
width=1280,
height=720,
pix_fmt="yuv420p",
frame_rate=(30, 1),
),
encoder="libx264",
encoder_config={
"preset": "fast",
"crf": "23",
},
)
Output container — Muxer(...) / Muxer.open(...)¶
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Output format / device override. |
|
|
Dict of muxer options. |
Example
ffmpeg ... -f mp4 -movflags +faststart out.mp4
muxer = spdl.io.Muxer("out.mp4", format="mp4")
muxer.add_encode_stream(...)
with muxer.open(muxer_config={"movflags": "+faststart"}):
...
Video filters — get_video_filter_desc(...)¶
spdl.io.get_video_filter_desc() builds a filter-graph string that is
passed as filter_desc= (raw libavfilter syntax, ≈ -vf). The Note
column shows the filter the attribute is emitted as.
Attribute |
FFmpeg |
Note (emitted as) |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
Center crop. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Color used when padding to |
|
extra |
Escape hatch; appended verbatim. |
Example
ffmpeg -i in.mp4 \
-vf "fps=30/1,trim=start=1.5:end=4.0,scale=w=256:h=256:flags=bicubic:force_original_aspect_ratio=decrease,pad=w=256:h=256:x=-1:y=-1:color=black,crop=w=224:h=224,tpad=stop=-1:stop_mode=clone,trim=end_frame=16,format=pix_fmts=rgb24" \
out.mp4
filter_desc = spdl.io.get_video_filter_desc(
timestamp=(1.5, 4.0),
scale_width=256,
scale_height=256,
scale_algo="bicubic",
crop_width=224,
crop_height=224,
frame_rate=(30, 1),
pix_fmt="rgb24",
num_frames=16,
)
# creates
# "fps=30/1,trim=start=1.5:end=4.0,scale=w=256:h=256:flags=bicubic:force_original_aspect_ratio=decrease,pad=w=256:h=256:x=-1:y=-1:color=black,crop=w=224:h=224,tpad=stop=-1:stop_mode=clone,trim=end_frame=16,format=pix_fmts=rgb24"
# Use it when decoding. Providing timestamp to demuxer reduces the amount of processing:
packets = spdl.io.demux_video("in.mp4", timestamp=(1.5, 4.0))
frames = spdl.io.decode_packets(packets, filter_desc=filter_desc)
Audio filters — get_audio_filter_desc(...)¶
spdl.io.get_audio_filter_desc() builds a filter-graph string passed as
filter_desc= (≈ -af). The filters are emitted in a fixed order —
num_channels → sample_rate → timestamp → num_frames → your
custom filter_desc → sample_fmt — so the sample-format conversion is
always applied last.
Attribute |
FFmpeg |
Note (emitted as) |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extra |
Escape hatch; appended verbatim. |
Example
ffmpeg -i in.wav \
-af "aformat=channel_layouts=1c,aresample=16000,atrim=start=0.0:end=10.0,volume=0.5,aformat=sample_fmts=fltp" \
out.wav
filter_desc = spdl.io.get_audio_filter_desc(
timestamp=(0.0, 10.0),
sample_rate=16000,
num_channels=1,
sample_fmt="fltp",
filter_desc="volume=0.5",
)
# creates
# "aformat=channel_layouts=1c,aresample=16000,atrim=start=0.0:end=10.0,volume=0.5,aformat=sample_fmts=fltp"
# Use it when decoding. Providing timestamp to demuxer reduces the amount of processing:
packets = spdl.io.demux_audio("in.wav", timestamp=(0.0, 10.0))
frames = spdl.io.decode_packets(packets, filter_desc=filter_desc)
Complex filter graphs — FilterGraph¶
The builders above produce linear chains — one input, one output — passed as
filter_desc=. For graphs with multiple inputs or outputs (FFmpeg’s
-filter_complex), use spdl.io.FilterGraph directly.
The key difference: ffmpeg adds the source and sink pads implicitly (from
-i and -map). With FilterGraph you spell them out — buffer /
abuffer source nodes and buffersink / abuffersink sink nodes — built
with spdl.io.get_buffer_desc() / spdl.io.get_abuffer_desc().
FFmpeg |
spdl.io |
|---|---|
|
|
input pads |
explicit |
feeding each input |
|
link labels |
identical |
output pad + |
named sink |
Example — side-by-side stack of two inputs
ffmpeg -i left.mp4 -i right.mp4 -filter_complex "[0:v][1:v]hstack" out.mp4
# Spell out the source/sink nodes that ffmpeg adds implicitly:
codec = spdl.io.Demuxer("left.mp4").video_codec
buf0 = spdl.io.get_buffer_desc(codec, label="in0")
buf1 = spdl.io.get_buffer_desc(codec, label="in1")
filter_desc = f"{buf0} [in0];{buf1} [in1],[in0] [in1] hstack,buffersink"
fg = spdl.io.FilterGraph(filter_desc)
fg.add_frames(left_frames, key="buffer@in0")
fg.add_frames(right_frames, key="buffer@in1")
stacked = fg.get_frames()
See also
Advanced Filter Graphs — the full guide to multi-input / multi-output graphs, streaming, and audio-to-video (multimedia) filters.
CUDAConfig — cuda_config(...)¶
Used to select the GPU (and CUDA stream / allocator) for transfer and hardware decoding.
Attribute |
FFmpeg |
Note |
|---|---|---|
|
|
Which GPU. |
|
(no CLI equivalent) |
SPDL-specific (CUDA stream handle). |
|
(no CLI equivalent) |
SPDL-specific (custom allocator/deleter). |
Example
ffmpeg -hwaccel cuda -hwaccel_device 1 -i in.mp4 ...
device_config = spdl.io.cuda_config(device_index=1)
NVDEC / nvJPEG — not a 1:1 of *_cuvid¶
Warning
spdl.io.decode_packets_nvdec(), spdl.io.nvdec_decoder(), and
spdl.io.decode_image_nvjpeg() are SPDL’s own NVDEC / nvJPEG
integrations — not wrappers over FFmpeg’s h264_cuvid / hevc_cuvid /
mjpeg_cuvid. The flags below are the closest analogues for intent only;
the color conversion, scaling resampler, and post-processing differ, so output
will not be byte-exact. These APIs are also experimental.
decode_packets_nvdec(...) / nvdec_decoder(...):
Attribute |
FFmpeg analogue |
Note |
|---|---|---|
|
|
|
(decoder implicit from codec) |
|
Not user-selectable. |
|
output of internal CSC |
|
|
|
Intent only. |
|
|
Intent only. |
Example
# Closest FFmpeg analogue — not byte-exact:
ffmpeg -hwaccel cuda -hwaccel_device 0 -c:v h264_cuvid -i in.mp4 \
-vf "crop=iw-16:ih-16:8:8,scale_cuda=224:224,format=rgb24" out.mp4
buffer = spdl.io.decode_packets_nvdec(
packets,
device_config=spdl.io.cuda_config(device_index=0),
pix_fmt="rgb",
scale_width=224, scale_height=224,
crop_left=8, crop_top=8, crop_right=8, crop_bottom=8,
)
decode_image_nvjpeg(...):
Attribute |
FFmpeg analogue |
Note |
|---|---|---|
|
|
|
(codec implicit nvJPEG) |
≈ |
Different implementation. |
|
|
|
|
output color format |
Example
ffmpeg -hwaccel cuda -c:v mjpeg_cuvid -i in.jpg \
-vf "scale_cuda=256:256,format=rgb24" out.png
buffer = spdl.io.decode_image_nvjpeg(
"in.jpg",
device_config=spdl.io.cuda_config(device_index=0),
scale_width=256, scale_height=256,
pix_fmt="rgb",
)
Deliberately not mapped¶
-vsync/-async/-itsoffset/-shortest— timing is handled per-stream via filter graphs and theptson reference frames.Anything beyond demux + decode + filter + encode + mux —
spdl.iois a data-loading library, not a full transcoder.