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.

Concatenate two or more video clips into a single output. The concat filter re-encodes on the fly so it works even when the clips have different codecs, resolutions, or frame rates.

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",
      in_2: "https://storage.rendi.dev/sample/sample.avi",
    },
    output_files: {
      out_1: "merged.mp4",
    },
    ffmpeg_command:
      '-i {{in_1}} -i {{in_2}} -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -c:a aac {{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("Merged 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));
}

How the FFmpeg command works

  • -i {{in_1}} -i {{in_2}} — two input videos (add more with in_3, in_4, etc.)
  • concat=n=2:v=1:a=1 — concatenate 2 inputs, each contributing 1 video stream + 1 audio stream
  • [v][a] — named outputs for the concatenated streams
  • -map "[v]" -map "[a]" — route concatenated streams to the output
  • -c:v libx264 -c:a aac — re-encode (required by the concat filter)
  • {{out_1}} — output file
For N videos, add -i {{in_N}} per input, update n=N, and extend the stream-selection list: [0:v][0:a][1:v][1:a]...[N-1:v][N-1:a]. If all clips share the same codec/resolution/framerate, the demuxer approach (concat as a protocol, no re-encode) is faster — but requires a concat list file.

Response

{
  "output_files": {
    "out_1": {
      "file_id": "d4c5b6a7-...",
      "size_mbytes": 58.3,
      "duration": 1192.918,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/.../merged.mp4",
      "width": 854,
      "height": 480,
      "codec": "h264"
    }
  },
  "status": "SUCCESS",
  "command_type": "FFMPEG_COMMAND"
}