n8n Workflow

Narrating Over A Video Using Multimodal Ai

This n8n workflow automates tasks and integrates with various services. Narrating Over A Video Using Multimodal Ai - ready to import and run in your n8n instance.

n8n workflow.json

About This Script

This n8n workflow automates tasks and integrates with various services. Narrating Over A Video Using Multimodal Ai - ready to import and run in your n8n instance.
Features:
  • Makes HTTP requests to external APIs
Source Code
{
    "nodes": [
        {
            "id": "6d16b5be-8f7b-49f2-8523-9b84c62f2759",
            "name": "OpenAI Chat Model",
            "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
            "position": [
                1960,
                660
            ],
            "parameters": {
                "model": "gpt-4o-2024-08-06",
                "options": []
            },
            "credentials": {
                "openAiApi": {
                    "id": "8gccIjcuf3gvaoEr",
                    "name": "OpenAi account"
                }
            },
            "typeVersion": 1
        },
        {
            "id": "a6084f09-9a4f-478a-ac1a-ab1413628c1f",
            "name": "Capture Frames",
            "type": "n8n-nodes-base.code",
            "position": [
                720,
                460
            ],
            "parameters": {
                "mode": "runOnceForEachItem",
                "language": "python",
                "pythonCode": "import cv2\nimport numpy as np\nimport base64\n\ndef extract_evenly_distributed_frames_from_base64(base64_string, max_frames=90):\n    # Decode the Base64 string into bytes\n    video_bytes = base64.b64decode(base64_string)\n    \n    # Write the bytes to a temporary file\n    video_path = '/tmp/temp_video.mp4'\n    with open(video_path, 'wb') as video_file:\n        video_file.write(video_bytes)\n    \n    # Open the video file using OpenCV\n    video_capture = cv2.VideoCapture(video_path)\n    \n    # Get the total number of frames in the video\n    total_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))\n    \n    # Calculate the step size to take 'max_frames' evenly distributed frames\n    step_size = max(1, total_frames // (max_frames - 1))\n    \n    # List to store selected frames as base64\n    selected_frames_base64 = []\n    \n    for i in range(0, total_frames, step_size):\n        # Set the current frame position\n        video_capture.set(cv2.CAP_PROP_POS_FRAMES, i)\n        \n        # Read the frame\n        ret, frame = video_capture.read()\n        if ret:\n            # Convert frame (NumPy array) to a Base64 string\n            frame_base64 = convert_frame_to_base64(frame)\n            selected_frames_base64.append(frame_base64)\n        if len(selected_frames_base64) >= max_frames:\n            break\n    \n    # Release the video capture object\n    video_capture.release()\n\n    return selected_frames_base64\n\ndef convert_frame_to_base64(frame):\n    # Convert the frame (NumPy array) to JPEG format\n    ret, buffer = cv2.imencode('.jpg', frame)\n    if not ret:\n        return None\n\n    # Encode JPEG image to Base64\n    frame_base64 = base64.b64encode(buffer).decode('utf-8')\n    return frame_base64\n\nbase64_video = _input.item.binary.data.data\nframes_base64 = extract_evenly_distributed_frames_from_base64(base64_video, max_frames=90)\n\nreturn { \"output\": frames_base64 }"
            },
            "typeVersion": 2
        },
        {
            "id": "b45e82a4-f304-4733-a9cf-07cae6df13ea",
            "name": "Split Out Frames",
            "type": "n8n-nodes-base.splitOut",
            "position": [
                920,
                460
            ],
            "parameters": {
                "options": [],
                "fieldToSplitOut": "output"
            },
            "typeVersion": 1
        },
        {
            "id": "83d29c51-a415-476d-b380-1ca5f0d4f521",
            "name": "Download Video",
            "type": "n8n-nodes-base.httpRequest",
            "position": [
                329,
                346
            ],
            "parameters": {
                "url": "=https://cdn.pixabay.com/video/2016/05/12/3175-166339863_small.mp4",
                "options": []
            },
            "typeVersion": 4.2
        },
        {
            "id": "0304ebb5-945d-4b0b-9597-f83ae8c1fe31",
            "name": "Convert to Binary",
            "type": "n8n-nodes-base.convertToFile",
            "position": [
                1480,
                500
            ],
            "parameters": {
                "options": [],
                "operation": "toBinary",
                "sourceProperty": "output"
            },
            "typeVersion": 1.1
        },
        {
            "id": "32a21e1d-1d8b-411e-8281-8d0e68a06889",
            "name": "When clicking \u2018Test workflow\u2019",
            "type": "n8n-nodes-base.manualTrigger",
            "position": [
                149,
                346
            ],
            "parameters": [],
            "typeVersion": 1
        },
        {
            "id": "0ad2ea6a-e1f4-4b26-a4de-9103ecbb3831",
            "name": "Combine Script",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                2640,
                360
            ],
            "parameters": {
                "options": [],
                "aggregate": "aggregateAllItemData"
            },
            "typeVersion": 1
        },
        {
            "id": "2d9bb91a-3369-4268-882f-f97e73897bb8",
            "name": "Upload to GDrive",
            "type": "n8n-nodes-base.googleDrive",
            "position": [
                3040,
                360
            ],
            "parameters": {
                "name": "=narrating-video-using-vision-ai-{{ $now.format('yyyyMMddHHmmss') }}.mp3",
                "driveId": {
                    "__rl": true,
                    "mode": "list",
                    "value": "My Drive",
                    "cachedResultUrl": "https://drive.google.com/drive/my-drive",
                    "cachedResultName": "My Drive"
                },
                "options": [],
                "folderId": {
                    "__rl": true,
                    "mode": "id",
                    "value": "1dBJZL_SCh6F2U7N7kIMsnSiI4QFxn2xD"
                }
            },
            "credentials": {
                "googleDriveOAuth2Api": {
                    "id": "yOwz41gMQclOadgu",
                    "name": "Google Drive account"
                }
            },
            "typeVersion": 3
        },
        {
            "id": "137185f6-ba32-4c68-844f-f50c7a5a261d",
            "name": "Sticky Note",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                -440,
                0
            ],
            "parameters": {
                "width": 476.34074202271484,
                "height": 586.0597334122469,
                "content": "Configuration note: update with your credentials or endpoint.",
                "color": "#FFF59D"
            },
            "typeVersion": 1
        },
        {
            "id": "0a42aeb0-96cd-401c-abeb-c50e0f04f7ad",
            "name": "Sticky Note2",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                560,
                120
            ],
            "parameters": {
                "color": "#FFF59D",
                "width": 605.2674418604653,
                "height": 522.6860465116279,
                "content": "Configuration note: update with your credentials or endpoint."
            },
            "typeVersion": 1
        },
        {
            "id": "b518461c-13f1-45ae-a156-20ae6051fc19",
            "name": "Sticky Note3",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                560,
                660
            ],
            "parameters": {
                "color": "#FFF59D",
                "width": 418.11627906976724,
                "height": 132.89534883720933,
                "content": "Configuration note: update with your credentials or endpoint."
            },
            "typeVersion": 1
        },
        {
            "id": "585f7a7f-1676-4bc3-a6fb-eace443aa5da",
            "name": "Sticky Note4",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                1200,
                118.69767441860472
            ],
            "parameters": {
                "color": "#FFF59D",
                "width": 1264.8139534883715,
                "height": 774.3720930232558,
                "content": "Configuration note: update with your credentials or endpoint."
            },
            "typeVersion": 1
        },
        {
            "id": "42c002a3-37f6-4dd7-af14-20391b19cb5a",
            "name": "Stay Within Service Limits",
            "type": "n8n-nodes-base.wait",
            "position": [
                2280,
                640
            ],
            "webhookId": "677fa706-b4dd-4fe3-ba17-feea944c3193",
            "parameters": [],
            "typeVersion": 1.1
        },
        {
            "id": "5beb17fa-8a57-4c72-9c3b-b7fdf41b545a",
            "name": "For Every 15 Frames",
            "type": "n8n-nodes-base.splitInBatches",
            "position": [
                1320,
                380
            ],
            "parameters": {
                "options": [],
                "batchSize": 15
            },
            "typeVersion": 3
        },
        {
            "id": "9a57256a-076a-4823-8cad-3b64a17ff705",
            "name": "Resize Frame",
            "type": "n8n-nodes-base.editImage",
            "position": [
                1640,
                500
            ],
            "parameters": {
                "width": 768,
                "height": 768,
                "options": {
                    "format": "jpeg"
                },
                "operation": "resize"
            },
            "typeVersion": 1
        },
        {
            "id": "3e776939-1a25-4ea0-8106-c3072d108106",
            "name": "Aggregate Frames",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                1800,
                500
            ],
            "parameters": {
                "options": {
                    "includeBinaries": true
                },
                "aggregate": "aggregateAllItemData"
            },
            "typeVersion": 1
        },
        {
            "id": "3a973a9c-2c7a-43c5-9c45-a14d49b56622",
            "name": "Sticky Note5",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                2500,
                120.6860465116277
            ],
            "parameters": {
                "color": "#FFF59D",
                "width": 769.1860465116274,
                "height": 487.83720930232533,
                "content": "Configuration note: update with your credentials or endpoint."
            },
            "typeVersion": 1
        },
        {
            "id": "92e07c18-4058-4098-a448-13451bd8a17a",
            "name": "Use Text-to-Speech",
            "type": "@n8n/n8n-nodes-langchain.openAi",
            "position": [
                2840,
                360
            ],
            "parameters": {
                "input": "={{ $json.data.map(item => item.text).join('\\n') }}",
                "options": {
                    "response_format": "mp3"
                },
                "resource": "audio"
            },
            "credentials": {
                "openAiApi": {
                    "id": "8gccIjcuf3gvaoEr",
                    "name": "OpenAi account"
                }
            },
            "typeVersion": 1.5
        },
        {
            "id": "0696c336-1814-4ad4-aa5e-b86489a4231e",
            "name": "Sticky Note6",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                61,
                598
            ],
            "parameters": {
                "color": "#FFF59D",
                "width": 458.1279069767452,
                "height": 296.8139534883723,
                "content": "Configuration note: update with your credentials or endpoint."
            },
            "typeVersion": 1
        },
        {
            "id": "81185ac4-c7fd-4921-937f-109662d5dfa5",
            "name": "Generate Narration Script",
            "type": "@n8n/n8n-nodes-langchain.chainLlm",
            "position": [
                1960,
                500
            ],
            "parameters": {
                "text": "=These are frames of a video. Create a short voiceover script in the style of David Attenborough. Only include the narration.\n{{\n$('Generate Narration Script').isExecuted\n ? `Continue from this script:\\n${$('Generate Narration Script').all().map(item => item.json.text.replace(/\\n/g,'')).join('\\n')}`\n : ''\n}}",
                "messages": {
                    "messageValues": [
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_1"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_2"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_3"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_4"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_5"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_6"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_7"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_8"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_9"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_10"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_11"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_12"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_13"
                        },
                        {
                            "type": "HumanMessagePromptTemplate",
                            "messageType": "imageBinary",
                            "binaryImageDataKey": "data_14"
                        }
                    ]
                },
                "promptType": "define"
            },
            "typeVersion": 1.4
        }
    ],
    "connections": {
        "Resize Frame": {
            "main": [
                [
                    {
                        "node": "Aggregate Frames",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Capture Frames": {
            "main": [
                [
                    {
                        "node": "Split Out Frames",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Combine Script": {
            "main": [
                [
                    {
                        "node": "Use Text-to-Speech",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Download Video": {
            "main": [
                [
                    {
                        "node": "Capture Frames",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Aggregate Frames": {
            "main": [
                [
                    {
                        "node": "Generate Narration Script",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Split Out Frames": {
            "main": [
                [
                    {
                        "node": "For Every 15 Frames",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Convert to Binary": {
            "main": [
                [
                    {
                        "node": "Resize Frame",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "OpenAI Chat Model": {
            "ai_languageModel": [
                [
                    {
                        "node": "Generate Narration Script",
                        "type": "ai_languageModel",
                        "index": 0
                    }
                ]
            ]
        },
        "Use Text-to-Speech": {
            "main": [
                [
                    {
                        "node": "Upload to GDrive",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "For Every 15 Frames": {
            "main": [
                [
                    {
                        "node": "Combine Script",
                        "type": "main",
                        "index": 0
                    }
                ],
                [
                    {
                        "node": "Convert to Binary",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Generate Narration Script": {
            "main": [
                [
                    {
                        "node": "Stay Within Service Limits",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Stay Within Service Limits": {
            "main": [
                [
                    {
                        "node": "For Every 15 Frames",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "When clicking \u2018Test workflow\u2019": {
            "main": [
                [
                    {
                        "node": "Download Video",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        }
    },
    "n8n_version": "1.5.0"
}
Requirements
n8n instance, API credentials for connected services
Tags
#n8n #automation #workflow
Quick Actions
More in n8n Workflows