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.

Produce a thumbnail and a short preview GIF in a single chained request. Chained commands run sequentially on the same input, and outputs from earlier commands can feed later ones — cheaper than two separate calls.

Code

const API_KEY = process.env.RENDI_API_KEY;

const submit = await fetch(
  "https://api.rendi.dev/v1/run-chained-ffmpeg-commands",
  {
    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: "thumbnail.jpg",
        out_2: "preview.gif",
      },
      ffmpeg_commands: [
        "-i {{in_1}} -ss 00:17 -vframes 1 {{out_1}}",
        "-i {{in_1}} -vf \"select='lte(t,60)*gt(trunc(t/10),trunc(prev_t/10))',setpts='PTS*0.1',scale=trunc(oh*a/2)*2:80:force_original_aspect_ratio=decrease,pad=trunc(oh*a/2)*2:80:-1:-1\" -an -vsync vfr {{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("Thumbnail:", data.output_files.out_1.storage_url);
    console.log("GIF:", 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 commands work

Command 1 (thumbnail): -i {{in_1}} -ss 00:17 -vframes 1 {{out_1}} — grab a single frame at 17 s. Command 2 (GIF):
  • select='lte(t,60)*gt(trunc(t/10),trunc(prev_t/10))' — keep one frame every 10 s, up to the 60 s mark (6 frames total)
  • setpts='PTS*0.1' — speed up playback by 10× so the GIF plays fast
  • scale=...:80:force_original_aspect_ratio=decrease,pad=...:80:-1:-1 — scale to 80 px tall, letterbox width
  • -an — drop audio
  • -vsync vfr — variable frame rate for the speed-up

Response

{
  "command_id": "963b85e1-...",
  "status": "SUCCESS",
  "output_files": {
    "out_1": {
      "file_id": "5a978607-...",
      "size_mbytes": 0.024,
      "file_type": "image",
      "file_format": "jpg",
      "storage_url": "https://storage.rendi.dev/files/.../thumbnail.jpg",
      "width": 854,
      "height": 480
    },
    "out_2": {
      "file_id": "3f51e56e-...",
      "size_mbytes": 0.300,
      "file_type": "image",
      "file_format": "gif",
      "storage_url": "https://storage.rendi.dev/files/.../preview.gif",
      "width": 142,
      "height": 80
    }
  },
  "command_type": "FFMPEG_CHAINED_COMMANDS"
}