How to two-pass video stabilization for the best result
- Step 1Understand what you're trading: time for quality — Two passes mean two full reads of the file plus an encode — roughly double a single-pass filter's time. That's the price of the better, look-ahead-smoothed result. The tool is Pro-tier; Pro allows up to 10 GB per file.
- Step 2Drop the clip — The file loads into FFmpeg.wasm locally — no upload. Both passes run on your CPU in the tab.
- Step 3Pass one runs automatically: vidstabdetect — JAD runs
vidstabdetect=stepsize=6:shakiness=8:accuracy=9over the whole clip and writes a temporary.trfmotion file. There's no visible output from this pass — it's pure analysis. The detect parameters are fixed; you don't set them. - Step 4Set Zoom and Smoothing for pass two — These feed
vidstabtransform. Zoom (0–15, default 5) crops in to hide edge wedges. Smoothing (0–30, default 15) sets the averaging window over the full motion record. Because pass two has the complete record, high Smoothing won't lag the way a single pass would. - Step 5Pass two runs: vidstabtransform + sharpen + encode — JAD runs
vidstabtransform=input=<trf>:zoom=…:smoothing=…,unsharp=5:5:0.8:3:3:0.4, then encodes H.264 (libx264, preset medium, CRF 20) and copies the audio. The.trffile is discarded after the run. - Step 6Download and, if needed, re-tune — Output is H.264 MP4. Because the detect pass already measured everything, re-tuning only changes pass-two parameters — but JAD re-runs both passes each time, so a re-run is a full job, not a quick adjust.
What each pass does
The two-pass pipeline JAD runs. Pass one is analysis; pass two is the visible work.
| Pass | Filter | Reads | Produces | User controls |
|---|---|---|---|---|
| Pass 1 (detect) | vidstabdetect=stepsize=6:shakiness=8:accuracy=9 | Whole clip | Temporary .trf motion-vector file | None (params fixed) |
| Pass 2 (transform) | vidstabtransform=input=trf:zoom=Z:smoothing=S + unsharp | Whole clip + .trf | Stabilised H.264 MP4 | Zoom, Smoothing |
Two-pass vs single-pass deshake
Why JAD uses vidstab two-pass instead of the older one-pass deshake filter.
| Aspect | vidstab two-pass (JAD) | Single-pass deshake (older) |
|---|---|---|
| Motion knowledge | Whole clip measured first | Only what's been seen so far |
| Path smoothing | Global, look-ahead | Reactive, lags real motion |
| Rotation correction | Yes | No (translation only) |
| Quality on irregular shake | Higher | Lower |
| Processing time | ~2× (two passes + encode) | ~1× (one pass) |
Fixed pipeline + tier
Not adjustable. Output is always re-encoded MP4. Pro-tier tool.
| Item | Value |
|---|---|
| Sharpening | unsharp=5:5:0.8:3:3:0.4 (always, in pass two) |
| Output codec / container | H.264 (libx264, preset medium, CRF 20) · MP4 |
| Audio | stream-copied unchanged |
| Temp artifact | .trf motion file (created then discarded) |
| Min tier / size | Pro · 10 GB (100 GB Pro+Media) |
Cookbook
Tuning recipes that exploit the two-pass design. Remember: detect is fixed, so all tuning is in pass two (Zoom + Smoothing).
The full two-pass command JAD runs
This is exactly what happens under the hood when you click run with default settings. Both passes read the file; the .trf bridges them.
# Pass 1 — analyse motion, write transform file
ffmpeg -i in.mov -vf vidstabdetect=stepsize=6:shakiness=8:accuracy=9:result=motion.trf -f null -
# Pass 2 — warp onto smoothed path, sharpen, encode
ffmpeg -i in.mov -vf vidstabtransform=input=motion.trf:zoom=5:smoothing=15,unsharp=5:5:0.8:3:3:0.4 \
-c:v libx264 -preset medium -crf 20 -c:a copy out.mp4Maximum stability the single-pass way can't match
High Smoothing only works well in two-pass, because pass two has the whole motion record to smooth against. A single pass at this strength would lag badly.
Zoom: 9 Smoothing: 28 Why it works here: pass 2 smooths the COMPLETE path, so it locks the shot without the reactive lag a single-pass filter would show at the same strength.
Preserve responsiveness while still two-passing
Two-pass isn't only for locked shots. Keep Smoothing moderate and you still get the data-driven, rotation-aware correction without flattening intentional motion.
Zoom: 5 Smoothing: 12 Gets you: rotation + translation correction from real measured vectors, but pans stay lively. Still better than single-pass at the same Smoothing because of look-ahead.
Why re-tuning re-runs both passes
Adjusting Zoom or Smoothing only changes pass two — but JAD re-runs the whole job, so each tweak is a full two-pass run. Plan a couple of deliberate runs rather than many tiny ones.
Run 1: Zoom 5 / Smoothing 15 (full two-pass) Run 2: Zoom 8 / Smoothing 15 (full two-pass again) Tip: change one variable per run so you can read the effect
Two-pass stabilise, then encode small for delivery
The stabilizer always outputs H.264 at CRF 20. If you need a smaller delivery file or a specific bitrate, encode the stabilised result separately.
Step 1 stabilizer (two-pass) -> steady.mp4 (CRF 20)
Step 2 [video transcoder](/video-tools/video-transcoder)
-> target a smaller size / specific codec
Keeps the quality fix and the delivery encode separateEdge cases and what actually happens
Expecting a quick single adjustment
By designThere's no 'preview then tweak' that reuses the detect pass — every run re-runs both passes. The detect pass can't be cached between runs in the tool, so changing Zoom/Smoothing means a full two-pass job again. Plan deliberate runs, changing one variable at a time.
Detect pass fails (vidstab missing in build)
errorPass one is where vidstab availability is tested. If the build lacks the filter, you'll see Stabiliser detect pass failed (vidstab may not be present in this build) and the job stops before pass two. Retry; if it persists the build can't do two-pass stabilisation.
Transform pass fails after a successful detect
errorIf pass one succeeds but pass two errors, you'll see Stabiliser transform pass failed. This usually points to an encode issue (e.g. an unusual stream the H.264 encoder couldn't handle). Try transcoding the source to a clean H.264 MP4 first with the video transcoder, then stabilise.
Two passes are slow on long/high-res footage
ExpectedTwo full reads plus an encode is inherently ~2× a single-pass filter. There's no duration cap, but a long 4K clip takes real time in FFmpeg.wasm. That's the cost of the better result — trim or resize first if you need speed over native resolution/length.
Detect sensitivity can't be raised for stubborn shake
By designshakiness, accuracy, and step size are fixed in the detect pass. If footage is too shaky for the tuned defaults, you can't crank detection — you can only shape pass two with Zoom and Smoothing, or take extreme cases to a desktop NLE.
Rolling shutter survives both passes
Not fixableNeither pass touches intra-frame distortion. vidstabdetect measures whole-frame motion and vidstabtransform applies whole-frame correction, so rolling-shutter Jello is unaffected. It's outside what two-pass vidstab does.
Output is always H.264 MP4 at CRF 20
By designPass two encodes with libx264 at CRF 20 — you can't choose codec, bitrate, or container in the stabilizer. For a specific delivery target, run the video transcoder or H.265 encoder on the result.
Audio re-encode expected but didn't happen
PreservedBy design, audio is stream-copied (-c:a copy), not re-encoded, across both passes — so it stays bit-identical and in sync. If you needed the audio re-encoded or normalised, do that as a separate step; the stabilizer never touches it.
Free-tier user can't run two-pass
rejectedThe stabilizer requires Pro (minTier: pro). Free users get an upgrade prompt. Pro's 10 GB per-file ceiling covers most clips; Pro+Media raises it to 100 GB for very large files.
Frequently asked questions
Why does vidstab need two passes?
Pass one (vidstabdetect) has to measure the entire clip's motion before pass two (vidstabtransform) can compute a globally smoothed path. With the full motion record, the transform can look ahead and plan — a single pass can only react to motion it's already seen, so it lags and can't smooth as well.
What is the .trf file?
It's the transform file vidstabdetect writes — a record of each frame's measured motion vectors. vidstabtransform reads it in pass two to know how to warp every frame. JAD creates it as a temporary file and discards it after the run.
Is two-pass really better than one-pass deshake?
Yes, meaningfully. Two-pass smooths against the complete motion record (look-ahead, no lag) and corrects rotation, which single-pass deshake can't. The trade is roughly double the processing time for clearly better quality.
Can I tune the detect pass?
No. shakiness, accuracy, and step size are fixed (8, 9, 6). All your tuning happens in pass two via Zoom and Smoothing. The detect defaults are chosen to work across general handheld and action footage.
Does re-tuning skip the detect pass?
No — JAD re-runs both passes on every job. There's no cached detect pass to reuse, so each Zoom/Smoothing change is a full two-pass run. Change one variable per run so you can read the effect.
What sharpening is applied and why?
A fixed unsharp=5:5:0.8:3:3:0.4 in pass two. Warping each frame onto the smoothed path slightly softens the image; the unsharp pass recovers some of that edge detail. It's always on and not adjustable.
What's the output codec and quality?
H.264 via libx264, preset medium, CRF 20 — visually near-lossless for most footage. Audio is stream-copied unchanged. For a smaller file or different codec, transcode the result separately.
Why did my job fail at the detect stage?
The detect pass is where vidstab availability is checked. If the FFmpeg.wasm build lacks the filter you'll see Stabiliser detect pass failed. Retry; if it persists, the build can't do vidstab — it's an environment issue, not your file.
Why did it fail at the transform stage instead?
If detect succeeds but transform fails (Stabiliser transform pass failed), it's usually an encode problem with an unusual source stream. Transcode the source to a clean H.264 MP4 first, then stabilise.
How much slower is two-pass?
Roughly double a single-pass filter, because the file is read fully twice plus encoded once. There's no length cap, only file size (10 GB Pro). For long 4K footage, trim or resize first if speed matters more than native resolution.
Does the two-pass run upload my footage?
No. Both passes run locally in your browser via FFmpeg.wasm. The clip never leaves the tab — no server sees it at any stage.
Does it work on Free tier?
No, it's Pro-only. Free users see an upgrade prompt. Pro allows 10 GB per file; Pro+Media 100 GB; Developer 100 GB with unlimited batch.
Privacy first
Every JAD Video tool runs entirely in your browser via WebCodecs and FFmpeg (WebAssembly). Your video files never leave your device — verified by zero outbound network requests during processing.