The FFmpeg Flags That Actually Matter for WebP
A flag-by-flag guide to the libwebp encoder options that change your output — with file-size numbers and the tradeoffs spelled out.
The minimum invocation that works
You can convert any image or short video clip to WebP with a single command:
ffmpeg -i input.mp4 output.webpThat is the entire command. ffmpeg detects the output format from the .webp extension, selects the libwebp encoder automatically, and applies its defaults: quality 75, no looping, compression level 4, method 4. Audio is silently dropped because WebP has no audio track concept.
The defaults are reasonable for a quick test but rarely what you want in production. Quality 75 with default compression is a sensible middle ground, but it leaves performance on the table. You have no loop control, no content-type hint, and the encoder effort is set to a balanced midpoint rather than to whatever your workload actually needs. Every section below covers one of the flags that moves the needle — either on file size, on visual quality, or on how long the encode takes.
Start here, then add flags one at a time as you understand what each one does. A command you understand is easier to tune than one you copied from a Stack Overflow answer.
-c:v libwebp vs -c:v libwebp_anim
ffmpeg ships two WebP encoders and they are not interchangeable. libwebp handles single-frame WebP images and also produces animated WebP when the source has multiple frames — a GIF, a multi-frame input, or a video. libwebp_animis a separate encoder wired to Google's animated-WebP mux API and was designed specifically for the animated case.
In practice, libwebp covers the vast majority of use cases. It handles video-to-animated-WebP conversions correctly, respects the -loop flag, and produces files that play in all browsers. The ffmpeg encoder documentation at ffmpeg.org/ffmpeg-codecs.html#libwebp lists both encoders with their full flag sets.
libwebp_anim becomes relevant when you need explicit control over per-frame metadata, mixed lossy/lossless frames within a single file, or when you are writing a tool that calls the libwebp C API directly. For shell-based video conversion workflows, it offers no practical advantage.
You can confirm which encoders your build of ffmpeg includes by running ffmpeg -encoders | grep webp. Both appear as V.....Sin the output — video, no audio, supports slices. If only one is listed, your distribution did not compile in both. Homebrew's ffmpeg formula includes both by default.
-quality 0..100 and the response curve
-qualityis the flag you will reach for most often. It maps directly to the WebP encoder's quality parameter, which controls the quantization step in the DCT-based lossy path. The default is 75. The range is 0 to 100, where 100 is near-lossless (still lossy — use -lossless 1 for true lossless).
# Compare quality settings on the same source
ffmpeg -i input.mp4 -c:v libwebp -quality 50 -loop 0 out-q50.webp
ffmpeg -i input.mp4 -c:v libwebp -quality 75 -loop 0 out-q75.webp
ffmpeg -i input.mp4 -c:v libwebp -quality 85 -loop 0 out-q85.webpThe response curve is not linear. Quality improvements between 0 and 60 are dramatic — each 10-point increment visibly reduces banding and block artifacts. From 60 to 85 the gains become subtler: you are buying smoother gradients and sharper edges in fine-detail areas. Above 85, file size grows steeply while the visible improvement shrinks to near-nothing for typical web content. Google's WebP study data, available at developers.google.com/speed/webp/docs/webp_study, shows WebP consistently outperforming JPEG at equivalent perceptual quality scores, with the gap widest in the 65–80 quality range.
| Quality | Size vs Q75 baseline | Visible artifacts | Typical use |
|---|---|---|---|
| 20–40 | −65% to −45% | Heavy banding, block edges | Thumbnails, placeholders |
| 50 | −40% | Visible in smooth gradients | Tight bandwidth budgets |
| 75 (default) | baseline | Imperceptible for most content | General web use |
| 85 | +35% | Imperceptible | Hero images, product shots |
| 95+ | +120% or more | None | Archival or pre-press only |
For animated WebP from video, 75–80 is the reliable sweet spot. Go to 85 for stills or animations with large flat-color areas where banding is visible. Going below 60 is almost never the right trade — if you need the file that small, you are better off cutting frame rate or resolution. See optimal WebP conversion settings for a breakdown by content type and use case.
-compression_level (encoder effort, no quality change)
-compression_level runs from 0 to 6, with a default of 4. Unlike -quality, it does not change the visual output — it controls how hard the encoder works to find an efficient bitstream at the quality setting you specified. A higher level means the encoder tries more candidate transforms, spends more time on entropy coding, and produces a smaller file. The decode cost stays the same regardless of what level was used during encode.
The tradeoff is pure encode time. Going from level 4 to level 6 typically adds 30–60% to the encode duration on a multi-frame input. The file-size gain is usually 5–12% — meaningful at scale, marginal for one-off conversions.
The practical rule is straightforward: use 6 in batch jobs and CI pipelines where files are encoded once and served many times. Use 4 (or lower) in interactive tools where users are waiting for a result. Use 0 only when encode speed is the single bottleneck and you are willing to accept 10–15% larger files.
-compression_level and -method (below) overlap in function but operate at different layers of the encoder. Set both together for full control.
-method 0..6 (the unsung knob)
-method sets how aggressively the encoder searches for compression opportunities at the transform and prediction stage — before entropy coding runs. Method 0 uses the fastest, least exhaustive search. Method 6 tries every candidate transform and picks the winner. The default is 4.
# Method comparison — same quality 80, different search effort
ffmpeg -i input.mp4 -c:v libwebp -quality 80 -method 0 -loop 0 out-m0.webp
ffmpeg -i input.mp4 -c:v libwebp -quality 80 -method 4 -loop 0 out-m4.webp
ffmpeg -i input.mp4 -c:v libwebp -quality 80 -method 6 -loop 0 out-m6.webpFor lossy WebP at quality 75–85, the file-size difference between method 4 and method 6 is typically 4–8%. For lossless WebP the gap is larger — 10–20% — because the lossless path relies more heavily on transform selection to achieve compression. If you are encoding lossless WebP in a pipeline where file size matters, method 6 is almost always worth the extra encode time.
On a concrete example: a 3-second 720p clip at quality 80, encoded with method 0 produces a 1.4 MB file in about 4 seconds. The same clip at method 6 produces a 1.28 MB file and takes about 11 seconds. That 8% size reduction translates to measurable bandwidth savings when the file is served millions of times.
-method is documented in the libwebp source at the WebPConfig.method field — see the libwebp encode.h header for the underlying semantics.
-preset shortcuts
libwebp ships six named presets that tune the encoder's internal parameters for different content types: default, picture, photo, drawing, icon, and text. Each preset adjusts the entropy coder weights and filter sharpness — not the quality or method values, which you still control explicitly.
picture is tuned for natural-scene photographs: smooth gradients, organic textures, continuous tone. It softens the filter to preserve tonal transitions. photo targets images captured by cameras, similar to picture but optimized for stronger textures and sharper edges. drawing and icon target synthetic graphics: flat fills, hard edges, limited palette. They sharpen the filter and lean on geometric prediction modes. text is specialized for rendered type — it treats near-white regions aggressively and protects edge contrast.
For animated WebP from video footage, use picture or default. For UI animation exports with flat colors, try icon. The preset name goes directly after the flag:
ffmpeg -i input.mp4 -c:v libwebp -quality 80 -preset picture -loop 0 output.webpPresets are a lightweight first step when you are not sure how to tune the encoder for a new content type. Start with a preset, measure the result, then override individual flags from there.
-loop, -lossless, alpha handling
Loop control. -loop 0 means the animation loops forever — this is what you want for web use. -loop 1 plays the animation once and stops on the last frame. Higher integers loop that many times. Without the flag, ffmpeg defaults to no loop (equivalent to -loop 1), which surprises most people the first time they open the output file and it stops after a single pass. Always set -loop 0 explicitly for any animated WebP you intend to embed as a looping graphic.
Lossless mode. -lossless 1 switches the encoder from the DCT-based lossy path to the lossless predictor path. The -quality value is ignored when lossless is active. Lossless WebP files are substantially larger than lossy at equivalent visual quality — for photographic content, expect 2–4× the size. Lossless makes sense for source assets, screenshots with text, or graphics where pixel-perfect accuracy matters. For web delivery of animated content, lossy at quality 80–85 produces smaller files with imperceptible quality loss.
Alpha channels. libwebp handles transparency automatically. If the source has an alpha channel — a PNG with transparency, or a video with alpha (ProRes 4444, MOV with alpha) — the encoder preserves it without any extra flag. The alpha channel is always encoded losslessly, even when the RGB data uses the lossy path. This means files with alpha are larger than their fully-opaque equivalents.
If you want to strip alpha and convert to an opaque WebP — saving the extra data when transparency is not needed — use the pixel format filter: -vf format=rgb24. This tells ffmpeg to drop the alpha plane before the WebP encoder sees the frame. For the full animated WebP workflow this connects to, see how to convert video to animated WebP.
A real-life conversion script from start to finish
The flags above are more useful together than in isolation. Here is a production-grade three-stage script: trim, scale and set frame rate, then encode. Each stage is a separate ffmpeg call so you can inspect intermediates and re-run just the last stage when you are tuning encode settings.
#!/usr/bin/env bash
set -euo pipefail
SOURCE="$1" # input file (mp4, mov, etc.)
OUT="$2" # output filename (must end in .webp)
QUALITY="-77" # optional quality override, default 80
# ── Stage 1: Trim ──────────────────────────────────────────────────────────
# Adjust -ss and -to to the segment you want.
# Input-side seek (-ss before -i) is fast but keyframe-aligned.
ffmpeg -ss 00:00:01.0 -to 00:00:06.0 -i "$SOURCE" \
-c copy /tmp/trimmed.mp4 -y
# ── Stage 2: Scale + fps ────────────────────────────────────────────────────
# scale=640:-2 → 640px wide, height rounded to nearest even number
# fps=20 → 20 frames per second, smooth enough for most animations
ffmpeg -i /tmp/trimmed.mp4 \
-vf "fps=20,scale=640:-2" \
-c copy /tmp/scaled.mp4 -y
# ── Stage 3: Encode to WebP ─────────────────────────────────────────────────
# -c:v libwebp explicit encoder
# -quality perceptual quality 0–100
# -compression_level 6 maximum encoder effort (slower, smaller)
# -method 6 maximum transform search (slower, smaller)
# -preset picture content-type hint for natural video frames
# -loop 0 infinite loop
# -an drop audio (WebP has no audio track)
ffmpeg -i /tmp/scaled.mp4 \
-c:v libwebp \
-quality "$QUALITY" \
-compression_level 6 \
-method 6 \
-preset picture \
-loop 0 \
-an \
"$OUT" -y
echo "Done: $OUT ($(du -sh "$OUT" | cut -f1))"
rm /tmp/trimmed.mp4 /tmp/scaled.mp4The script takes three arguments: the source file, the output path, and an optional quality value. Stage 1 cuts the clip before any expensive decoding happens. Stage 2 downsizes and reduces frame rate — two changes that have more impact on file size than any encoder flag. Stage 3 runs the actual WebP encode with the full set of quality and effort flags.
The -compression_level 6 and -method 6 combination produces the smallest possible lossy file at the given quality. For a 5-second 640px clip this encode takes 15–25 seconds on a modern laptop — acceptable for a batch job, too slow for an interactive UI. Drop both to 4 if you are building a tool where users wait for results.
For content type guidance — when to use quality 75 vs 85, and how frame rate interacts with file size — see optimal WebP conversion settings. If you prefer a browser-based tool that handles trimming, scaling, and encoding without installing ffmpeg, try the 2WebP converter.