How to Crop a Video with FFmpeg and the RenderIO API

September 4, 2026 · RenderIO

You've finished the 16:9 master, approved the edit, and then distribution asks for vertical and square versions before the day is over. Dragging a crop box in an editor can produce one acceptable export, but it doesn't give your team a repeatable way to regenerate every version when the master changes.

The reliable approach starts with geometry, not a user interface. Define the rectangle you want to retain, test how that rectangle affects the subject and overlays, then move the exact FFmpeg arguments into a hosted processing workflow. That gives you source-relative crops for 9:16, 4:5, and 1:1 outputs without repeatedly opening the project or recompressing the master.

For broader editing context, teams can also find video production tutorials covering the surrounding production workflow. Here, the focus is narrower and more operational: how to crop a video with FFmpeg, decide when padding is safer, and submit the same commands to a REST API.

Table of Contents

The Crop Problem You Are Actually Trying to Solve

A finished video contains more than pixels. It contains a composition, a subject position, captions, lower-thirds, logos, and assumptions about where viewers will look. A 16:9 master may work perfectly on a wide player, yet the same frame can lose a face or cut through a subtitle when converted to a tall mobile canvas.

Treat the task as two connected problems:

  1. Geometry: choose a rectangle with the target aspect ratio and position it correctly over the source.
  2. Pipeline execution: make that rectangle reproducible across exports, teammates, source revisions, and delivery channels.

Modern social guidance commonly uses 9:16 for short-form video, corresponding to 1080×1920 pixels, while 16:9 remains common for long-form video and 1:1 or 4:5 can serve as compromise formats across feeds. The same master therefore needs different crop decisions for different destinations, as outlined in current social-media aspect-ratio guidance.

Start with the deliverable, not the crop handle

Write down the output contract before touching FFmpeg:

  • TikTok and short-form vertical outputs: use a 9:16 crop when the frame can hold the subject.
  • Feed-oriented portrait output: use 4:5 when you want more vertical presence without removing as much horizontal context.
  • Square preview or feed asset: use 1:1 when the composition remains legible after side cropping.
  • Horizontal master: preserve the original 16:9 file as the source of truth.

The crop should be source-aligned, not merely centered by default. A centered rectangle is a useful first test, but it may fail when the speaker stands on one side, when a product sits near an edge, or when captions occupy the lower portion of the frame.

Practical rule: Keep the master untouched. Store the crop expression beside the job definition so every revision can reproduce the same framing.

That separation prevents a common production trap: exporting a cropped file, cropping it again, and gradually degrading the image through unnecessary encode cycles. Build each derivative from the original master instead.

Understanding the FFmpeg Crop Filter

FFmpeg's crop filter is a rectangle operation on the decoded video frame. Its syntax is:

crop=w:h:x:y

The first two values define the retained width and height. The last two define the rectangle's top-left origin, measured from the top-left corner of the input frame. If x:y is omitted, FFmpeg centers the crop, which is convenient for symmetrical footage but not reliable for off-axis subjects.

A command that takes the right half of a source frame looks like this:

ffmpeg -i input.mp4 -filter:v "crop=in_w/2:in_h:in_w/2:0" -c:a copy output.mp4

Here, in_w/2 retains half the input width, in_h keeps the full height, and in_w/2:0 starts the rectangle halfway across the source. The -filter:v option applies the video filter, while -c:a copy keeps the audio stream without an unnecessary audio encode.

For a vertical pillar taken from the left edge of a source, use a source-relative expression:

ffmpeg -i input.mp4 -filter:v "crop=ih*9/16:ih:0:0" -c:a copy vertical-left.mp4

The width is calculated from the input height, so the retained rectangle has a 9:16 aspect ratio regardless of whether the source is small, high resolution, or delivered at another pixel size. FFmpeg's crop geometry and relative-expression behavior are documented in this FFmpeg crop filter guide.

Why source-relative expressions matter

Absolute coordinates work for one known input. They become fragile when a camera changes resolution or an upstream transcode produces a different frame size. Expressions using iw, ih, in_w, and in_h describe the relationship between the crop and the source, so the same filter can travel through different jobs.

To center a crop, calculate the unused horizontal space and divide it between both sides:

crop=ih*9/16:ih:(iw-ih*9/16)/2:0

The crop width is ih*9/16, and the x-origin centers that width within the input. You can use ow in related expressions after the output width has been established, but spelling out the geometry often makes debugging easier for a teammate reading the command.

Hard cuts are a separate concern. The crop filter changes the frame geometry, but it doesn't decide where edits occur. If you're cutting at a specific point, place the trim or seek logic deliberately and validate keyframe behavior before assuming a frame-accurate result. Put the video filter before the output file and keep audio handling explicit.

For a wider explanation of running these commands in FFmpeg workflows, see RenderIO's FFmpeg usage guide.

Cropping for TikTok, Reels, and Shorts

The safest starting point is to derive the crop from the source height. That makes the expression independent of the input's absolute resolution and preserves the target aspect ratio.

For a 9:16 crop from a horizontal source, use a centered expression:

ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih:(iw-ih*9/16)/2:0" -c:a copy vertical.mp4

