Workflow · n8n automation

A sheet row in, a brainrot reel out

How my Peter in Tech channel makes its explainer reels. Two voices talk through a tech topic over Minecraft parkour: S asks the questions, P explains. Claude writes the dialogue, Coqui clones the voices, Remotion builds the video and n8n runs every step on my laptop. No paid APIs.

11reels rendered
226dialogue lines voiced
2cloned voices
11background clips
18n8n nodes
0paid APIs

The big picture

Three lanes of work run side by side, and n8n is the conductor. The writing lane decides what gets said, the voice lane turns every line into speech in a cloned voice, and the visuals lane supplies the background and the two speakers. Remotion is where they meet.

row marked completed + video linkWRITINGVOICEVISUALSn8n, the conductorReads the sheet, calls each service in turn,waits for the render, writes the result back.self-hosted18 nodesClaudeWrites a two-voice dialogue:S asks, P explains. Plus a caption.ClaudeGoogle SheetOne row per reel: topic, script,caption, status.Google Sheetsvideo_010Physical AIcompletedvideo_011Kunal Shahcompletedvideo_012next topicreadyFFmpegPreps the reference audiofor each voice.FFmpegCoqui TTSOpen-source speech model,running on the laptop.Coqui:8000Voice cloningEvery line spoken in S's or P'scloned voice, one WAV per line.CoquiWAVSPBackground clips11 Minecraft parkour clips,hosted on Cloudinary.CloudinarySpeakers + pickArtwork for S and P, plus onerandom clip per reel.n8n codeRemotionBuilds the video in React: backgroundclip, the speaker who is talking,and their voice, scene by scene.Remotion:3000clipvoiceartPPPPPeach block = one line, as long as its audioframes = audio seconds × 30 + 5FFmpeg encodeRemotion hands frames andaudio to FFmpeg: out comesthe MP4.FFmpegMP4SPWhat even is RAG?@peterintech.ai9:16 MP4 → Instagram sheet row marked completed ↑all three lanes merge hereWRITINGVOICEVISUALSn8n, the conductorReads the sheet, calls each service in turn,waits for the render, writes the result back.self-hosted18 nodesClaudeWrites a two-voice dialogue:S asks, P explains. Plus a caption.ClaudeGoogle SheetOne row per reel: topic, script,caption, status.Google Sheetsvideo_010Physical AIcompletedvideo_011Kunal Shahcompletedvideo_012next topicreadyFFmpegPreps referenceaudio per voice.FFmpegCoqui TTSOpen-sourcespeech model.CoquiVoice cloningEvery line spoken in S's or P'scloned voice, one WAV per line.CoquiWAVSPBackground clips11 Minecraft parkour clips,hosted on Cloudinary.CloudinarySpeakers + pickArtwork for S and P, plus onerandom clip per reel.n8n codeRemotionBuilds the video in React: backgroundclip, the speaker who is talking,and their voice, scene by scene.Remotion:3000clipvoiceartPPPPPeach block = one line, as long as its audioframes = audio seconds × 30 + 5FFmpeg encodeRemotion hands frames andaudio to FFmpeg: out comesthe MP4.FFmpegMP4SPWhat even is RAG?@peterintech.ai9:16 MP4 → Instagram
content moving between tools n8n calling a service result written back to the sheet

Inside the n8n workflow

The real workflow, step by step. One run makes one reel: it picks the next row marked “ready”, voices every line, asks Remotion to render, then keeps checking until the video is done and writes the link back to the sheet.

