Skip to main content

Generate multiple thumbnails from video

Rendi JSON body Command for run-ffmpeg-command:
{
  "input_files": {
    "in_1": "https://storage.rendi.dev/sample/sample.avi"
  },
  "output_files": {
    "out_1": "thumbnail1.jpg",
    "out_2": "thumbnail2.jpg"
  },
  "ffmpeg_command": "-i {{in_1}} -filter_complex \"[0:v]split=2[first][second];[first]select='gte(t,10)'[thumb1];[second]select='gte(t,20)'[thumb2]\" -map [thumb1] -frames:v 1 {{out_1}} -map [thumb2] -frames:v 1 {{out_2}}"
}
Run command:
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_1": "https://storage.rendi.dev/sample/sample.avi"
    },
    "output_files": {
        "out_1": "thumbnail1.jpg",
        "out_2": "thumbnail2.jpg"
    },
    "ffmpeg_command": "-i {{in_1}} -filter_complex \"[0:v]split=2[first][second];[first]select='\''gte(t,10)'\''[thumb1];[second]select='\''gte(t,20)'\''[thumb2]\" -map [thumb1] -frames:v 1 {{out_1}} -map [thumb2] -frames:v 1 {{out_2}}"
}'
Running this command will return the command_id:
{
  "command_id": "f6bb88cb-83a9-4ea5-b763-078bff3431d4"
}
Poll result:
curl --request GET \
  --url https://api.rendi.dev/v1/commands/f6bb88cb-83a9-4ea5-b763-078bff3431d4 \
  --header 'X-API-KEY: <api-key>'
On SUCCESS
{
  "output_files": {
    "out_1": {
      "file_id": "eba1a713-4631-4ccb-9ef8-b727a9f7f274",
      "size_mbytes": 0.08534908294677734,
      "file_type": "image",
      "file_format": "jpg",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/f6bb88cb-83a9-4ea5-b763-078bff3431d4/thumbnail1.jpg",
      "width": 1280,
      "height": 720
    },
    "out_2": {
      "file_id": "d8278ca9-cede-4677-b8d2-374afc4604fc",
      "size_mbytes": 0.03953361511230469,
      "file_type": "image",
      "file_format": "jpg",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/f6bb88cb-83a9-4ea5-b763-078bff3431d4/thumbnail2.jpg",
      "width": 1280,
      "height": 720
    }
  },
  "status": "SUCCESS",
  "original_request": {
    "input_files": {
      "in_1": "https://storage.rendi.dev/sample/sample.avi"
    },
    "output_files": {
      "out_1": "thumbnail1.jpg",
      "out_2": "thumbnail2.jpg"
    },
    "ffmpeg_command": "-i {{in_1}} -filter_complex \"[0:v]split=2[first][second];[first]select='gte(t,10)'[thumb1];[second]select='gte(t,20)'[thumb2]\" -map [thumb1] -frames:v 1 {{out_1}} -map [thumb2] -frames:v 1 {{out_2}}"
  },
  "ffmpeg_command_run_seconds": 0.8197736740112305,
  "total_processing_seconds": 5.868829,
  "vcpu_count": 8,
  "command_type": "FFMPEG_COMMAND"
}

Create several trimmed videos with different resolutions

Rendi JSON body Command for run-ffmpeg-command:
{
  "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}}"
}
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_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}}"
}'
Running this command will return the command_id:
{
  "command_id": "42c95292-d953-4b5a-8a58-cf1513363a33"
}
Poll result:
curl --request GET \
  --url https://api.rendi.dev/v1/commands/42c95292-d953-4b5a-8a58-cf1513363a33 \
  --header 'X-API-KEY: <api-key>'