If the action sits on the left third, shift the crop toward the left:

ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih:0:0" -c:a copy vertical-left.mp4

If the important subject is on the right, anchor the crop at the right edge:

ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih:iw-ih*9/16:0" -c:a copy vertical-right.mp4

For a 4:3 source where the desired action is near the right edge, retain the rightmost 9:16-compatible region with:

ffmpeg -i input.mp4 -vf "crop=iw-(ih*9/16):ih:0:0" -c:a copy vertical-source.mp4

That expression needs careful review because the available source width and target width must support the intended geometry. Don't trust a syntactically valid command until you inspect the output.

4:5 and 1:1 expressions

A 4:5 portrait crop derived from the full source height uses a crop width of ih*4/5. Center it with:

ffmpeg -i input.mp4 -vf "crop=ih*4/5:ih:(iw-ih*4/5)/2:0" -c:a copy portrait.mp4

A centered square crop is simpler:

ffmpeg -i input.mp4 -vf "crop=ih:ih:(iw-ih)/2:0" -c:a copy square.mp4

These examples use iw and ih, so they adapt to the source dimensions. For a moving subject, a static crop may still be insufficient. You'll need either a deliberate anchor chosen for the whole shot or a separate reframe strategy that changes the x-origin over time.

FFmpeg may calculate fractional dimensions from expressions. Encoders commonly behave better with even dimensions, so use truncation and even-up modifiers when your pipeline produces odd values. A typical pattern is:

crop=trunc(ih*9/16/2)*2:trunc(ih/2)*2:(iw-ow)/2:0

Test the expression against the actual source because the relationship between ow, the crop width, and the x-origin should remain clear to everyone maintaining the pipeline.

Keep captions away from platform interfaces

A crop can preserve the subject while still making the export unusable. Hard-coded captions, logos, and lower-thirds may sit close to an edge that was safe in a wide format but exposed to mobile interface overlays after reframing. Guidance on caption and crop video workflows is useful when reviewing these interactions.

If you need breathing room around the cropped image, chain pad after crop:

ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih:(iw-ih*9/16)/2:0,pad=iw:ih+120:0:60:color=black" -c:a copy vertical-padded.mp4

The exact margin should come from your design and caption review, not a guessed universal value. The important pattern is that crop selects the picture, while pad adds a new canvas around it.

For a platform-focused treatment of vertical geometry, see RenderIO's 9:16 guide.

When to Crop vs Pad and Resize

Crop, pad, and scale answer different questions. Crop asks what can be removed. Pad asks what must be preserved. Scale asks how large the complete frame should become.

Cropping removes pixels outside a rectangle. It's the right tool when the subject fits inside the target frame and edge content is expendable. Padding adds pixels around the image, usually with a solid color, so the complete source remains visible inside a different canvas. Scaling changes pixel dimensions, but it doesn't fix an aspect-ratio mismatch by itself. Scaling a wide frame directly into a portrait rectangle can distort faces, products, and typography.

Goal Use Trade-off
Fill a target frame and remove dispensable edges Crop You lose content outside the rectangle
Preserve the entire source composition Pad Added bars or background occupy part of the canvas
Change output dimensions while preserving the source ratio Scale It doesn't solve a mismatched target ratio alone
Preserve content, then meet a delivery canvas Scale, then pad The output may include letterboxing or pillarboxing
Create a tighter editorial composition Crop, then scale The crop must keep the subject and overlays intact

A talking-head clip with edge text often needs padding rather than aggressive cropping. A centered product demonstration may benefit from cropping if the unused sides carry no information. A source that already matches the delivery ratio can be scaled without adding geometry changes.

The wrong choice is usually visible immediately. Distortion makes circles look oval, crop makes important content disappear, and padding can make a mobile export feel visually small. Decide what you can afford to lose before writing the filter chain.

Posting Crop Commands to the RenderIO API

Once a command works locally, keep the FFmpeg argument list unchanged when moving it to a hosted runner. The crop expression, padding chain, and scale operations are still ordinary FFmpeg filters. The API supplies the input, executes the command, and returns the rendered output.

A job request to RenderIO uses POST /v1/jobs with a JSON body containing the source URL, an FFmpeg arguments array, the output format, and, optionally, a callback URL. A representative payload looks like this:

{ "input_url": "https://media.example.com/master.mp4", "ffmpeg_args": [ "-i", "{{input}}", "-filter:v", "crop=ih*9/16:ih:(iw-ih*9/16)/2:0", "-c:a", "copy", "{{output}}" ], "output_format": "mp4", "callback_url": "https://app.example.com/webhooks/renderio" }

Use the placeholder conventions required by the API account and environment you're using. The key engineering principle is to preserve the same filter string that passed local validation. That avoids a subtle but costly failure where local FFmpeg and production use different crop coordinates.

The API command details are covered in RenderIO's run-FFmpeg command reference. After the POST, retain the returned job identifier. You can poll GET /v1/jobs/:id when your worker wants direct status control, or provide a callback URL and let the service notify your application when processing finishes.

