Handheld footage can be smoothed, and the mechanism explains the trade-off completely: the filter moves each frame to cancel out the camera's movement, which means part of the picture moves outside the frame.
Check the filter exists
ffmpeg -hide_banner -filters | grep vidstab
Stabilisation comes from an optional library, and many distribution builds omit it. If nothing is listed, the filter is not there, which is a build problem instead of a syntax one.
Pass one: analyse
ffmpeg -i shaky.mp4 -vf vidstabdetect=shakiness=5:accuracy=15 -f null -
This produces no video. It reads the whole file and writes transforms.trf describing how the camera moved in every frame.
shakiness runs from 1 to 10 and describes how much movement to expect. accuracy raises the analysis quality and the time it takes.
The file is tied to this exact source. Trim or scale the video and the analysis no longer matches, which is why stabilisation goes first in any chain of operations.
Pass two: correct
ffmpeg -i shaky.mp4 -vf vidstabtransform=smoothing=30:zoom=0:optzoom=1 \ -c:v libx264 -crf 20 -c:a copy stable.mp4
smoothing is the number of frames averaged over. Higher is steadier and less responsive, at very high values a deliberate pan starts to look like a slow drift, because the filter is trying to remove it.
30 is a reasonable start for handheld footage. Reduce it if intentional camera movement is being flattened.
Zoom is the crop
When a frame is shifted, an empty edge appears. optzoom=1 lets the filter work out the minimum zoom that hides the empty areas across the whole video.
That zoom is the cost. The finished video is more cropped and slightly softer, because a smaller area of the original is being enlarged to fill the frame.
Shakier source, more crop. On badly shaken footage the result can lose a noticeable share of the picture, and at that point the honest answer is that the footage is not recoverable to broadcast quality.
If you know in advance that footage will be stabilised, shoot wider than your final framing and let the crop take the margin.
Order matters
Stabilise first, scale afterwards.
ffmpeg -i shaky.mp4 -vf "vidstabtransform=smoothing=30:optzoom=1,scale=1280:-2" \ -c:v libx264 -crf 20 -c:a copy out.mp4
Scaling before stabilising throws away detail the analysis needed, and the analysis file was made against the original dimensions anyway. Understanding FFmpeg filters walks through why chains run left to right.
The one-pass alternative
ffmpeg -i shaky.mp4 -vf deshake -c:v libx264 -crf 20 -c:a copy out.mp4
deshake needs no analysis pass and is noticeably worse. It works on a short window instead of the whole clip, so it removes jitter and leaves drift.
It is useful when processing must be automatic and single-pass. A queue of user uploads, where two passes over every file is not affordable. For anything you will publish, the two-pass route is worth the time.
Rolling shutter
Phone and mirrorless footage often has a wobble where vertical lines lean and bend during movement. Stabilisation does not fix that. It may make it more obvious by holding the frame still while the distortion continues.
That is a separate correction, and if it dominates the footage, stabilisation alone will disappoint.
Cost, and where it belongs
Two full decodes plus the analysis. On long files this is slow, and it is entirely processor-bound.
It belongs in a queue rather than in front of a waiting user, building a batch video processing pipeline goes into the arrangement, and performance optimisation walks through making the encode side faster once the analysis is done.
Judge whether the footage is worth stabilising
Stabilisation crops and softens the picture, so material that is only slightly unsteady is frequently better left alone.
ffmpeg -i in.mp4 -vf "vidstabdetect=shakiness=5:accuracy=15:result=t.trf" -f null - 2>&1 | tail -3 head -5 t.trf
The analysis file records the movement detected per frame. Large values throughout mean genuine camera shake; small ones mean the movement is mostly intentional and correcting it will look wrong.
Footage with deliberate panning is the case to be careful with. Stabilisation resists that motion as well, producing a result where the camera appears to fight the operator.
The crop is the cost, and it is adjustable
Correcting movement means moving the frame, which leaves empty edges that have to be hidden by zooming in.
ffmpeg -i in.mp4 -vf "vidstabtransform=input=t.trf:zoom=0:optzoom=1:smoothing=15" out.mp4 ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 out.mp4
Automatic zoom calculates the minimum needed, which is usually less than a fixed value would be. The smoothing value controls how much movement is removed, and a higher figure requires more crop.
Read the output dimensions against the input. Losing ten per cent is normal; losing a quarter means the smoothing is set higher than the footage justifies.
Two passes are not optional for good results
The single pass alternative exists and produces noticeably worse output, because it corrects without knowing what comes next.
The analysis pass reads the whole file and records the motion. The correction pass uses that complete picture to smooth movement across the entire clip rather than reacting frame by frame.
time ffmpeg -nostdin -i in.mp4 -vf vidstabdetect=result=t.trf -f null - time ffmpeg -nostdin -i in.mp4 -vf vidstabtransform=input=t.trf out.mp4
The first pass is fast because it decodes without encoding. The second is a full encode. Together they take roughly the time of one encode plus a decode, which is the honest cost.
Apply it before anything else in the pipeline
Stabilisation should operate on the original material, not on something already processed.
Correcting after a resize means the analysis was performed on fewer pixels and the result is less accurate. Correcting after a crop means the edges needed for the correction have already been discarded.
ffmpeg -i original.mp4 -vf "vidstabtransform=input=t.trf,scale=1280:-2" -c:a copy out.mp4
Combining both in one filter chain, in that order, does the work once and applies each step to the right input. Running them as separate commands costs two encodes and one generation of quality for no benefit.
Confirm the correction did not introduce worse problems
Stabilised footage can develop artefacts that were not in the source, particularly on material with rolling shutter distortion.
ffmpeg -ss 10 -i out.mp4 -frames:v 1 corrected.png ffmpeg -ss 10 -i in.mp4 -frames:v 1 original.png
Compare the same frame before and after. Straight lines that now bend, or edges that appear to wobble, mean the correction is fighting distortion in the source rather than camera movement.
Where that happens, correcting the distortion first and stabilising afterwards produces a better result than increasing the smoothing, which makes the artefact more pronounced rather than less.
Keep the analysis file with the source
The first pass produces a file describing the movement, and it is specific to that exact input.
ls -la t.trf ffprobe -v error -show_entries format=duration -of csv=p=0 in.mp4
Reusing it against a different file, or against the same file after trimming, produces corrections applied to the wrong frames and a result that is worse than the original.
Name it after the source and delete it once the corrected file is confirmed. A directory of analysis files with no obvious owner is the state that leads to somebody using the wrong one.