On SUCCESS
{
  "output_files": {
    "out_1": {
      "file_id": "f775b15d-67e9-4235-b89f-4bb33c0a5f57",
      "size_mbytes": 2.2677812576293945,
      "duration": 30.0,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/42c95292-d953-4b5a-8a58-cf1513363a33/output_320p.mp4",
      "width": 568,
      "height": 320,
      "codec": "h264",
      "frame_rate": 24.0,
      "bitrate_video_kb": 370.5654296875,
      "bitrate_audio_kb": 242.349609375,
      "is_varying_frame_rate": false
    },
    "out_2": {
      "file_id": "9df00eca-3221-49c6-8a64-07850c9a5921",
      "size_mbytes": 29.620187759399414,
      "duration": 596.459,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/42c95292-d953-4b5a-8a58-cf1513363a33/output_180p.mp4",
      "width": 320,
      "height": 180,
      "codec": "h264",
      "frame_rate": 24.0,
      "bitrate_video_kb": 160.955078125,
      "bitrate_audio_kb": 239.9833984375,
      "is_varying_frame_rate": false
    }
  },
  "status": "SUCCESS",
  "original_request": {
    "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}}"
  },
  "ffmpeg_command_run_seconds": 19.58051347732544,
  "total_processing_seconds": 24.955581,
  "vcpu_count": 8,
  "command_type": "FFMPEG_COMMAND"
}

Combine images with audio to create a video

Rendi JSON body Command for run-ffmpeg-command:
{
  "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": "output.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}}"
}
Run command:
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": "output.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}}"
}'
Running this command will return the command_id:
{
  "command_id": "644c1ce5-57a5-423d-9b55-052fb087674e"
}
Poll result:
curl --request GET \
  --url https://api.rendi.dev/v1/commands/644c1ce5-57a5-423d-9b55-052fb087674e \
  --header 'X-API-KEY: <api-key>'
On SUCCESS
{
  "output_files": {
    "out_1": {
      "file_id": "10cfed0c-f25f-4b29-a58d-ffa563bc57e8",
      "size_mbytes": 1.0871257781982422,
      "duration": 15.001,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/644c1ce5-57a5-423d-9b55-052fb087674e/output.mp4",
      "width": 1920,
      "height": 1080,
      "codec": "h264",
      "frame_rate": 25.0,
      "bitrate_video_kb": 453.5546875,
      "bitrate_audio_kb": 132.6640625,
      "is_varying_frame_rate": false
    }
  },
  "status": "SUCCESS",
  "original_request": {
    "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": "output.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}}"
  },
  "ffmpeg_command_run_seconds": 6.009521722793579,
  "total_processing_seconds": 10.877786,
  "vcpu_count": 8,
  "command_type": "FFMPEG_COMMAND"
}
Music credit to https://www.fiftysounds.com/music/neon-lights.mp3

Add srt subtitles to video

Rendi JSON body Command for run-ffmpeg-command:
{
  "input_files": {
    "in_video": "https://storage.rendi.dev/sample/sample.avi",
    "in_srt": "https://storage.rendi.dev/sample/subtitles.srt"
  },
  "output_files": {
    "out_1": "output.mp4"
  },
  "ffmpeg_command": "-i {{in_video}} -ss 00:00 -to 01:00 -vf subtitles={{in_srt}} -c:v libx264 -crf 20 -c:a aac -b:a 192k {{out_1}}"
}
Run command:
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_video": "https://storage.rendi.dev/sample/sample.avi",
    "in_srt": "https://storage.rendi.dev/sample/subtitles.srt"
  },
  "output_files": {
    "out_1": "output.mp4"
  },
  "ffmpeg_command": "-i {{in_video}} -ss 00:00 -to 01:00 -vf subtitles={{in_srt}} -c:v libx264 -crf 20 -c:a aac -b:a 192k {{out_1}}"
}'
Running this command will return the command_id:
{
  "command_id": "059946cd-2e7c-41b8-8a27-0b992f516d4f"
}
Poll result:
curl --request GET \
  --url https://api.rendi.dev/v1/commands/059946cd-2e7c-41b8-8a27-0b992f516d4f \
  --header 'X-API-KEY: <api-key>'