Screenshot from https://renderio.example.com/docs/screenshots/renderio-job-post.png

Keep the production handoff deterministic

Debug the command locally with the actual source or a representative sample. Confirm the crop's visual result, output dimensions, audio behavior, and encoder compatibility before submitting it to the API. Then send the same ordered arguments rather than reconstructing a shell command as one opaque string.

On completion, the response provides a signed output URL that downstream systems can download during its valid window. Your application should copy the file or hand the URL to the next stage promptly, rather than treating the signed address as permanent storage.

Treat the hosted runner like the same FFmpeg binary inside a container. Validate the argument list first, then ship that list without improvising in production.

Building a Multi-Platform Crop Pipeline

A reusable pipeline stores one source URL and a set of named geometry recipes. Each recipe has a platform key, an aspect-ratio expression, and an output convention. The source master remains unchanged while the derivatives fan out in parallel.

A diagram illustrating a video cropping pipeline that converts a 16:9 master video into three different aspect ratios.

For a centered layout, the crop definitions can look like this:

  • TikTok vertical: crop=ih*9/16:ih:(iw-ow)/2:0
  • Reels portrait: crop=ih*4/5:ih:(iw-ow)/2:0
  • Feed square: crop=ih:ih:(iw-ih)/2:0

The vertical recipe retains a tall rectangle from the full source height. The portrait recipe retains a wider rectangle than 9:16, and the square recipe removes equal horizontal space when the source is wider than it is tall. If the subject isn't centered, replace the centered x-origin with a deliberate anchor and version that decision alongside the code.

Represent the fan-out as data

A wrapper can generate one job entry per target rather than duplicating shell commands throughout a repository:

const variants = [ { platform: "tiktok", filter: "crop=ih*9/16:ih:(iw-ow)/2:0" }, { platform: "reels", filter: "crop=ih*4/5:ih:(iw-ow)/2:0" }, { platform: "square", filter: "crop=ih:ih:(iw-ih)/2:0" } ];

The wrapper maps each filter into its FFmpeg argument list, includes the same input URL, submits the collection in one batch request, and writes the returned signed URLs into a manifest keyed by platform. That manifest can feed publishing, review, storage, or a later captioning step.

This pattern is more durable than keeping crop coordinates in a spreadsheet or editing them manually in a desktop project. A teammate can inspect the geometry in version control, review a change, and rerun the same set after the master edit is replaced.

Tools such as an ai video editor can help with adjacent creative work, but predictable platform derivatives still benefit from explicit, testable crop definitions. Keep automated geometry separate from editorial exceptions, such as a shot that needs a different anchor halfway through the clip.

Cropping Without Breaking Quality or Captions

A valid crop command can still produce a bad deliverable. Before rendering the complete file, inspect what lies at the new boundaries: subtitles, lower-thirds, watermarks, logos, product labels, and faces near the edge.

Start with a probe:

ffprobe -v error -select_streams v:0 -show_streams input.mp4

Confirm the source width and height, then run a short preview rather than committing immediately to a full encode:

ffmpeg -ss 00:00:10 -i input.mp4 -t 5 -vf "crop=ih*9/16:ih:(iw-ih*9/16)/2:0" -c:a copy preview.mp4

Review the first, middle, and last useful shots. A static crop that works for the opening can fail after a cut, especially when the subject changes position.

Three failures deserve a pre-flight check

Failure Mode Symptom Debug Command Fix
Wrong crop anchor Subject disappears or hugs one edge ffmpeg -loglevel debug -i input.mp4 -vf "crop=..." -f null - Change x and test left, center, and right anchors
Captions cut at the edge Text is truncated or collides with interface space ffmpeg -ss 00:00:10 -i input.mp4 -t 5 -vf "crop=..." preview.mp4 Move the crop, reposition captions upstream, or pad the output
Unexpected encoding or color behavior Output looks different after the filter chain ffmpeg -loglevel debug -i input.mp4 -vf "crop=...,format=..." -f null - Inspect stderr, make pixel format explicit, and test the final encoder

cropdetect can help identify visible borders during a diagnostic pass:

ffmpeg -t 30 -i input.mp4 -vf "cropdetect=limit=24:round=2:reset=0" -f null -

Use its output as a clue, not as an automatic composition decision. It can detect borders, but it doesn't know which person, caption, or product detail matters.

Cropping doesn't touch audio. If the source audio is already suitable, adding -c:a aac creates needless work and may introduce another generation of loss. Prefer -c:a copy when the container and downstream requirements allow it, then re-encode only when compatibility requires a different audio format.

Finally, check the entire filter chain and encoder together. A crop can be geometrically correct while a later scale, format conversion, or codec setting changes the result. Read FFmpeg's stderr, compare the preview with the source, and approve the rectangle before the job enters the batch pipeline.


RenderIO lets you submit FFmpeg 7.x commands through a hosted REST API, track jobs by polling or webhooks, and receive processed files through signed output URLs. Put your tested crop expressions into version-controlled job definitions, then visit RenderIO to turn the local crop workflow into repeatable platform exports without managing rendering servers or queues.