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));
}
import os
import time
import requests
API_KEY = os.environ["RENDI_API_KEY"]
BASE = "https://api.rendi.dev/v1"
headers = {"X-API-KEY": API_KEY}
submit = requests.post(
f"{BASE}/run-chained-ffmpeg-commands",
headers=headers,
json={
"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}}",
],
},
)
command_id = submit.json()["command_id"]
while True:
res = requests.get(f"{BASE}/commands/{command_id}", headers=headers).json()
if res["status"] == "SUCCESS":
print("Thumbnail:", res["output_files"]["out_1"]["storage_url"])
print("GIF:", res["output_files"]["out_2"]["storage_url"])
break
if res["status"] == "FAILED":
raise RuntimeError("Command failed")
time.sleep(2)
curl --request POST \
--url https://api.rendi.dev/v1/run-chained-ffmpeg-commands \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '{
"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}}"
]
}'
curl --request GET \
--url https://api.rendi.dev/v1/commands/<command_id> \
--header 'X-API-KEY: <api-key>'
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"
}