Read probe width, height and rotation before 9:16 crop fractions

A 9:16 crop needs width = 9/16 x H / W: 0.3164 for 1920x1080 but 0.5625 for a square clip. Read the probe first, and swap W and H if it reports rotation.

4 min readSume
All posts

Video filter crops by fractions, so the right numbers depend on the file: the 9:16 window is width = (9/16) x H / W at height 1, centered at x = (1 - width) / 2. That is 0.3164 / 0.3418 for 1920 x 1080 but 0.5625 / 0.21875 for a square 1080 x 1080 clip, so read the probe from POST /v1/video-inspect before you send a crop.

YouTube states Shorts are vertical and up to 3 minutes (read 2026-10-09); a clip that is already 9:16 needs no crop at all.

Crop fractions by source size

Values from the formula, to four decimals. Source sizes are hypothetical examples.

9:16 center crop fractions (arithmetic only, filter rules read 2026-10-09)
Source (W x H)widthx
1920 x 10800.31640.3418
1440 x 10800.42190.2891
1080 x 10800.56250.2188
1080 x 1920no crop-

Function and probe call

Inspect with frames: false returns only the probe, so the call is cheap to make. The probe covers size, rotation, fps, codecs, audio and HDR; confirm the exact field names in your response before you code against them, then swap width and height when the clip is rotated 90 or 270 degrees, because the stored pixels and the displayed picture then differ.

def crop_916(w, h, rotation=0):
    if rotation in (90, 270):
        w, h = h, w                     # displayed size
    if w * 16 <= h * 9:
        return None                     # already 9:16 or taller
    width = round(9 * h / (16 * w), 4)
    return {"op": "crop", "x": round((1 - width) / 2, 5),
            "y": 0, "width": width, "height": 1}

print(crop_916(1920, 1080))   # width 0.3164, x 0.3418

Gotchas

  • Whether crop fractions apply to the stored or displayed frame on rotated clips is not spelled out in the docs; extract one still with video frames after the crop before you trust it.
  • A crop must keep x + width <= 1, width and height at least 0.05, or the call fails with video_filter_crop_out_of_bounds.
  • The free POST /v1/video-filter/check validates the same program without encoding.
  • Each real crop is a $0.02 encode job.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume