TechEarl

How to Crop a Video with ffmpeg

Crop a video with ffmpeg's crop filter: crop=w:h:x:y from the top-left origin, centered crops with in_w/in_h expressions, square crops for social, and cropdetect to strip black bars automatically.

Ishan Karunaratne⏱️ 7 min readUpdated
Share thisCopied
Crop a video with ffmpeg using the crop filter: width:height:x:y from the top-left origin, centered and square crops with in_w/in_h, and cropdetect for black bars.

To crop a video with ffmpeg, run the crop video filter and tell it the output size plus where the crop box sits:

bash
ffmpeg -i in.mp4 -vf "crop=w:h:x:y" -c:a copy out.mp4

crop=w:h:x:y reads as width:height:x-offset:y-offset. The origin (0,0) is the top-left corner of the frame, x grows to the right, y grows downward. So a 500x500 crop anchored at the top-left of a 1920x1080 clip is:

bash
ffmpeg -i in.mp4 -vf "crop=500:500:0:0" -c:a copy out.mp4

The -c:a copy keeps the original audio stream untouched. I add it on every crop because crop is a video filter and ffmpeg will otherwise re-encode the audio for no reason (more on the re-encode below).

Let ffmpeg center the crop

If you give crop only a width and height and omit x:y, ffmpeg centers the box automatically. Internally it sets x = (in_w - out_w) / 2 and y = (in_h - out_h) / 2, which is exactly what you want most of the time:

bash
# 1280x720 cut from the middle of the frame
ffmpeg -i in.mp4 -vf "crop=1280:720" -c:a copy out.mp4

That covers the common case where you are trimming the edges off symmetrically and do not care about the exact offsets.

Crop relative to the input size with expressions

Hardcoding pixel values means redoing the math for every source resolution. The crop filter exposes the input dimensions as variables, so you can express the crop in terms of the frame instead. The two you reach for constantly are in_w (the input width, aliased iw) and in_h (the input height, aliased ih).

To shave 100px off the left and right (200px total) while keeping full height:

bash
ffmpeg -i in.mp4 -vf "crop=in_w-200:in_h" -c:a copy out.mp4

Because x:y are omitted the remaining strip stays centered, so you lose 100px from each side. The same idea trims top and bottom with crop=in_w:in_h-200. These commands work on a 720p clip and a 4K clip without edits, which is the whole point of writing them relative to in_w/in_h.

Crop to a square for social

Instagram and a lot of social embeds want a 1:1 square. The cleanest way to get one is to crop to the height (the shorter dimension on a landscape video) and let ffmpeg center it:

bash
# Square crop, centered, sized to the frame height
ffmpeg -i in.mp4 -vf "crop=in_h:in_h" -c:a copy out.mp4

For a fixed aspect ratio rather than a square, drive the height off the width. A centered 16:9 crop is:

bash
ffmpeg -i in.mp4 -vf "crop=in_w:in_w*9/16" -c:a copy out.mp4

If you need a specific area and not a centered one, find the offsets first. Open the clip in a player, note the pixel coordinates of the top-left corner of the region you want, and feed them as x:y. There is no preview in ffmpeg itself, so I usually crop once, eyeball the result, and nudge x/y by a few dozen pixels until it lands.

Strip black bars automatically with cropdetect

When a video has letterbox or pillarbox black bars, you do not have to measure them. The cropdetect filter scans the frames and prints a suggested crop=... string to the log. It is a metadata filter, so it does not change the video; it just reports what it would crop:

bash
ffmpeg -i in.mp4 -vf cropdetect -f null -

The -f null - discards the output (you only want the analysis). Watch the log and you will see lines ending in something like crop=1920:800:0:140. Let it run over a chunk of the video so it settles on a stable value, then copy that string into a real crop pass:

bash
ffmpeg -i in.mp4 -vf "crop=1920:800:0:140" -c:a copy out.mp4

cropdetect detects black borders by default; on a clip where the bars are not pure black you can loosen its threshold, but the default works for standard letterboxing.

Cropping always re-encodes the video

There is one expectation to reset. You cannot pair a crop with -c:v copy. Stream copy (-c copy) muxes the existing compressed frames straight through without decoding them, and a filter like crop has to decode each frame, modify the pixels, and encode them again. So a crop is always a video re-encode, which means it takes real time and you should set the quality:

bash
ffmpeg -i in.mp4 -vf "crop=1280:720" -c:v libx264 -crf 18 -preset medium -c:a copy out.mp4

-crf 18 is visually near-lossless for libx264 (lower is higher quality; the sane range is roughly 18 to 28). The audio still gets -c:a copy because cropping never touches the audio. This is the difference from a trim: a trim with -ss/-t and -c copy can be instant and lossless because it cuts on keyframes without decoding, whereas a crop cannot.

Crop and scale in one pass

Often you crop to a region and then want it at a specific output size. Chain crop and scale in the same filter graph with a comma so ffmpeg decodes once:

bash
# Crop a centered square, then downscale it to 1080x1080
ffmpeg -i in.mp4 -vf "crop=in_h:in_h,scale=1080:1080" -c:v libx264 -crf 18 -c:a copy out.mp4

Order matters: crop first to pick the region, then scale to resize it. Running them as one filter chain is faster and avoids a second generation-loss encode you would get from cropping to a file and scaling that file.

For the rest of the command syntax (trimming, converting, muting, rotating), the ffmpeg command cheat sheet collects the canonical 2026 forms in one place.

FAQ

See also

Sources

Authoritative references this article was fact-checked against.

Tagsffmpegcrop videocrop filtercropdetectCLIvideo editingLinux

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

How to Reverse a Video with ffmpeg

Reverse a video with ffmpeg using the reverse filter for picture and areverse for sound. Why you must write to a new output file, and why you trim before you reverse.

How to Trim or Cut a Video with ffmpeg

Trim or cut a video from the command line with ffmpeg: the fast lossless -c copy way, the keyframe gotcha that makes your cut land early, and the frame-accurate re-encode. With -ss and -to/-t explained.

How to Extract Audio From a Video with ffmpeg

Pull the audio out of a video with ffmpeg: copy the stream untouched when you just want to demux (fast, lossless), or re-encode to MP3, AAC, or WAV when you need a different format. Plus how to check the source codec first and grab a single segment.