video.resize

Scale a video — by a percentage of its own size, or into a pixel box with a fit mode. Chain as many as you like: they compile into one filter pass, so the frames are decoded and encoded once.

Config

Fields depend on mode. In percentage mode only percent is read; in pixels mode width, height, fit, and padColor are read.

FieldTypeDefaultNotes
modepercentage · pixelspercentageWhich fields below are used.
percentnumber 1–10050percentage mode. Scales both dimensions. A value above 100 fails the job — see below.
widthnumber1280pixels mode. Set one of width/height to scale by a single axis; the other follows the aspect ratio.
heightnumber720pixels mode.
fitcontain · cover · fill · inside · outsidecontainpixels mode. How the frame maps into the box (see below). Read only when both width and height are set.
padColorstringblackpixels mode, contain only — the letterbox colour. A name (black), #rrggbb, or 0xRRGGBB; anything else falls back to black.
A percentabove 100 fails the job rather than doing nothing. Scaling up is a request the transport can't honour, and a silent no-op would bill you for a video you didn't ask for. image.resize treats the same value as a no-op — that difference is deliberate.

Fit modes

  • inside — fit within the box, preserve aspect, never upscale, no padding. This is the "longest side ≤ N" cap that .maxSize() uses.
  • contain — fit within the box, then letterbox with padColor to exactly W×H. Keeps the whole frame.
  • cover — fill the box, preserve aspect, crop the overflow. Output is exactly W×H.
  • fill — stretch to exactly W×H, ignoring aspect.
  • outside — cover the box preserving aspect without cropping, so one side may overshoot.

Final dimensions are rounded down to a multiple of two, which the yuv420p pixel format every output uses requires. A box of 481 comes back as 480.

In a pipeline

Config fields are { value, editable } objects — the shape shared with the visual editor. Prefer to pass only the values you care about? mergePipelineNodeConfig fills the rest from these defaults.

{
  id: 'resize',
  type: 'video.resize',
  config: {
    mode: { value: 'pixels' },
    width: { value: 1080 },
    height: { value: 1080 },
    fit: { value: 'cover' }, // square crop, no bars
  },
}

With runQueue

tk.runQueue(files, 'video')
  .maxSize(720)                                    // fit: inside, longest side ≤ 720
  .resize({ width: 1080, height: 1080, fit: 'cover' })
  .resize({ percent: 50 });                        // half size
Resizes chain — each one sees the frame the previous produced, and they still cost a single decode and encode. That is the opposite of image.resize, where the last resize in a branch wins.

Resizing without converting

A branch with no video.convert is re-encoded back into its source container, so the source has to be one this engine can write — mp4, webm, mov, or mkv. Resize an .avi on its own and the job fails asking for a convert node to pick the output container, rather than quietly handing you a different format than the key says.