AutomationFlowsAI & RAG › Turn Long Videos Into Social Shorts with Renderio and Openai

Turn Long Videos Into Social Shorts with Renderio and Openai

ByRenderIO @hodho on n8n.io

Content creators, YouTubers, and social media managers who want to repurpose long form videos into short clips without doing it manually. Works on self hosted n8n instances.

Event trigger★★★★★ complexityAI-powered46 nodesGoogle Drive TriggerGoogle DriveN8N Nodes RenderioHTTP RequestOpenAIGoogle Sheets
AI & RAG Trigger: Event Nodes: 46 Complexity: ★★★★★ AI nodes: yes Added:
Turn Long Videos Into Social Shorts with Renderio and Openai — n8n workflow card showing Google Drive Trigger, Google Drive, N8N Nodes Renderio integration

This workflow corresponds to n8n.io template #15132 — we link there as the canonical source.

This workflow follows the Google Drive → Google Drive Trigger 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 →

Download .json
{
  "id": "18dZrILI3scxPcnj",
  "name": "Turn Long Videos into Shorts",
  "tags": [
    {
      "id": "Zkn4MatBRsM3Cbvi",
      "name": "managed-as-code",
      "createdAt": "2026-04-05T12:17:54.478Z",
      "updatedAt": "2026-04-05T12:17:54.478Z"
    }
  ],
  "nodes": [
    {
      "id": "59efe8ae-afaf-4d3b-87b5-0c86140086b1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Turn Long Videos into Shorts\n\n### How it works\n\n1. The workflow begins by monitoring a Google Drive folder for new video files.\n2. Once a video file is detected, it is downloaded and uploaded to RenderIO for processing.\n3. The audio is extracted and transcribed using Whisper, then the transcript is uploaded to Google Drive.\n4. Transcripts are merged and OpenAI suggests highlight clips, which are then validated and rendered.\n5. Rendered clips are downloaded in various formats and uploaded back to Google Drive.\n6. The workflow concludes by appending details of the operation to a Google Sheets log.\n\n### Setup steps\n\n- [ ] Set up Google Drive and RenderIO credentials to allow file uploads and downloads.\n- [ ] Configure OpenAI API access for transcript processing and clip suggestion.\n- [ ] Prepare Google Sheets with the necessary structure to log operations.\n\n### Customization\n\nAdjust the number of clips or formats rendered by modifying the configuration settings in the 'Set Config' node."
      },
      "typeVersion": 1
    },
    {
      "id": "acd5dbb5-c53a-4294-b5a3-72d181746982",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        512
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Monitor drive for videos\n\nTriggers the workflow by watching a Google Drive folder for new video files."
      },
      "typeVersion": 1
    },
    {
      "id": "08f9f1d5-91fe-4f83-98d7-7d89ef55edcd",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        512
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 304,
        "content": "## Handle video upload\n\nDownloads the video from Google Drive and uploads it to RenderIO for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "89174dc8-3ae3-4703-9da0-318ee3d29d1d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        512
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Create folder and extract audio\n\nCreates an output folder in Google Drive and extracts audio from the video using RenderIO."
      },
      "typeVersion": 1
    },
    {
      "id": "0291628d-3827-416a-aa4a-41628d30c62c",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 480,
        "content": "## Audio status management\n\nManages the waiting and checking of audio extraction process to ensure it's ready for further processing."
      },
      "typeVersion": 1
    },
    {
      "id": "ed6648ec-3dc0-4d4d-8caf-6a2fe179f450",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2624,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Audio transcription\n\nDownloads the extracted audio and transcribes it using Whisper."
      },
      "typeVersion": 1
    },
    {
      "id": "3bb22442-00b2-46f8-9acb-efe50e1415be",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3072,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 496,
        "content": "## Build and upload transcripts\n\nProcesses transcripts into text and SRT formats and uploads them to Google Drive."
      },
      "typeVersion": 1
    },
    {
      "id": "08fc6aa4-7845-4e4f-a395-ede4ce9d7c72",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3520,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Merge and analyze transcripts\n\nMerges transcripts and uses OpenAI to pick potential video clips for highlights."
      },
      "typeVersion": 1
    },
    {
      "id": "c9e8cba7-832e-4f13-a4ea-3eaa0ae5362a",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3968,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 336,
        "content": "## Validate and render clips\n\nValidates clip suggestions and sends them for rendering via HTTP requests."
      },
      "typeVersion": 1
    },
    {
      "id": "c90dd34b-84b2-4967-b4d5-85fabc42feea",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4864,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 608,
        "content": "## Render status management\n\nMonitors and checks the rendering status, waiting if necessary."
      },
      "typeVersion": 1
    },
    {
      "id": "bcc305d0-cffc-4ab6-a097-84dcd20d14f8",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5760,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 688,
        "content": "## Download and upload clips\n\nDownloads rendered clips in different formats and uploads them to Google Drive."
      },
      "typeVersion": 1
    },
    {
      "id": "b8c1403e-ddd7-4f54-b515-3b9a24d5f444",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5984,
        720
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Log clip details\n\nAppends details of each clip and overall run to Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "n1",
      "name": "Google Drive Folder Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        208,
        640
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "id",
          "value": "1czZfoTE5kL7VIv1SspKK3gqOPrLjGI6X"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n2",
      "name": "Set Configuration Parameters",
      "type": "n8n-nodes-base.set",
      "position": [
        432,
        640
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-clipCount",
              "name": "clipCount",
              "type": "number",
              "value": 5
            },
            {
              "id": "cfg-outputParentFolderId",
              "name": "outputParentFolderId",
              "type": "string",
              "value": "1Op9gdmBQXUM2VQbjTlhBnLcIba4tcOZH"
            },
            {
              "id": "cfg-sheetId",
              "name": "sheetId",
              "type": "string",
              "value": "1gfg98qMzRCMjwG2vPw9IPewvWDcaGdYjJCfXxf-8LJI"
            },
            {
              "id": "cfg-sheetTab",
              "name": "sheetTab",
              "type": "string",
              "value": "1456743167"
            },
            {
              "id": "cfg-sheetRunsTab",
              "name": "sheetRunsTab",
              "type": "string",
              "value": "416381150"
            },
            {
              "id": "cfg-llmModel",
              "name": "llmModel",
              "type": "string",
              "value": "gpt-4o-mini"
            },
            {
              "id": "cfg-fileId",
              "name": "sourceFileId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "cfg-fileName",
              "name": "sourceFileName",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "cfg-sourceUrl",
              "name": "sourceDriveUrl",
              "type": "string",
              "value": "={{ $json.webViewLink || ('https://drive.google.com/file/d/' + $json.id + '/view') }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "n4",
      "name": "Download Video from Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        656,
        640
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.sourceFileId }}"
        },
        "options": {
          "binaryPropertyName": "data"
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n5",
      "name": "Upload Video to RenderIO",
      "type": "n8n-nodes-renderio.renderio",
      "position": [
        880,
        640
      ],
      "parameters": {
        "resource": "file",
        "operation": "upload"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n5b",
      "name": "Retrieve RenderIO File",
      "type": "n8n-nodes-renderio.renderio",
      "position": [
        1104,
        640
      ],
      "parameters": {
        "fileId": "={{ $('Upload Video to RenderIO').item.json.file_id }}",
        "resource": "file"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n6",
      "name": "Create Google Drive Folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1328,
        640
      ],
      "parameters": {
        "name": "={{ $('Set Configuration Parameters').item.json.sourceFileName.replace(/\\.[^.]+$/, '') }} \u2014 shorts {{ $now.toFormat('yyyy-MM-dd HHmm') }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.outputParentFolderId }}"
        },
        "resource": "folder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n7",
      "name": "Extract Audio with RenderIO",
      "type": "n8n-nodes-renderio.renderio",
      "position": [
        1552,
        640
      ],
      "parameters": {
        "inputFiles": {
          "fileValues": [
            {
              "value": "={{ $('Retrieve RenderIO File').item.json.storage_url }}"
            }
          ]
        },
        "outputFiles": {
          "fileValues": [
            {
              "key": "out_audio",
              "value": "audio.mp3"
            }
          ]
        },
        "ffmpegCommand": "-i {{in_video}} -vn -c:a libmp3lame -q:a 4 {{out_audio}}"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n8",
      "name": "Wait 10 Seconds for Audio",
      "type": "n8n-nodes-base.wait",
      "position": [
        1776,
        640
      ],
      "parameters": {
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "n9",
      "name": "Verify Audio Extraction",
      "type": "n8n-nodes-renderio.renderio",
      "position": [
        2000,
        640
      ],
      "parameters": {
        "commandId": "={{ $('Extract Audio with RenderIO').item.json.command_id }}",
        "operation": "get"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n10",
      "name": "If Audio is Ready",
      "type": "n8n-nodes-base.if",
      "position": [
        2224,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "audio-status-check",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Verify Audio Extraction').item.json.status }}",
              "rightValue": "SUCCESS"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "n11",
      "name": "Wait 30 Seconds for Audio Retry",
      "type": "n8n-nodes-base.wait",
      "position": [
        2448,
        736
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "n12",
      "name": "Download Extracted Audio",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2672,
        512
      ],
      "parameters": {
        "url": "={{ $('Verify Audio Extraction').item.json.output_files.out_audio.storage_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n13",
      "name": "Transcribe Audio with Whisper",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2896,
        512
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/audio/transcriptions",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            },
            {
              "name": "model",
              "value": "whisper-1"
            },
            {
              "name": "response_format",
              "value": "verbose_json"
            },
            {
              "name": "timestamp_granularities[]",
              "value": "segment"
            }
          ]
        },
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n14",
      "name": "Generate Transcript Files",
      "type": "n8n-nodes-base.code",
      "position": [
        3120,
        512
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const t = $input.item.json;\nconst segments = Array.isArray(t.segments) ? t.segments : [];\nconst fullText = t.text || segments.map(s => (s.text || '').trim()).join(' ');\n\nfunction fmt(sec) {\n\tconst ms = Math.round(sec * 1000);\n\tconst h = Math.floor(ms / 3600000);\n\tconst m = Math.floor((ms % 3600000) / 60000);\n\tconst s = Math.floor((ms % 60000) / 1000);\n\tconst mil = ms % 1000;\n\tconst pad = (n, w = 2) => String(n).padStart(w, '0');\n\treturn `${pad(h)}:${pad(m)}:${pad(s)},${pad(mil, 3)}`;\n}\n\nlet srt = '';\nsegments.forEach((seg, i) => {\n\tsrt += `${i + 1}\\n${fmt(seg.start)} --> ${fmt(seg.end)}\\n${(seg.text || '').trim()}\\n\\n`;\n});\nif (!srt) {\n\tsrt = `1\\n00:00:00,000 --> 00:00:10,000\\n${fullText}\\n\\n`;\n}\n\nconst toBin = (text, mimeType, ext, fileName) => ({\n\tdata: Buffer.from(text, 'utf8').toString('base64'),\n\tmimeType,\n\tfileExtension: ext,\n\tfileName,\n});\n\nreturn {\n\tjson: {\n\t\tfullText,\n\t\tsegments,\n\t\tduration: t.duration || (segments.length ? segments[segments.length - 1].end : null),\n\t\tlanguage: t.language || null,\n\t},\n\tbinary: {\n\t\ttxt: toBin(fullText, 'text/plain', 'txt', 'transcript.txt'),\n\t\tsrt: toBin(srt, 'application/x-subrip', 'srt', 'transcript.srt'),\n\t},\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "n15",
      "name": "Upload TXT Transcript to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3344,
        416
      ],
      "parameters": {
        "name": "transcript.txt",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Google Drive Folder').item.json.id }}"
        },
        "inputDataFieldName": "txt"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n16",
      "name": "Upload SRT Transcript to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3344,
        608
      ],
      "parameters": {
        "name": "transcript.srt",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Google Drive Folder').item.json.id }}"
        },
        "inputDataFieldName": "srt"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n17",
      "name": "Merge Transcripts Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        3568,
        512
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "n18",
      "name": "Select Clips for Editing",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        3792,
        512
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.llmModel }}"
        },
        "options": {
          "maxTokens": 2048
        },
        "responses": {
          "values": [
            {
              "content": "=You are a viral-short-form editor. From the transcript SEGMENTS below, pick EXACTLY {{ $('Set Configuration Parameters').item.json.clipCount }} clips that will perform best as TikTok / Instagram Reels / YouTube Shorts. Each clip must be between 15 and 90 seconds long, start on a sentence boundary, and be self-contained (has a hook, a payoff, and no dangling reference to earlier context).\n\nReturn ONLY a valid JSON object (no prose, no markdown fences) with this exact shape:\n{\n  \"clips\": [\n    {\n      \"id\": \"c01\",\n      \"start_sec\": number,\n      \"end_sec\": number,\n      \"title\": string,\n      \"hook\": string,\n      \"tiktok_caption\": string,\n      \"instagram_caption\": string,\n      \"youtube_caption\": string,\n      \"hashtags\": [string]\n    }\n  ]\n}\n\nConstraints:\n- Use lowercase, zero-padded IDs like c01, c02, ...\n- end_sec must be > start_sec and within the video duration of {{ $('Generate Transcript Files').item.json.duration }} seconds.\n- Do not overlap clips.\n- TikTok caption: punchy, <=150 chars, first 60 chars must be the hook.\n- Instagram caption: 1-2 sentences, <=220 chars.\n- YouTube caption: 1 sentence + 3 hashtags appended.\n- hashtags: 5-8 relevant, lowercase, no # prefix.\n\nSEGMENTS (Whisper verbose_json):\n{{ JSON.stringify($('Generate Transcript Files').item.json.segments) }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "n19",
      "name": "Validate Selected Clips",
      "type": "n8n-nodes-base.code",
      "position": [
        4016,
        512
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json;\nlet text = '';\nif (raw && raw.output && Array.isArray(raw.output) && raw.output[0] && Array.isArray(raw.output[0].content) && raw.output[0].content[0]) {\n\ttext = raw.output[0].content[0].text || '';\n} else if (typeof raw.content === 'string') {\n\ttext = raw.content;\n} else if (raw.message && typeof raw.message.content === 'string') {\n\ttext = raw.message.content;\n} else if (typeof raw.text === 'string') {\n\ttext = raw.text;\n} else {\n\ttext = JSON.stringify(raw);\n}\n\ntext = text.replace(/^```(?:json)?\\s*/i, '').replace(/```\\s*$/i, '').trim();\nlet parsed = { clips: [] };\ntry { parsed = JSON.parse(text); } catch { parsed = { clips: [] }; }\nconst clipsIn = Array.isArray(parsed.clips) ? parsed.clips : [];\nconst duration = Number($('Generate Transcript Files').first().json.duration) || 999999;\n\nconst out = [];\nconst used = [];\nfor (let i = 0; i < clipsIn.length; i++) {\n\tconst c = clipsIn[i];\n\tlet start = Math.max(0, Number(c.start_sec) || 0);\n\tlet end = Math.min(duration, Number(c.end_sec) || start);\n\tif (end - start < 15) end = Math.min(duration, start + 20);\n\tif (end - start > 90) end = start + 90;\n\tif (end <= start) continue;\n\tif (used.some(u => start < u.end && end > u.start)) continue;\n\tused.push({ start, end });\n\tconst id = (c.id || `c${String(i + 1).padStart(2, '0')}`).toLowerCase().replace(/[^a-z0-9]/g, '');\n\tout.push({\n\t\tjson: {\n\t\t\tid,\n\t\t\tstart_sec: Math.round(start * 1000) / 1000,\n\t\t\tend_sec: Math.round(end * 1000) / 1000,\n\t\t\tduration_sec: Math.round((end - start) * 1000) / 1000,\n\t\t\ttitle: String(c.title || id),\n\t\t\thook: String(c.hook || ''),\n\t\t\ttiktok_caption: String(c.tiktok_caption || ''),\n\t\t\tinstagram_caption: String(c.instagram_caption || ''),\n\t\t\tyoutube_caption: String(c.youtube_caption || ''),\n\t\t\thashtags: Array.isArray(c.hashtags) ? c.hashtags.slice(0, 10) : [],\n\t\t},\n\t});\n}\nreturn out;"
      },
      "typeVersion": 2
    },
    {
      "id": "n21",
      "name": "Create Clip Commands",
      "type": "n8n-nodes-base.code",
      "position": [
        4464,
        448
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const c = $input.item.json;\nconst start = c.start_sec;\nconst dur = c.duration_sec;\nconst base = `-i {{in_video}} -ss ${start} -t ${dur} `;\nconst enc = ` -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -movflags +faststart`;\nreturn {\n\tjson: {\n\t\t...c,\n\t\ttiktok_cmd: base + `-vf \"crop=ih*9/16:ih,scale=1080:1920\"` + enc + ` {{out_tiktok}}`,\n\t\treels_cmd: base + `-vf \"crop=ih*4/5:ih,scale=1080:1350\"` + enc + ` {{out_reels}}`,\n\t\tsquare_cmd: base + `-vf \"crop=ih:ih,scale=1080:1080\"` + enc + ` {{out_square}}`,\n\t\tout_tiktok_name: `${c.id}_tiktok_1080x1920.mp4`,\n\t\tout_reels_name: `${c.id}_reels_1080x1350.mp4`,\n\t\tout_square_name: `${c.id}_square_1080x1080.mp4`,\n\t},\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "n22",
      "name": "Render Video Clip",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4688,
        448
      ],
      "parameters": {
        "url": "https://renderio.dev/api/v1/run-chained-ffmpeg-commands",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({\n  input_files: { in_video: $('Retrieve RenderIO File').item.json.storage_url },\n  output_files: {\n    out_tiktok: $('Create Clip Commands').item.json.out_tiktok_name,\n    out_reels: $('Create Clip Commands').item.json.out_reels_name,\n    out_square: $('Create Clip Commands').item.json.out_square_name\n  },\n  ffmpeg_commands: [\n    $('Create Clip Commands').item.json.tiktok_cmd,\n    $('Create Clip Commands').item.json.reels_cmd,\n    $('Create Clip Commands').item.json.square_cmd\n  ]\n}) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "renderioApi"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n23",
      "name": "Wait 15 Seconds for Render",
      "type": "n8n-nodes-base.wait",
      "position": [
        4912,
        448
      ],
      "parameters": {
        "amount": 15
      },
      "typeVersion": 1.1
    },
    {
      "id": "n24",
      "name": "Verify Render Completion",
      "type": "n8n-nodes-renderio.renderio",
      "position": [
        5136,
        448
      ],
      "parameters": {
        "commandId": "={{ $('Render Video Clip').item.json.command_id }}",
        "operation": "get"
      },
      "credentials": {
        "renderioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "n25",
      "name": "If Render is Ready",
      "type": "n8n-nodes-base.if",
      "position": [
        5360,
        368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "render-status-check",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Verify Render Completion').item.json.status }}",
              "rightValue": "SUCCESS"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "n26",
      "name": "Wait 30 Seconds for Render Retry",
      "type": "n8n-nodes-base.wait",
      "position": [
        5584,
        704
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "n27",
      "name": "Download TikTok Format",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5808,
        128
      ],
      "parameters": {
        "url": "={{ $('Verify Render Completion').item.json.output_files.out_tiktok.storage_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n28",
      "name": "Download Reels Format",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5808,
        320
      ],
      "parameters": {
        "url": "={{ $('Verify Render Completion').item.json.output_files.out_reels.storage_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n29",
      "name": "Download Square Format",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5808,
        512
      ],
      "parameters": {
        "url": "={{ $('Verify Render Completion').item.json.output_files.out_square.storage_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "n30",
      "name": "Upload TikTok to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6032,
        128
      ],
      "parameters": {
        "name": "={{ $('Create Clip Commands').item.json.out_tiktok_name }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Google Drive Folder').item.json.id }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n31",
      "name": "Upload Reels to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6032,
        320
      ],
      "parameters": {
        "name": "={{ $('Create Clip Commands').item.json.out_reels_name }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Google Drive Folder').item.json.id }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n32",
      "name": "Upload Square to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        6032,
        512
      ],
      "parameters": {
        "name": "={{ $('Create Clip Commands').item.json.out_square_name }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Create Google Drive Folder').item.json.id }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "n32b",
      "name": "Merge Uploaded Clips",
      "type": "n8n-nodes-base.merge",
      "position": [
        6256,
        304
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "n33",
      "name": "Append Clip Data to Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        6032,
        848
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.sheetTab }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1gfg98qMzRCMjwG2vPw9IPewvWDcaGdYjJCfXxf-8LJI"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "n34",
      "name": "Append Summary to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        6256,
        848
      ],
      "parameters": {
        "columns": {
          "value": {
            "duration_sec": "={{ $('Generate Transcript Files').item.json.duration }}",
            "processed_at": "={{ $now.toISO() }}",
            "clips_generated": "={{ $('Validate Selected Clips').all().length }}",
            "source_drive_url": "={{ $('Set Configuration Parameters').item.json.sourceDriveUrl }}",
            "output_folder_url": "={{ $('Create Google Drive Folder').item.json.webViewLink }}",
            "source_video_name": "={{ $('Set Configuration Parameters').item.json.sourceFileName }}"
          },
          "schema": [
            {
              "id": "source_video_name",
              "type": "string",
              "displayName": "source_video_name",
              "canBeUsedToMatch": true
            },
            {
              "id": "source_drive_url",
              "type": "string",
              "displayName": "source_drive_url",
              "canBeUsedToMatch": true
            },
            {
              "id": "output_folder_url",
              "type": "string",
              "displayName": "output_folder_url",
              "canBeUsedToMatch": true
            },
            {
              "id": "duration_sec",
              "type": "number",
              "displayName": "duration_sec",
              "canBeUsedToMatch": true
            },
            {
              "id": "clips_generated",
              "type": "number",
              "displayName": "clips_generated",
              "canBeUsedToMatch": true
            },
            {
              "id": "processed_at",
              "type": "string",
              "displayName": "processed_at",
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.sheetRunsTab }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Configuration Parameters').item.json.sheetId }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "1dc8ab1d-1f8e-4f60-a4ad-614b782aaad0",
  "connections": {
    "If Audio is Ready": {
      "main": [
        [
          {
            "node": "Download Extracted Audio",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30 Seconds for Audio Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Render Video Clip": {
      "main": [
        [
          {
            "node": "Wait 15 Seconds for Render",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Render is Ready": {
      "main": [
        [
          {
            "node": "Download TikTok Format",
            "type": "main",
            "index": 0
          },
          {
            "node": "Download Reels Format",
            "type": "main",
            "index": 0
          },
          {
            "node": "Download Square Format",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30 Seconds for Render Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Clip Commands": {
      "main": [
        [
          {
            "node": "Render Video Clip",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Uploaded Clips": {
      "main": [
        [
          {
            "node": "Append Clip Data to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Reels Format": {
      "main": [
        [
          {
            "node": "Upload Reels to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Reels to Drive": {
      "main": [
        [
          {
            "node": "Merge Uploaded Clips",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Download Square Format": {
      "main": [
        [
          {
            "node": "Upload Square to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download TikTok Format": {
      "main": [
        [
          {
            "node": "Upload TikTok to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Transcripts Data": {
      "main": [
        [
          {
            "node": "Select Clips for Editing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve RenderIO File": {
      "main": [
        [
          {
            "node": "Create Google Drive Folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Square to Drive": {
      "main": [
        [
          {
            "node": "Merge Uploaded Clips",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Upload TikTok to Drive": {
      "main": [
        [
          {
            "node": "Merge Uploaded Clips",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Selected Clips": {
      "main": [
        [
          {
            "node": "Create Clip Commands",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify Audio Extraction": {
      "main": [
        [
          {
            "node": "If Audio is Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Extracted Audio": {
      "main": [
        [
          {
            "node": "Transcribe Audio with Whisper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Clips for Editing": {
      "main": [
        [
          {
            "node": "Validate Selected Clips",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Video to RenderIO": {
      "main": [
        [
          {
            "node": "Retrieve RenderIO File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify Render Completion": {
      "main": [
        [
          {
            "node": "If Render is Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Clip Data to Sheet": {
      "main": [
        [
          {
            "node": "Append Summary to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Video from Drive": {
      "main": [
        [
          {
            "node": "Upload Video to RenderIO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Transcript Files": {
      "main": [
        [
          {
            "node": "Upload TXT Transcript to Drive",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload SRT Transcript to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 10 Seconds for Audio": {
      "main": [
        [
          {
            "node": "Verify Audio Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Google Drive Folder": {
      "main": [
        [
          {
            "node": "Extract Audio with RenderIO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 15 Seconds for Render": {
      "main": [
        [
          {
            "node": "Verify Render Completion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Audio with RenderIO": {
      "main": [
        [
          {
            "node": "Wait 10 Seconds for Audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Folder Trigger": {
      "main": [
        [
          {
            "node": "Set Configuration Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration Parameters": {
      "main": [
        [
          {
            "node": "Download Video from Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcribe Audio with Whisper": {
      "main": [
        [
          {
            "node": "Generate Transcript Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload SRT Transcript to Drive": {
      "main": [
        [
          {
            "node": "Merge Transcripts Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Upload TXT Transcript to Drive": {
      "main": [
        [
          {
            "node": "Merge Transcripts Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30 Seconds for Audio Retry": {
      "main": [
        [
          {
            "node": "Verify Audio Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30 Seconds for Render Retry": {
      "main": [
        [
          {
            "node": "Verify Render Completion",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Content creators, YouTubers, and social media managers who want to repurpose long form videos into short clips without doing it manually. Works on self hosted n8n instances.

Source: https://n8n.io/workflows/15132/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

The Problem That it Solves

Google Drive Trigger, OpenAI, Google Drive +5
AI & RAG

This workflow automatically turns new technical video uploads into short, engaging Facebook post drafts—complete with a suggested image—and saves the results to Google Sheets for quick review or publi

Google Drive Trigger, Google Drive, HTTP Request +2
AI & RAG

Scrape ads – Pulls Facebook Ad Library data for "ai automation" keywords using Apify Filter & sort – Filters ads by page likes (&gt;1,000) and separates into videos, images, and text ads Analyze creat

HTTP Request, Google Drive, OpenAI +3
AI & RAG

This workflow converts emailed timesheets into structured invoice rows in Google Sheets and stores them in the correct Google Drive folder structure.

Gmail Trigger, OpenAI, Google Sheets +2
AI & RAG

[Template] Viral Video Factory - Fal.ai + GPT-4. Uses googleDrive, httpRequest, openAi, googleSheets. Event-driven trigger; 39 nodes.

Google Drive, HTTP Request, OpenAI +1