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.
Combine a set of images and an audio track into a single video. Each image displays for a fixed duration and the audio plays over the top — finishing when the audio ends.
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_img_1: "https://storage.rendi.dev/sample/bbb-splash.png",
in_img_2: "https://storage.rendi.dev/sample/rodents.png",
in_img_3: "https://storage.rendi.dev/sample/evil-frank.png",
in_audio_1: "https://storage.rendi.dev/sample/Neon%20Lights.mp3",
},
output_files: {
out_1: "slideshow.mp4",
},
ffmpeg_command:
'-loop 1 -t 5 -i {{in_img_1}} -loop 1 -t 5 -i {{in_img_2}} -loop 1 -t 5 -i {{in_img_3}} -i {{in_audio_1}} -filter_complex "[0:v][1:v][2:v]concat=n=3:v=1:a=0,format=yuv420p[v]" -map [v] -map 3:a -c:v libx264 -c:a aac -shortest {{out_1}}',
}),
});
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("Slideshow URL:", data.output_files.out_1.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-ffmpeg-command",
headers=headers,
json={
"input_files": {
"in_img_1": "https://storage.rendi.dev/sample/bbb-splash.png",
"in_img_2": "https://storage.rendi.dev/sample/rodents.png",
"in_img_3": "https://storage.rendi.dev/sample/evil-frank.png",
"in_audio_1": "https://storage.rendi.dev/sample/Neon%20Lights.mp3",
},
"output_files": {"out_1": "slideshow.mp4"},
"ffmpeg_command": '-loop 1 -t 5 -i {{in_img_1}} -loop 1 -t 5 -i {{in_img_2}} -loop 1 -t 5 -i {{in_img_3}} -i {{in_audio_1}} -filter_complex "[0:v][1:v][2:v]concat=n=3:v=1:a=0,format=yuv420p[v]" -map [v] -map 3:a -c:v libx264 -c:a aac -shortest {{out_1}}',
},
)
command_id = submit.json()["command_id"]
while True:
res = requests.get(f"{BASE}/commands/{command_id}", headers=headers).json()
if res["status"] == "SUCCESS":
print("Slideshow URL:", res["output_files"]["out_1"]["storage_url"])
break
if res["status"] == "FAILED":
raise RuntimeError("Command failed")
time.sleep(2)
curl --request POST \
--url https://api.rendi.dev/v1/run-ffmpeg-command \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '{
"input_files": {
"in_img_1": "https://storage.rendi.dev/sample/bbb-splash.png",
"in_img_2": "https://storage.rendi.dev/sample/rodents.png",
"in_img_3": "https://storage.rendi.dev/sample/evil-frank.png",
"in_audio_1": "https://storage.rendi.dev/sample/Neon%20Lights.mp3"
},
"output_files": {"out_1": "slideshow.mp4"},
"ffmpeg_command": "-loop 1 -t 5 -i {{in_img_1}} -loop 1 -t 5 -i {{in_img_2}} -loop 1 -t 5 -i {{in_img_3}} -i {{in_audio_1}} -filter_complex \"[0:v][1:v][2:v]concat=n=3:v=1:a=0,format=yuv420p[v]\" -map [v] -map 3:a -c:v libx264 -c:a aac -shortest {{out_1}}"
}'
curl --request GET \
--url https://api.rendi.dev/v1/commands/<command_id> \
--header 'X-API-KEY: <api-key>'
How the FFmpeg command works
-loop 1 -t 5 -i {{in_img_1}} — loop each image for 5 seconds (repeat per image)
-i {{in_audio_1}} — audio track as the last input
concat=n=3:v=1:a=0 — concatenate the 3 video streams, 1 video, 0 audio
format=yuv420p — pixel format compatible with most players
-map [v] -map 3:a — pick the concatenated video + audio from input index 3
-shortest — stop when the shortest stream ends (typically when video runs out)
{{out_1}} — output file
For longer images, increase -t 5 per input. For crossfades between images, replace concat with xfade.
Response
{
"output_files": {
"out_1": {
"file_id": "10cfed0c-...",
"size_mbytes": 1.09,
"duration": 15.001,
"file_type": "video",
"file_format": "mp4",
"storage_url": "https://storage.rendi.dev/temp_files/.../slideshow.mp4",
"width": 1920,
"height": 1080,
"codec": "h264",
"frame_rate": 25.0,
"bitrate_video_kb": 453.5,
"bitrate_audio_kb": 132.6
}
},
"status": "SUCCESS",
"command_type": "FFMPEG_COMMAND"
}