Why you can't upload the same video everywhere
You generated a great AI video. Now you need it on TikTok, Instagram Reels, YouTube Shorts, LinkedIn, and Twitter. Each platform wants different dimensions, aspect ratios, file sizes, and audio levels. If you're also looking to .
const INPUT_URL = "https://storage.example.com/ai-video.mp4";
const platforms = [
{
name: "tiktok",
command: `-i {{in_video}} -map_metadata -1 -filter_complex "[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,boxblur=25[bg];[0:v]scale=1080:1920:force_original_aspect_ratio=decrease,noise=alls=16:allf=t[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2[v]" -map "[v]" -map 0:a? -af "loudnorm=I=-14:TP=-2:LRA=7" -c:v libx264 -crf 22 -c:a aac -b:a 128k -movflags +faststart {{out_video}}`,
},
{
name: "reels",
command: `-i {{in_video}} -map_metadata -1 -t 90 -filter_complex "[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,boxblur=25[bg];[0:v]scale=1080:1920:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2[v]" -map "[v]" -map 0:a? -af "loudnorm=I=-14:TP=-2:LRA=7" -c:v libx264 -crf 22 -c:a aac -b:a 128k -movflags +faststart {{out_video}}`,
},
{
name: "shorts",
command: `-i {{in_video}} -map_metadata -1 -t 60 -filter_complex "[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,boxblur=25[bg];[0:v]scale=1080:1920:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2[v]" -map "[v]" -map 0:a? -af "loudnorm=I=-14:TP=-2:LRA=7" -c:v libx264 -crf 20 -c:a aac -b:a 128k -movflags +faststart {{out_video}}`,
},
{
name: "linkedin",
command: `-i {{in_video}} -map_metadata -1 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black" -af "loudnorm=I=-16:TP=-2:LRA=11" -c:v libx264 -crf 20 -c:a aac -b:a 192k -movflags +faststart {{out_video}}`,
},
{
name: "twitter",
command: `-i {{in_video}} -map_metadata -1 -t 140 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2:black" -af "loudnorm=I=-16:TP=-2:LRA=11" -c:v libx264 -crf 23 -c:a aac -b:a 128k -movflags +faststart {{out_video}}`,
},
];
async function processForAllPlatforms(inputUrl) {
const jobs = platforms.map(platform =>
fetch("https://renderio.dev/api/v1/run-ffmpeg-command", {
method: "POST",
headers: {
"X-API-KEY": process.env.RENDERIO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
ffmpeg_command: platform.command,
input_files: { in_video: inputUrl },
output_files: { out_video: `${platform.name}.mp4` },
}),
}).then(r => r.json())
);
return Promise.all(jobs);
}
const results = await processForAllPlatforms(INPUT_URL);
// 5 jobs running in parallel on Cloudflare's edge
Five API calls. Five platform-optimized videos. All processing happens in parallel, so you wait for one, not five.
If you also need to generate speed variations — a 1.5x version for Stories previews or a 2x cut for YouTube Shorts teasers — you can add those as additional jobs in the same batch. The or the for normalization and branding steps.
Choosing aspect ratio strategy
When converting 16:9 to 9:16, you have three options. The right choice depends on your content.
Crop from center works when the subject is centered (most AI talking-head videos). You lose the left and right edges but keep the subject sharp.
Blurred background preserves the full frame at a smaller size with a blurred version filling the background. Looks clean but the video appears smaller on screen.
Letterbox/pillarbox (black bars) is technically correct but looks terrible on mobile-first platforms. Avoid it for TikTok and Reels.
For landscape-to-portrait conversion specifically, the . You can also transcode video with FFmpeg locally for testing before scaling to the API.
Troubleshooting common issues
Black screen on TikTok upload. Usually means the video codec isn't H.264 or the pixel format isn't yuv420p. Add -pix_fmt yuv420p to your command.
Audio out of sync after conversion. Common with variable frame rate sources. Add -vsync cfr to force constant frame rate before other filters.
Instagram rejects the upload. Check file size (250 MB max for Reels) and duration (3 minutes max). Also confirm the video is at least 3 seconds long, since Reels rejects shorter clips.
FAQ
Can I batch process videos that aren't AI-generated?
Yes. The commands work with any MP4 input. Screen recordings, phone clips, webcam footage, anything. The pipeline doesn't care about the video source.
How long does batch processing take for one video?
About 15-45 seconds for all five platform versions to finish, depending on the video length. They process in parallel, so you're waiting for the slowest one, not all five sequentially.
What if a platform changes its specs?
Update the relevant command in your platforms array. The rest of the pipeline stays the same. We update this guide when platforms change their requirements.
Can I add a watermark or logo during batch processing?
Yes. Add an overlay filter to each command. For example: -i {{in_video}} -i {{in_logo}} -filter_complex "[1:v]scale=80:-1[logo];[0:v][logo]overlay=W-w-20:20[v]". The logo file is a second input in the API call.
What's the difference between this and using CapCut's batch export?
CapCut requires manual setup per video and runs on your machine. RenderIO processes via API, so it integrates into automated workflows (n8n, Zapier, custom scripts) and runs on Cloudflare's edge infrastructure. No local compute needed.
SOCIAL SHARE CARD GENERATOR