This workflow corresponds to n8n.io template #10502 — we link there as the canonical source.
This workflow follows the Executecommand → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "NpOU5BmtmxwWbSzM",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Prompt-Based AI Video Creation with Auto Script, Voiceover & B-Roll Assembly",
"tags": [],
"nodes": [
{
"id": "cab91705-8229-4fa0-adc8-3fae3e7941d0",
"name": "Generate Video Script",
"type": "n8n-nodes-base.openAi",
"position": [
704,
144
],
"parameters": {
"model": "=gpt-3.5-turbo-instruct",
"options": {},
"requestOptions": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "cabbc4d2-3240-4698-90a2-6b5588820a21",
"name": "Parse Script into Scenes",
"type": "n8n-nodes-base.code",
"position": [
928,
144
],
"parameters": {
"jsCode": "const script = $input.first().json.choices[0].message.content;\n\n// Parse script into scenes\nconst scenes = [];\nconst lines = script.split('\\n').filter(line => line.trim());\n\nlet currentScene = {\n number: 1,\n voiceover: '',\n visuals: '',\n duration: 5\n};\n\nfor (const line of lines) {\n if (line.match(/^Scene \\d+:/i) || line.match(/^\\[Scene \\d+\\]/i)) {\n if (currentScene.voiceover) {\n scenes.push({...currentScene});\n currentScene = {\n number: scenes.length + 1,\n voiceover: '',\n visuals: '',\n duration: 5\n };\n }\n } else if (line.match(/^Voiceover:/i) || line.match(/^VO:/i)) {\n currentScene.voiceover += line.replace(/^(Voiceover:|VO:)/i, '').trim() + ' ';\n } else if (line.match(/^Visual:/i) || line.match(/^Visuals:/i)) {\n currentScene.visuals = line.replace(/^(Visual:|Visuals:)/i, '').trim();\n } else if (currentScene.voiceover === '') {\n currentScene.voiceover += line.trim() + ' ';\n }\n}\n\nif (currentScene.voiceover) {\n scenes.push(currentScene);\n}\n\n// If no structured scenes found, create single scene\nif (scenes.length === 0) {\n scenes.push({\n number: 1,\n voiceover: script,\n visuals: $input.first().json.prompt || 'relevant stock footage',\n duration: 10\n });\n}\n\nreturn scenes.map(scene => ({\n json: {\n sceneNumber: scene.number,\n voiceoverText: scene.voiceover.trim(),\n visualDescription: scene.visuals || 'stock footage',\n estimatedDuration: scene.duration,\n fullScript: script\n }\n}));"
},
"typeVersion": 2
},
{
"id": "42c325b8-a14b-4d37-924a-df40a60b829f",
"name": "Generate Voiceover (TTS)",
"type": "n8n-nodes-base.openAi",
"position": [
1600,
48
],
"parameters": {
"model": "=tts-1-hd",
"options": {},
"requestOptions": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "0848f454-0590-4bb6-b3f6-d9adaea778e4",
"name": "Search Stock Footage (Pexels)",
"type": "n8n-nodes-base.httpRequest",
"position": [
1152,
240
],
"parameters": {
"url": "https://api.pexels.com/videos/search",
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "query",
"value": "={{ $json.visualDescription }}"
},
{
"name": "per_page",
"value": "3"
},
{
"name": "size",
"value": "medium"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "453117f8-5a08-4693-90db-ed076639dbce",
"name": "Extract Video URLs",
"type": "n8n-nodes-base.code",
"position": [
1376,
240
],
"parameters": {
"jsCode": "const items = $input.all();\nconst result = [];\n\nfor (let i = 0; i < items.length; i++) {\n const item = items[i].json;\n \n // Get the first available video file\n let videoUrl = '';\n if (item.videos && item.videos.length > 0) {\n const video = item.videos[0];\n if (video.video_files && video.video_files.length > 0) {\n // Find HD quality video\n const hdVideo = video.video_files.find(vf => vf.quality === 'hd') || video.video_files[0];\n videoUrl = hdVideo.link;\n }\n }\n \n result.push({\n json: {\n sceneNumber: item.sceneNumber,\n videoUrl: videoUrl,\n videoId: item.videos?.[0]?.id || i,\n duration: item.videos?.[0]?.duration || 5\n }\n });\n}\n\nreturn result;"
},
"typeVersion": 2
},
{
"id": "52d7df36-7169-4a22-83f8-88c927c3d9b2",
"name": "Download B-Roll Footage",
"type": "n8n-nodes-base.httpRequest",
"position": [
1600,
240
],
"parameters": {
"url": "={{ $json.videoUrl }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.1
},
{
"id": "b0c2f48b-1f5e-46bc-8c16-5d44a9cb047a",
"name": "Merge Audio & Video",
"type": "n8n-nodes-base.merge",
"position": [
1824,
144
],
"parameters": {
"mode": "combine",
"options": {},
"mergeByFields": {
"values": [
{
"field1": "sceneNumber",
"field2": "sceneNumber"
}
]
}
},
"typeVersion": 2.1
},
{
"id": "51b579ee-a26a-4a5c-8924-0d87d2bb6014",
"name": "Generate Subtitles (SRT)",
"type": "n8n-nodes-base.code",
"position": [
2048,
144
],
"parameters": {
"jsCode": "// Generate SRT subtitle format\nconst items = $input.all();\nlet srtContent = '';\nlet startTime = 0;\n\nfor (let i = 0; i < items.length; i++) {\n const scene = items[i].json;\n const text = scene.voiceoverText || '';\n \n // Estimate duration based on text length (average speaking rate: 150 words/min)\n const words = text.split(' ').length;\n const duration = Math.max(3, Math.ceil((words / 150) * 60));\n \n const endTime = startTime + duration;\n \n // Format timestamps for SRT\n const formatTime = (seconds) => {\n const hrs = Math.floor(seconds / 3600);\n const mins = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n const ms = Math.floor((seconds % 1) * 1000);\n return `${String(hrs).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')},${String(ms).padStart(3, '0')}`;\n };\n \n srtContent += `${i + 1}\\n`;\n srtContent += `${formatTime(startTime)} --> ${formatTime(endTime)}\\n`;\n srtContent += `${text}\\n\\n`;\n \n startTime = endTime;\n}\n\nreturn [{\n json: {\n srtContent: srtContent,\n totalDuration: startTime\n },\n binary: {\n subtitles: {\n data: Buffer.from(srtContent).toString('base64'),\n mimeType: 'text/plain',\n fileName: 'subtitles.srt'\n }\n }\n}];"
},
"typeVersion": 2
},
{
"id": "7e8e2e9b-8a69-4350-b656-5d2f88b85853",
"name": "Assemble Final Video",
"type": "n8n-nodes-base.executeCommand",
"position": [
2272,
144
],
"parameters": {
"command": "# This is a placeholder for FFmpeg video assembly\n# In production, you would use FFmpeg or a video editing API\n\n# Example FFmpeg command structure:\n# ffmpeg -i voiceover.mp3 -i video1.mp4 -i video2.mp4 \\\n# -filter_complex \"[0:a]volume=1.0[a];[1:v][2:v]concat=n=2:v=1:a=0[v]\" \\\n# -map \"[v]\" -map \"[a]\" -c:v libx264 -c:a aac output.mp4\n\necho \"Video assembly requires FFmpeg installation\"\necho \"Total scenes: $(ls *.mp4 2>/dev/null | wc -l)\"\necho \"Voiceover files: $(ls *.mp3 2>/dev/null | wc -l)\"\necho \"Subtitle file: $(ls *.srt 2>/dev/null)\""
},
"typeVersion": 1
},
{
"id": "be8985a5-f16f-4fec-8053-844d13fe0faa",
"name": "Save to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
2496,
144
],
"parameters": {
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "f1b73ddf-266e-431e-85ac-910c925a0c09",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
16,
-464
],
"parameters": {
"width": 389,
"height": 444,
"content": "## How it works\n\nThis workflow transforms a simple text prompt into a complete video with voiceover, stock footage, and subtitles. It uses OpenAI to generate a structured script, converts text to speech, searches Pexels for matching B-roll footage, and assembles everything into video components ready for final editing.\n\n## Setup steps\n\n1. **Add API credentials**: Connect your OpenAI account and Pexels API key (free at pexels.com/api)\n2. **Configure Google Drive**: Set up Google Drive OAuth for video storage\n3. **Test the webhook**: Send a POST request with your video topic\n4. **Install FFmpeg**: Required for final video assembly (or use alternative video editing tool)\n\n**Note**: The final assembly step requires FFmpeg or a video editing service. All components (audio, video clips, subtitles) are prepared and can be manually edited if needed."
},
"typeVersion": 1
},
{
"id": "25b768b1-2e65-4bcc-968a-1fcef942946a",
"name": "Set Video Parameters",
"type": "n8n-nodes-base.set",
"position": [
256,
144
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a1b2c3d4",
"name": "prompt",
"type": "string",
"value": "Create a 60-second video about the benefits of morning exercise"
},
{
"id": "b2c3d4e5",
"name": "videoStyle",
"type": "string",
"value": "motivational"
},
{
"id": "c3d4e5f6",
"name": "targetDuration",
"type": "number",
"value": "60"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "5cbebc12-a5d1-4a5f-820f-e14e1fb27db3",
"name": "Prepare Script Prompt",
"type": "n8n-nodes-base.set",
"position": [
480,
144
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d4e5f6g7",
"name": "systemPrompt",
"type": "string",
"value": "You are a professional video script writer. Create a detailed video script with the following format:\n\nScene 1:\nVoiceover: [What the narrator says]\nVisual: [Description of what should be shown]\n\nScene 2:\nVoiceover: [What the narrator says]\nVisual: [Description of what should be shown]\n\nCreate 4-6 scenes for a {{ $('Set Video Parameters').item.json.targetDuration }}-second video about: {{ $('Set Video Parameters').item.json.prompt }}\n\nStyle: {{ $('Set Video Parameters').item.json.videoStyle }}\n\nMake the script engaging, concise, and suitable for stock footage visuals."
}
]
}
},
"typeVersion": 3.3
},
{
"id": "dca76e16-6d41-4baf-b3e2-677f498eeaae",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
32,
144
],
"parameters": {
"path": "2d562675-fada-4183-aca9-a95813e81819",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "4d2a9351-7718-4efa-a2d3-eada3e8aa353",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
16
],
"parameters": {
"color": 4,
"width": 528,
"height": 240,
"content": "## Input & Configuration\n\nReceives video prompt via webhook and sets parameters like duration, style, and prepares the AI script generation prompt."
},
"typeVersion": 1
},
{
"id": "74175936-d229-4cb5-95fa-7fefd1a341e5",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
16
],
"parameters": {
"color": 3,
"width": 304,
"height": 240,
"content": "## Script Generation\n\nUses OpenAI to create a structured video script with scenes, voiceover text, and visual descriptions."
},
"typeVersion": 1
},
{
"id": "f0be8b88-4549-4d86-a96f-72d618d7e700",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
-80
],
"parameters": {
"color": 5,
"width": 528,
"height": 336,
"content": "## Content Generation\n\nGenerates AI voiceover from script and searches Pexels for matching stock footage based on scene descriptions."
},
"typeVersion": 1
},
{
"id": "a2e42ac7-82b8-4e59-aa9e-eff1f790aa81",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
16
],
"parameters": {
"color": 2,
"width": 720,
"height": 240,
"content": "## Assembly & Export\n\nCombines audio and video clips, generates SRT subtitles, assembles final video, and uploads to Google Drive."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "f19a5bdd-8a23-4eb8-8040-b8b6096c6a94",
"connections": {
"Webhook": {
"main": [
[
{
"node": "Set Video Parameters",
"type": "main",
"index": 0
}
]
]
},
"Extract Video URLs": {
"main": [
[
{
"node": "Download B-Roll Footage",
"type": "main",
"index": 0
}
]
]
},
"Merge Audio & Video": {
"main": [
[
{
"node": "Generate Subtitles (SRT)",
"type": "main",
"index": 0
}
]
]
},
"Assemble Final Video": {
"main": [
[
{
"node": "Save to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Set Video Parameters": {
"main": [
[
{
"node": "Prepare Script Prompt",
"type": "main",
"index": 0
}
]
]
},
"Generate Video Script": {
"main": [
[
{
"node": "Parse Script into Scenes",
"type": "main",
"index": 0
}
]
]
},
"Prepare Script Prompt": {
"main": [
[
{
"node": "Generate Video Script",
"type": "main",
"index": 0
}
]
]
},
"Download B-Roll Footage": {
"main": [
[
{
"node": "Merge Audio & Video",
"type": "main",
"index": 1
}
]
]
},
"Generate Subtitles (SRT)": {
"main": [
[
{
"node": "Assemble Final Video",
"type": "main",
"index": 0
}
]
]
},
"Generate Voiceover (TTS)": {
"main": [
[
{
"node": "Merge Audio & Video",
"type": "main",
"index": 0
}
]
]
},
"Parse Script into Scenes": {
"main": [
[
{
"node": "Generate Voiceover (TTS)",
"type": "main",
"index": 0
},
{
"node": "Search Stock Footage (Pexels)",
"type": "main",
"index": 0
}
]
]
},
"Search Stock Footage (Pexels)": {
"main": [
[
{
"node": "Extract Video URLs",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleDriveOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automatically creates complete videos from a text prompt—script, voiceover, stock footage, and subtitles all assembled and ready.
Source: https://n8n.io/workflows/10502/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Transforms provider documentation (URLs) into an auditable, enforceable multicloud security control baseline. It: Fetches and sanitizes HTML Uses AI to extract security requirements* (strict 3-line TX
Listens for completed Fireflies transcripts, qualifies whether a proposal is needed using OpenAI, drafts structured proposal content, populates a Google Doc template, converts to PDF, and sends it to
This system meticulously guides each lead through a fully automated journey, from initial contact to a personalized follow-up and CRM integration.
A smart, fully automated coding pipeline built inside n8n that leverages Cursor AI to write, refactor, review, and optimize code projects — triggered by a webhook, schedule, or manual prompt. Every ou
Build a fully automated music generation workflow in n8n using Suno to create and store AI-generated songs.