video-adsautomation

Don't generate bulk video ad variants. Reframe your master clip.

··10 min read
Don't generate bulk video ad variants. Reframe your master clip.

You have one good product clip, a creative calendar that wants 20 ads, and about two weeks before the window closes. Most tools answer it the same way: generate 20 brand new videos from a prompt. That throws away the footage you already paid to shoot, and bills you per generation.

Quick answer: To produce bulk video ad variants, don't generate new video. Take the one master clip you already have, burn each hook line onto its first three seconds with FFmpeg's drawtext filter, then reframe every winner to 9:16, 1:1, 4:5 and 16:9 with scale plus pad or crop. Doing it locally means an encoder on your machine and 20 sequential exports; sending the same two passes to FFmpeg Micro is one API call per row, with no encoder to host, billing per second of input video processed, and failed jobs never billed.

The published BFCM calendars ask for reformatting, not reshooting

Conventional wisdom says 20 ad variants means 20 productions. Most agency workflows produce exactly that, which is why creative volume gets described as a shooting problem. It's a render problem instead: the plans that set this season's dates assume one hero cut gets rehooked and reframed, and they budget the calendar for that.

Heat Marketers' 6-week DTC plan puts Black Friday on Nov 27 and Cyber Monday on Nov 30, sale running Nov 27 to Dec 1, with produce-and-pre-test at weeks 4 and 3 (Oct 30 to Nov 12) on roughly 15% of Q4 budget and no experiments once the sale starts. Plaid Testing's BFCM paid media calendar names Oct 12 to 18 as the creative volume week for briefing and shooting the set, and closes paid media setup on Friday Nov 6. Kive's BFCM prep checklist wants hero-product scenes approved by Oct 29 and every scene cropped to 1:1, 4:5, 9:16 and 16:9 by Nov 5. UGC briefing guides like Influee's put briefs out by Oct 15 and creator delivery by Nov 1, with three hook variants per format across two creators.

Together they describe one deliverable: a few source cuts, several hooks each, four ratios each, locked by the first week of November. That's a batch job with a deadline, not a creative brief.

A hook variant is a drawbox and a drawtext, timed to the first three seconds

A hook variant is the cheapest real test you can run: same footage, same offer, different opening line. In FFmpeg it's a filled box across the lower third with text centered inside, both gated to the first three seconds by enable.

ffmpeg -y -i master.mp4 \
  -vf "drawbox=x=0:y=ih*0.70:w=iw:h=ih*0.12:color=0x111827@0.92:t=fill:enable='between(t,0,3)',\
drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:\
textfile=/tmp/hook.txt:fontcolor=white:fontsize=54:line_spacing=10:\
x=(w-text_w)/2:y=ih*0.70+(ih*0.12-text_h)/2:enable='between(t,0,3)'" \
  -c:v libx264 -crf 20 -preset veryfast -pix_fmt yuv420p -c:a copy \
  variants/hook-01.mp4

Use textfile= rather than text= and the escaping problem disappears. Spreadsheet hook lines contain colons ("Black Friday: 40% off"), apostrophes ("don't"), percent signs and commas, and each one breaks a text= filter string. Write the row to a temp file instead.

20 variants is a loop over a one-column file:

i=0
while IFS= read -r hook; do
  i=$((i+1))
  printf '%s' "$hook" > /tmp/hook.txt
  ffmpeg -y -i master.mp4 -vf "$HOOK_FILTER" \
    -c:v libx264 -crf 20 -preset veryfast -pix_fmt yuv420p -c:a copy \
    "variants/hook-$(printf '%02d' "$i").mp4"
done < hooks.txt

A 15-second 1080p master at -preset veryfast takes a few seconds per variant on a laptop. The cost shows up at the next step, where each winner has to exist four times.

Pad keeps the product whole; crop makes it fill the frame

The only judgment call in the ratio pass is pad versus crop. Padding preserves every pixel you shot and adds bars. Cropping fills the frame and cuts the edges off, which is how a product ends up half out of frame or a price badge gets sliced. For product footage shot 16:9, pad to 9:16 and crop to 4:5 and 1:1, where the loss is small.

Superscale's Meta ad size reference lists the placements: 4:5 at 1080x1350 for Feed, 9:16 at 1080x1920 for Stories and Reels, 1:1 for carousel, 16:9 for in-stream, delivered as MP4 or MOV at 30fps or lower.

PlacementRatioTargetFilter
Reels, Stories, TikTok9:161080x1920`scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=0x0b0b0b,setsar=1`
Feed4:51080x1350`crop='min(iw,ih*4/5)':'min(ih,iw*5/4)',scale=1080:1350,setsar=1`
Carousel, smaller placements1:11080x1080`crop='min(iw,ih)':'min(iw,ih)',scale=1080:1080,setsar=1`
In-stream, marketplace16:91920x1080`scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:color=0x0b0b0b,setsar=1`

The crop idiom centers automatically whatever the source dimensions are, so the same string survives a vertical phone clip and a 4K camera export. Keep setsar=1 on every one, or players that respect sample aspect ratio will stretch your 1:1 back out.

Five winners times four ratios is 20 more renders, where hand-editing stops being viable. The placement-spec side is in Facebook video specs aren't the problem. Your encode is.

The same two passes as one API call per row

Running this unattended means the render doesn't live on your machine. The FFmpeg Micro flow is four calls per variant: POST /v1/upload/presigned-url, a PUT of the master straight to storage, POST /v1/upload/confirm, then POST /v1/transcodes with the filter you want. Upload the master once and reuse the file for all 20 rows.

curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
  -H "Authorization: Bearer $FFMPEG_MICRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputFileId": "file_abc123",
    "filters": [
      { "filter": "@text-overlay",
        "params": { "text": "Black Friday: 40% off everything",
                    "fontSize": 54, "charsPerLine": 28, "lineSpacing": 10 } }
    ]
  }'

The @text-overlay filter is the hosted version of that drawbox plus drawtext pair, with the same style knobs (charsPerLine, fontSize, lineSpacing, box border). The full field list is in the docs. Jobs run asynchronously, so poll until complete, then fetch a signed download URL. Status checks, job listing and downloads are free, so polling aggressively costs nothing.

In n8n, each render is three nodes on the FFmpeg Micro community node: Create, Wait for Completion, Get Download URL. Put a Google Sheets read and a Loop Over Items in front, and a 20-row sheet produces 20 renders with nobody watching. Our Product Ad Machine walkthrough uses that three-node pattern, and the bulk shorts script fires 100 text-overlay jobs in parallel from a CSV if you'd rather drive it from bash. In Make, it's Google Sheets Search Rows into an Iterator into the FFmpeg Micro module.

The Text Hook Variants blueprint is this post's first pass as a form: one video in, up to three hooks out, each on a colored bar. The Listing Video Kit blueprint does the ratio pass, turning one cut into 9:16, 1:1, 4:5 and a marketplace-safe 16:9 in one run.

Twenty variants of a 15-second master is 30 tokens

Pricing units matter more than price in a variant fan-out: one input multiplies into many outputs. FFmpeg Micro bills on the duration of the video you process, not per render and not per command: one token covers 10 seconds of input, metered per second with no rounding up to the minute.

A 15-second master, 20 hook rows, is 300 seconds of input, which is 30 tokens. Five winners reframed to four ratios each is another 20 renders of 15 seconds, so another 30 tokens. The full Black Friday set costs 60 tokens, and a new account gets 200 for free with no card, about 33 minutes of video. Starter is $19.99 a month for 2,500 tokens if you're running this for several brands.

Two details matter for a variant batch. If you trim a 15-second cut out of a one-hour recording, you're billed for the 15 seconds, not the hour. And failed jobs are never billed, so a malformed filter string on row 14 costs you a retry, not a charge. Compare that with the generative route, where each of up to 100 variants per source is a fresh model run in Sora, Veo or Kling, priced in credits whose cost moves with model, duration and quality setting. Same arithmetic for GPU rentals in RunPod FFmpeg at $0.33/hr isn't cheap. Price it per video.

Pitfalls that cost you a re-render

Most failures in a variant batch are mechanical, and they all surface if you test one row before firing 20.

  • Cannot find a valid font for the family Sans means drawtext had no fontfile. Always pass an absolute path, and bundle the font if the render runs in a container.
  • width not divisible by 2 from libx264 comes from odd scale targets. Use -2 for the computed dimension, as in scale=1080:-2.
  • -c:a copy is fine for a hook burn, which doesn't touch audio. Re-encode to AAC if you change container or duration.
  • Screen-recorded or phone-exported masters often carry variable frame rate, which Amazon rejects on product listings. Normalize with -r 30 before the ratio pass.
  • Keep the hook bar out of the platform UI. TikTok and Reels overlay captions, handles and buttons across the top and bottom of a 1080x1920 frame, so a bar at y=ih*0.70 reads and a bar at y=ih*0.88 gets covered.
  • Don't render for placements that no longer exist. Meta's v26.0 changes apply to all remaining supported Marketing API versions on Oct 27, 2026, and the Messenger Stories story value in messenger_positions is silently removed from manual placements.

FAQ

Can I make bulk video ad variants from footage I already shot instead of generating new video with AI?

Yes, and for a Black Friday set it's the faster route. A hook variant only changes the opening text, and a ratio variant only changes framing, so both are deterministic FFmpeg passes over the master clip you already approved. Generative tools re-render the whole video, which means new footage to review and brand-check on every row. Meta's own in-platform generation has the same catch, covered in Meta generative video ads still leave you 3 render jobs.

What is the real last date to start the Black Friday variant batch?

The last comfortable start date is around Oct 29. Kive's checklist wants all four ratios cropped by Nov 5 and hero scenes approved by Oct 29, Plaid Testing closes paid media setup on Friday Nov 6, and Heat Marketers' plan ends pre-testing on Nov 12 before Black Friday on Nov 27. A render batch takes an afternoon; the approval loop around it is what eats the week.

Do I need all four aspect ratios for every variant?

Four ratios are for the winners, not for every hook test. Test hooks in the one ratio that gets the most spend, usually 9:16 for Reels and TikTok or 4:5 for Feed, then run the full 9:16, 1:1, 4:5 and 16:9 pass on the two or three variants that survive. That keeps the second pass at roughly 12 renders instead of 80.

Am I billed per variant or per second of video?

FFmpeg Micro bills per second of input video processed, so 20 renders of a 15-second master is 300 seconds, or 30 tokens, no matter how many filters each render applies. Failed jobs are never billed, and status checks and downloads are free.

How do I stop an n8n workflow from timing out on a 20-render batch?

Submit the job and poll it rather than waiting on one long HTTP request. The FFmpeg Micro node splits this into Create, Wait for Completion and Get Download URL, so the queueing call returns immediately. Driving the loop from a Google Sheet also means a failed row can be re-run on its own instead of restarting the batch.

The variant pass is the part of a Black Friday calendar that scales badly by hand and almost perfectly in a loop, which is the whole argument on our video ads page. Sign up free and the 200 tokens you start with cover this entire batch three times over.

About Javid Jamae

Founder & CEO at FFmpeg Micro

Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Skip the command line

The Text Hook Variants blueprint runs the same job for you: upload, done.

Run it (free)