{ "name": "Remove Video Background & Compose on Custom Background with Google Drive", "nodes": [ { "parameters": { "height": 580, "width": 520, "content": "## šŸŽ¬ Video Background Removal & Composition\n\n**What it does:**\n- Removes background from ANY video (AI actors, product demos, webcam footage, etc.)\n- Composites foreground onto custom background video\n- Mixes audio from both videos\n- Saves final result to Google Drive\n\n**Perfect for:**\n- AI UGC ad creators (HeyGen, Synthesia, D-ID)\n- E-commerce product videos with branded backgrounds\n- Social media content with custom scenes\n- Webcam/talking head videos on professional backgrounds\n- Sports training videos with clean backgrounds\n\n**Processing time:** 3-5 minutes per minute of video\n\n**Setup:** ~7 minutes total\n\n[šŸ“– Full Documentation](https://docs.videobgremover.com/)" }, "id": "sticky-overview", "name": "šŸ“‹ Overview", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-1100, 60], "notesTextSize": "large", "notesBackgroundColor": 4 }, { "parameters": { "height": 360, "width": 380, "content": "## šŸ”‘ API Key Setup (Required)\n\n**Step 1:** Get your API key\n- Visit: https://videobgremover.com/api-management\n- Sign up (free tier available)\n- Copy your API key\n\n**Step 2:** Add to n8n environment variables\n- Go to: Settings → Variables\n- Add new variable:\n - Name: `VIDEOBGREMOVER_KEY`\n - Value: your API key\n- Save\n\n**Pricing:** $0.50-$2.00 per minute processed\n\nāœ… This workflow uses `$vars.VIDEOBGREMOVER_KEY` (secure)" }, "id": "sticky-api-key", "name": "šŸ”‘ API Key Setup", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-480, 60] }, { "parameters": { "height": 280, "width": 380, "content": "## šŸ“„ Input Videos Required\n\n**Foreground video:** Subject with any background\n- AI actors (HeyGen, Synthesia, D-ID)\n- Product demonstrations\n- Webcam/talking head footage\n- Sports/training content\n\n**Background video:** Your custom scene\n- Brand environments\n- Stock footage\n- Custom locations\n- Animated backgrounds\n\nāš ļø Both must be **publicly accessible URLs**" }, "id": "sticky-inputs", "name": "šŸ“„ Inputs", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-1100, 660] }, { "parameters": { "height": 360, "width": 380, "content": "## šŸŽØ Composition Template\n\n**Template:** `ai_ugc_ad`\n- Positions foreground in bottom-right corner\n- 35% of canvas size\n- Slight transparency for polish (95% opacity)\n- Perfect for AI avatars over product backgrounds\n\n**Audio mixing:**\n- Background audio: 30% volume\n- Foreground audio: 100% volume\n- Smooth audio blending\n\n**Export:**\n- Format: H.264 (MP4)\n- Preset: Medium (balanced quality/speed)\n\n*Customize these in the \"Start Composition\" node*" }, "id": "sticky-composition", "name": "šŸŽØ Composition", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-480, 460] }, { "parameters": { "height": 300, "width": 380, "content": "## šŸ”„ Processing & Polling\n\n**How it works:**\n1. Job submitted to API\n2. Background removal starts (20-60 sec)\n3. Composition applied\n4. Status checked every 20 seconds\n5. When complete → download & upload\n\n**Status flow:**\n- `processing` → Wait 20s → Check again\n- `completed` → Download video\n- `failed` → Return error details\n\nā±ļø Typical: 3-5 min per min of video" }, "id": "sticky-polling", "name": "šŸ”„ Polling", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-60, 60] }, { "parameters": { "height": 280, "width": 380, "content": "## šŸ’¾ Google Drive Setup\n\n**Step 1:** Connect Google Drive\n- Click \"Upload to Google Drive\" node\n- Click \"Connect\"\n- Authorize n8n\n\n**Step 2:** Choose folder (optional)\n- Default: Root of \"My Drive\"\n- Or select specific folder\n\n**Output:**\n- Permanent shareable link\n- Direct download URL\n- File metadata\n\nā±ļø Setup time: ~2 minutes" }, "id": "sticky-gdrive", "name": "šŸ’¾ Google Drive", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [540, 60] }, { "parameters": { "height": 340, "width": 380, "content": "## šŸš€ How to Use\n\n**Manual testing:**\n1. Update video URLs in \"Sample Inputs (manual)\"\n2. Click \"Execute Workflow\"\n3. Wait for processing (3-5 min per min of video)\n4. Check Google Drive for result\n\n**Webhook automation:**\n1. Activate workflow\n2. Copy webhook URL\n3. POST to webhook:\n```json\n{\n \"foreground_video_url\": \"https://...\",\n \"background_video_url\": \"https://...\"\n}\n```\n\n**Batch processing:** Connect to Google Sheets or Airtable for bulk automation" }, "id": "sticky-usage", "name": "šŸš€ Usage", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [1140, 60] }, { "parameters": { "httpMethod": "POST", "path": "compose-video", "responseMode": "responseNode", "options": { "responseData": "allEntries" } }, "id": "webhook-1", "name": "Webhook Trigger", "type": "n8n-nodes-base.webhook", "typeVersion": 1.1, "position": [-1040, 900], "webhookId": "compose-video" }, { "parameters": {}, "id": "manual-1", "name": "Manual Trigger", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [-1040, 1040] }, { "parameters": { "assignments": { "assignments": [ { "name": "foreground_video_url", "value": "={{ $json.body?.foreground_video_url ?? $json.foreground_video_url ?? 'https://videos.videobgremover.com/public-videos/assets/ai-actor.mp4' }}", "type": "string" }, { "name": "background_video_url", "value": "={{ $json.body?.background_video_url ?? $json.background_video_url ?? 'https://videos.videobgremover.com/public-videos/assets/vertical_background.mp4' }}", "type": "string" }, { "name": "source", "value": "webhook", "type": "string" } ] } }, "id": "set-web-1", "name": "Extract Webhook Data", "type": "n8n-nodes-base.set", "typeVersion": 3.3, "position": [-820, 900] }, { "parameters": { "assignments": { "assignments": [ { "name": "foreground_video_url", "value": "https://videos.videobgremover.com/public-videos/assets/ai-actor.mp4", "type": "string" }, { "name": "background_video_url", "value": "https://videos.videobgremover.com/public-videos/assets/vertical_background.mp4", "type": "string" }, { "name": "source", "value": "manual", "type": "string" } ] } }, "id": "set-manual-1", "name": "Sample Video URLs (Edit Here)", "type": "n8n-nodes-base.set", "typeVersion": 3.3, "position": [-820, 1040] }, { "parameters": { "mode": "append", "options": {} }, "id": "merge-1", "name": "Merge Triggers", "type": "n8n-nodes-base.merge", "typeVersion": 2.1, "position": [-600, 970] }, { "parameters": { "method": "POST", "url": "https://api.videobgremover.com/api/v1/jobs", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-API-Key", "value": "={{ $vars.VIDEOBGREMOVER_KEY }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={ \"video_url\": \"{{ $json.foreground_video_url }}\" }", "options": { "response": { "response": { "responseFormat": "json", "neverError": true } } } }, "id": "http-1", "name": "1. Create Job (Upload Foreground)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [-380, 970] }, { "parameters": { "method": "POST", "url": "=https://api.videobgremover.com/api/v1/jobs/{{ $json.id }}/start", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-API-Key", "value": "={{ $vars.VIDEOBGREMOVER_KEY }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"background\": {\n \"type\": \"composition\",\n \"composition\": {\n \"template\": \"ai_ugc_ad\",\n \"background_type\": \"video\",\n \"background_url\": \"{{ $('Merge Triggers').item.json.background_video_url }}\",\n \"background_audio_enabled\": true,\n \"background_audio_volume\": 0.3,\n \"export_format\": \"h264\",\n \"export_preset\": \"medium\"\n }\n }\n}", "options": { "response": { "response": { "responseFormat": "json", "neverError": true } } } }, "id": "http-2", "name": "2. Start Composition", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [-140, 970] }, { "parameters": { "method": "GET", "url": "=https://api.videobgremover.com/api/v1/jobs/{{ $('1. Create Job (Upload Foreground)').item.json.id }}/status", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-API-Key", "value": "={{ $vars.VIDEOBGREMOVER_KEY }}" } ] }, "options": { "response": { "response": { "responseFormat": "json", "neverError": true } } } }, "id": "http-3", "name": "3. Check Job Status", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [100, 970] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "is_completed_condition", "leftValue": "={{ $json.status }}", "rightValue": "completed", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "options": {} }, "id": "if-complete", "name": "Is Complete?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [300, 970] }, { "parameters": { "url": "={{ $json.processed_video_url }}", "options": { "response": { "response": { "responseFormat": "file" } } } }, "id": "download", "name": "4. Download Video", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [520, 830] }, { "parameters": { "operation": "upload", "binaryPropertyName": "data", "name": "=composed_video_{{ $('1. Create Job (Upload Foreground)').item.json.id }}_{{ new Date().getTime() }}.mp4", "driveId": { "__rl": true, "mode": "list", "value": "My Drive" }, "folderId": { "__rl": true, "mode": "list", "value": "root" }, "options": { "googleFileConvert": false, "simplifyOutput": true } }, "id": "gdrive", "name": "5. Upload to Google Drive", "type": "n8n-nodes-base.googleDrive", "typeVersion": 3, "position": [740, 830] }, { "parameters": { "assignments": { "assignments": [ { "name": "final_result", "type": "object", "value": "={{ {\n success: true,\n job_id: $('1. Create Job (Upload Foreground)').item.json.id,\n export_id: $('2. Start Composition').item.json.export_id,\n google_drive_id: $json.id,\n google_drive_url: $json.webViewLink,\n download_url: $('3. Check Job Status').item.json.processed_video_url,\n message: 'Video composed successfully and saved to Google Drive',\n filename: $json.name,\n video_length_seconds: $('3. Check Job Status').item.json.length_seconds,\n source: $('Merge Triggers').item.json.source\n} }}" } ] } }, "id": "success-set", "name": "Build Success Response", "type": "n8n-nodes-base.set", "typeVersion": 3.3, "position": [960, 830] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "is_failed_condition", "leftValue": "={{ $json.status }}", "rightValue": "failed", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "options": {} }, "id": "if-failed", "name": "Has Failed?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [500, 1200] }, { "parameters": { "amount": 20, "unit": "seconds" }, "id": "wait-20", "name": "Wait 20s", "type": "n8n-nodes-base.wait", "typeVersion": 1.1, "position": [720, 1340] }, { "parameters": { "assignments": { "assignments": [ { "name": "final_result", "type": "object", "value": "={{ {\n success: false,\n job_id: $('1. Create Job (Upload Foreground)').item.json.id,\n error: $json.error || 'Video composition failed',\n status: $json.status,\n message: 'Failed to compose video',\n source: $('Merge Triggers').item.json.source\n} }}" } ] } }, "id": "error-set", "name": "Build Error Response", "type": "n8n-nodes-base.set", "typeVersion": 3.3, "position": [720, 1200] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "is_webhook_condition", "leftValue": "={{ $json.final_result?.source ?? $json.source }}", "rightValue": "webhook", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "options": {} }, "id": "if-webhook", "name": "From Webhook?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [1180, 1010] }, { "parameters": { "responseBody": "={{ $json.final_result ?? $json }}", "responseCode": 200 }, "id": "respond", "name": "Respond to Webhook", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.1, "position": [1400, 920] }, { "parameters": { "assignments": { "assignments": [ { "name": "final_result", "type": "object", "value": "={{ $json.final_result ?? $json }}" } ] } }, "id": "end-manual", "name": "Manual Test Complete", "type": "n8n-nodes-base.set", "typeVersion": 3.3, "position": [1400, 1100] } ], "connections": { "Webhook Trigger": { "main": [[{ "node": "Extract Webhook Data", "type": "main", "index": 0 }]] }, "Manual Trigger": { "main": [[{ "node": "Sample Video URLs (Edit Here)", "type": "main", "index": 0 }]] }, "Extract Webhook Data": { "main": [[{ "node": "Merge Triggers", "type": "main", "index": 0 }]] }, "Sample Video URLs (Edit Here)": { "main": [[{ "node": "Merge Triggers", "type": "main", "index": 1 }]] }, "Merge Triggers": { "main": [[{ "node": "1. Create Job (Upload Foreground)", "type": "main", "index": 0 }]] }, "1. Create Job (Upload Foreground)": { "main": [[{ "node": "2. Start Composition", "type": "main", "index": 0 }]] }, "2. Start Composition": { "main": [[{ "node": "3. Check Job Status", "type": "main", "index": 0 }]] }, "3. Check Job Status": { "main": [[{ "node": "Is Complete?", "type": "main", "index": 0 }]] }, "Is Complete?": { "main": [ [{ "node": "4. Download Video", "type": "main", "index": 0 }], [{ "node": "Has Failed?", "type": "main", "index": 0 }] ] }, "4. Download Video": { "main": [[{ "node": "5. Upload to Google Drive", "type": "main", "index": 0 }]] }, "5. Upload to Google Drive": { "main": [[{ "node": "Build Success Response", "type": "main", "index": 0 }]] }, "Build Success Response": { "main": [[{ "node": "From Webhook?", "type": "main", "index": 0 }]] }, "Has Failed?": { "main": [ [{ "node": "Build Error Response", "type": "main", "index": 0 }], [{ "node": "Wait 20s", "type": "main", "index": 0 }] ] }, "Build Error Response": { "main": [[{ "node": "From Webhook?", "type": "main", "index": 0 }]] }, "Wait 20s": { "main": [[{ "node": "3. Check Job Status", "type": "main", "index": 0 }]] }, "From Webhook?": { "main": [ [{ "node": "Respond to Webhook", "type": "main", "index": 0 }], [{ "node": "Manual Test Complete", "type": "main", "index": 0 }] ] } }, "settings": { "executionOrder": "v1" } }