On SUCCESS
{
  "output_files": {
    "out_1": {
      "file_id": "cb5b9186-4060-4942-ac4f-1dc9df5172be",
      "size_mbytes": 13.946301460266113,
      "duration": 60.0,
      "file_type": "video",
      "file_format": "mp4",
      "storage_url": "https://storage.rendi.dev/temp_files/224ea098-5c10-419b-8a77-707d89443c56/059946cd-2e7c-41b8-8a27-0b992f516d4f/output.mp4",
      "width": 854,
      "height": 480,
      "codec": "h264",
      "frame_rate": 24.0,
      "bitrate_video_kb": 1710.490234375,
      "bitrate_audio_kb": 188.927734375,
      "is_varying_frame_rate": false
    }
  },
  "status": "SUCCESS",
  "original_request": {
    "input_files": {
      "in_srt": "https://storage.rendi.dev/sample/subtitles.srt",
      "in_video": "https://storage.rendi.dev/sample/sample.avi"
    },
    "output_files": {
      "out_1": "output.mp4"
    },
    "ffmpeg_command": "-i {{in_video}} -ss 00:00 -to 01:00 -vf subtitles={{in_srt}} -c:v libx264 -crf 20 -c:a aac -b:a 192k {{out_1}}"
  },
  "ffmpeg_command_run_seconds": 7.182231664657593,
  "total_processing_seconds": 11.956641,
  "vcpu_count": 8,
  "command_type": "FFMPEG_COMMAND"
}

Generate thumbnail + GIF using chained commands

Rendi JSON body Command for run-chained-ffmpeg-commands:
{
  "input_files": {
    "in_1": "https://storage.rendi.dev/sample/sample.avi"
  },
  "output_files": { "out_1": "thumbnail.jpg", "out_2": "output.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 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": "output.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}}"
  ]
}'
Running this command will return the command_id:
{
  "command_ids": ["963b85e1-0a2d-4fde-8565-634ae0b22b92"]
}
Poll result:
curl --request GET \
 --url https://api.rendi.dev/v1/poll-command/963b85e1-0a2d-4fde-8565-634ae0b22b92 \
 --header 'X-API-KEY: <api-key>'
On SUCCESS
{
  "command_id": "963b85e1-0a2d-4fde-8565-634ae0b22b92",
  "status": "SUCCESS",
  "output_files": {
    "out_1": {
      "file_id": "5a978607-8c20-4b3b-91db-b67516e7f274",
      "storage_url": "https://storage.rendi.dev/files/224ea098-5c10-419b-8a77-707d89443c56/963b85e1-0a2d-4fde-8565-634ae0b22b92/thumbnail.jpg",
      "status": "STORED",
      "rendi_store_type": "OUTPUT",
      "is_deleted": false,
      "size_mbytes": 0.02407360076904297,
      "file_type": "image",
      "file_format": "jpg",
      "width": 854,
      "height": 480
    },
    "out_2": {
      "file_id": "3f51e56e-18b1-4277-b0e8-42a2f4cf6bf4",
      "storage_url": "https://storage.rendi.dev/files/224ea098-5c10-419b-8a77-707d89443c56/963b85e1-0a2d-4fde-8565-634ae0b22b92/output.gif",
      "status": "STORED",
      "rendi_store_type": "OUTPUT",
      "is_deleted": false,
      "size_mbytes": 0.30026817321777344,
      "file_type": "image",
      "file_format": "gif",
      "width": 142,
      "height": 80
    }
  },
  "original_request": {
    "input_files": {
      "in_1": "https://storage.rendi.dev/sample/sample.avi"
    },
    "output_files": {
      "out_1": "thumbnail.jpg",
      "out_2": "output.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}}"
    ]
  },
  "ffmpeg_command_run_seconds": 6.013741970062256,
  "total_processing_seconds": 20.55214,
  "vcpu_count": 8,
  "command_type": "FFMPEG_CHAINED_COMMANDS"
}

Credit to www.bigbuckbunny.org for the video and image files.
I