noyesyesnot yetask again until the render finishesPICK A ROW← VOICES AND PAYLOADRENDER AND WAIT1Execute workflowStarted by hand, one reelper run.Manual trigger6Split OutOne item per dialogue line,so each gets its own audio.Split Out11Wait2 seconds before the firststatus check.Wait2Get rowsReads the content queuesheet.Google Sheets7Generate TTSPOST text + speaker to Coqui,get a WAV in the cloned voice.HTTP:80002 tries12Check render statusGET /renders/{jobId}returns queued, done or failed.HTTP:30003FilterKeeps only rows wherestatus = “ready”.Filter8Save audio + durationSaves each WAV for Remotion,reads its length from the header.Code:808013Render failed?If status = failed, takethe error branch.If4LimitTakes the first ready row,so one reel per run.Limit9Pick clip + payload1 random clip of 11, speakerart, all scenes + caption.Code14Render done?If status = completed, thevideo is ready. Else wait.If5Prepare scriptParses script_json; every lineneeds speaker S or P + text.Code10Send to RemotionPOST /renders starts a renderjob and returns its id.HTTP:300015Video readyCollects video URL, file path,job id and caption.Code16Update rowSets status = completed withjobId, videoUrl, processedAt.Google SheetsStop with errorThrows Remotion's fullresponse so it shows in n8n.CodeWait + retry100 seconds, then checkthe status again.Wait noyes1Execute workflowStarted by hand, one reelper run.Manual trigger2Get rowsReads the content queuesheet.Google Sheets3FilterKeeps only rows wherestatus = “ready”.Filter4LimitTakes the first ready row,so one reel per run.Limit5Prepare scriptParses script_json; every lineneeds speaker S or P + text.Code6Split OutOne item per dialogue line,so each gets its own audio.Split Out7Generate TTSPOST text + speaker to Coqui,get a WAV in the cloned voice.HTTP:80002 tries8Save audio + durationSaves each WAV for Remotion,reads its length from the header.Code:80809Pick clip + payload1 random clip of 11, speakerart, all scenes + caption.Code10Send to RemotionPOST /renders starts a renderjob and returns its id.HTTP:300011Wait2 seconds before the firststatus check.Wait12Check render statusGET /renders/{jobId}returns queued, done or failed.HTTP:300013Render failed?If status = failed, takethe error branch.Ifyes → stop with an error14Render done?If status = completed, thevideo is ready. Else wait.Ifno → wait 100 s, check again ↺15Video readyCollects video URL, file path,job id and caption.Code16Update rowSets status = completed withjobId, videoUrl, processedAt.Google Sheets
the main path polling loop render failed

What the data looks like

1 · A row in the sheet

Claude writes the dialogue as JSON; I paste it in and set the status to ready.

id      video_002
topic   What Are RAGs
status  ready
script_json [
  {"actor":"S", "text":"Everyone keeps saying RAG. What even is it?"},
  {"actor":"P", "text":"RAG stands for Retrieval Augmented Generation. Fancy words for a simple idea."},
  … 16 more lines
]

2 · One scene after the voice step

Each line now has its own WAV file and an exact length in frames (30 fps, plus 5 frames of breathing room).

{
  "actor": "S",
  "text": "Everyone keeps saying RAG. What even is it?",
  "audioUrl": "http://127.0.0.1:8080/audio/000_S_….wav",
  "durationInFrames": 104
}
// example: 3.3 s of audio → 99 + 5 = 104 frames

3 · What Remotion receives

One request starts the render; n8n then polls the job until it reports completed or failed.

POST :3000/renders
{
  "scenes": [ … 18 scenes … ],
  "backgroundVideoUrl": 1 of 11 clips,
  "postCaption": "Everyone is throwing…"
}
→ { "jobId": "db945c0d-…" }
GET :3000/renders/db945c0d-…
→ { "status": "completed" }

What it made

A reel from @peterintech.ai · open on Instagram ↗

Eight of these came out of one afternoon on 18 June, about one every 8 minutes.

RowTopicLinesWordsRendered
video_001What Are AI Agents? (In Depth, with Example, vs Chatbots and Workflows)3047618 Jun
video_002What Are RAGs1822418 Jun
video_003What Are MCPs (Model Context Protocol)1824018 Jun
video_004What Are Vector Databases1821618 Jun
video_005Fine-Tuning vs RAG1824118 Jun
video_006Tools vs Memory in AI and Why AI Hallucinates1823418 Jun
video_007Easter Eggs in Apps2028918 Jun
video_008CORS Error Explained2029918 Jun
video_009SpaceX Buys Cursor for 60 Billion and What Elon Is Really Thinking2238622 Jun
video_0010Embodied and Physical AI and Who Is Leading It2238422 Jun
video_0011Kunal Shah Leaves CRED to Become WhatsApp's Global CEO2240322 Jun

226 lines and 3,392 words of dialogue across 11 reels, all rendered in June 2026. The channel is paused for now.

Want to build this yourself?

I'm writing the whole pipeline up as a step-by-step PDF: the n8n workflow, the voice setup, the Remotion project and the mistakes to skip.

Get the workflow PDF →