Skip to main content

Documentation Index

Fetch the complete documentation index at: https://rendi.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

Trim a video to a time range and simultaneously output multiple resolutions from the same input. One command instead of several — cheaper and faster because the input is decoded once.

Code

const API_KEY = process.env.RENDI_API_KEY;

const submit = await fetch("https://api.rendi.dev/v1/run-ffmpeg-command", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-KEY": API_KEY,
  },
  body: JSON.stringify({
    input_files: {
      in_1: "https://storage.rendi.dev/sample/sample.avi",
    },
    output_files: {
      out_1: "output_320p.mp4",
      out_2: "output_180p.mp4",
    },
    ffmpeg_command:
      '-i {{in_1}} -ss 00:00 -to 00:30 -filter_complex "[0:v]split=2[vid1][vid2];[vid1]scale=trunc(oh*a/2)*2:320:force_original_aspect_ratio=decrease,pad=trunc(oh*a/2)*2:320:-1:-1[320p];[vid2]scale=trunc(oh*a/2)*2:180:force_original_aspect_ratio=decrease,pad=trunc(oh*a/2)*2:180:-1:-1[180p]" -map [320p] -map 0:a -c:a copy -c:v libx264 -preset medium {{out_1}} -map [180p] -map 0:a -c:a copy -c:v libx264 -preset medium {{out_2}}',
  }),
});
const { command_id } = await submit.json();

while (true) {
  const res = await fetch(`https://api.rendi.dev/v1/commands/${command_id}`, {
    headers: { "X-API-KEY": API_KEY },
  });
  const data = await res.json();
  if (data.status === "SUCCESS") {
    console.log("320p:", data.output_files.out_1.storage_url);
    console.log("180p:", data.output_files.out_2.storage_url);
    break;
  }
  if (data.status === "FAILED") throw new Error("Command failed");
  await new Promise((r) => setTimeout(r, 2000));
}

How the FFmpeg command works

  • -ss 00:00 -to 00:30 — trim the video to the first 30 seconds
  • split=2[vid1][vid2] — duplicate the video stream so each copy can be scaled independently
  • scale=...:320:...,pad=...:320:-1:-1[320p] — scale first copy to 320 px tall, letterbox to maintain aspect
  • scale=...:180:...,pad=...:180:-1:-1[180p] — scale second copy to 180 px tall
  • -map [320p] -map 0:a ... {{out_1}} — first output: 320p video + original audio
  • -map [180p] -map 0:a ... {{out_2}} — second output: 180p video + original audio
  • -c:a copy — pass audio through unchanged for both outputs
  • -c:v libx264 -preset medium — re-encode each video with H.264
For N resolutions, extend the split=N and add another scale...pad...[NNp] stage plus output mapping.

Response

{
  "output_files": {
    "out_1": {
      "file_id": "f775b15d-...",
      "size_mbytes": 2.27,
      "duration": 30.0,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/.../output_320p.mp4",
      "width": 568,
      "height": 320,
      "codec": "h264"
    },
    "out_2": {
      "file_id": "9df00eca-...",
      "size_mbytes": 1.05,
      "duration": 30.0,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/.../output_180p.mp4",
      "width": 320,
      "height": 180,
      "codec": "h264"
    }
  },
  "status": "SUCCESS",
  "command_type": "FFMPEG_COMMAND"
}