Workflow n8n

Automatisation YouTube avec n8n : création de vidéos à partir de citations

Ce workflow n8n a pour objectif de simplifier la création et la publication de vidéos sur YouTube à partir de citations. Il est particulièrement utile pour les entreprises et les créateurs de contenu qui souhaitent automatiser le processus de génération de vidéos inspirantes. En intégrant plusieurs services, ce workflow permet de transformer des citations en vidéos attrayantes, tout en gérant les ressources nécessaires comme les images et les sons. Le processus commence par un déclencheur manuel qui initie le workflow. Ensuite, une image est générée via une requête HTTP, suivie de l'acquisition de cette image pour l'utiliser dans la vidéo. Après avoir attendu deux minutes pour le traitement de l'image, le workflow passe à la génération d'un clip vidéo en utilisant l'image et le son. Les étapes suivantes incluent l'upload du son et de la vidéo sur Google Drive et YouTube, respectivement. À chaque étape, des mises à jour sont effectuées dans Google Sheets pour suivre l'état des uploads. Ce workflow n8n offre une solution efficace pour réduire le temps de création de contenu vidéo, tout en garantissant une qualité professionnelle. En automatisant ces tâches, les utilisateurs peuvent se concentrer sur la création de contenu et l'engagement avec leur audience, tout en minimisant les erreurs humaines.

Tags clés :automatisationYouTubeGoogle Sheetsvidéon8n
Catégorie: Manual · Tags: automatisation, YouTube, Google Sheets, vidéo, n8n0

Workflow n8n YouTube, Google Sheets, vidéo : vue d'ensemble

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Workflow n8n YouTube, Google Sheets, vidéo : détail des nœuds

  • When clicking ‘Test workflow’

    Ce noeud déclenche le workflow manuellement lorsque l'utilisateur clique sur 'Test workflow'.

  • Generate Image

    Ce noeud envoie une requête HTTP pour générer une image à partir d'une URL spécifiée.

  • Get image

    Ce noeud récupère une image en effectuant une requête HTTP à une URL donnée.

  • Sticky Note

    Ce noeud crée une note autocollante avec des dimensions et un contenu spécifiés.

  • Update image background URL

    Ce noeud met à jour l'URL de fond d'une image dans une feuille Google.

  • Image-to-Video

    Ce noeud envoie une requête HTTP pour convertir une image en vidéo.

  • Wait image 2 min

    Ce noeud suspend l'exécution du workflow pendant 2 minutes.

  • Wait video 5 min

    Ce noeud suspend l'exécution du workflow pendant 5 minutes.

  • Get Video

    Ce noeud effectue une requête HTTP pour récupérer une vidéo à partir d'une URL donnée.

  • Sticky Note1

    Ce noeud crée une note autocollante avec des dimensions, une couleur et un contenu spécifiés.

  • Generate Audio

    Ce noeud envoie une requête HTTP pour générer un audio à partir d'une URL donnée.

  • Get data from Google Sheet

    Ce noeud récupère des données d'une feuille Google en utilisant des options et des filtres spécifiés.

  • Update Sound background URL

    Ce noeud met à jour l'URL de fond d'un son dans une feuille Google.

  • Update video background URL

    Ce noeud met à jour l'URL de fond d'une vidéo dans une feuille Google.

  • Sticky Note2

    Ce noeud crée une note autocollante avec des dimensions, une couleur et un contenu spécifiés.

  • Upload Sound to Google Drive

    Ce noeud télécharge un son sur Google Drive avec un nom et un dossier spécifiés.

  • Save Video Background Locally1

    Ce noeud enregistre une vidéo en local avec un nom de fichier spécifié.

  • Get Binary Video Background

    Ce noeud effectue une requête HTTP pour obtenir un fond vidéo binaire à partir d'une URL.

  • Save Music Background Locally1

    Ce noeud enregistre de la musique en local avec un nom de fichier spécifié.

  • Prepare Overlay Text (Quote & Author)1

    Ce noeud prépare du texte de superposition (citation et auteur) en exécutant un code JavaScript.

  • Generate Final Video Clip1

    Ce noeud génère un clip vidéo final en exécutant une commande spécifiée.

  • Initiate YouTube Resumable Upload

    Ce noeud initie un téléchargement de vidéo sur YouTube en effectuant une requête HTTP.

  • Read output file

    Ce noeud lit un fichier de sortie à partir du système de fichiers.

  • Upload Video to YouTube

    Ce noeud télécharge une vidéo sur YouTube en effectuant une requête HTTP.

  • Update Quote Upload Status

    Ce noeud met à jour le statut de téléchargement d'une citation dans une feuille Google.

  • Sticky Note3

    Ce noeud crée une note autocollante avec des dimensions, une couleur et un contenu spécifiés.

  • Sticky Note4

    Ce noeud crée une note autocollante avec des dimensions, une couleur et un contenu spécifiés.

  • Sticky Note5

    Ce noeud crée une note autocollante avec des dimensions, une couleur et un contenu spécifiés.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "id": "CvXjXG4SFnN0ioJQ",
  "meta": {
    "instanceId": "e2034325698638870d6b764285427bad9d79bf1e08a458be597c06e61ad7e545",
    "templateCredsSetupCompleted": true
  },
  "name": "AutoQoutesV2_template",
  "tags": [],
  "nodes": [
    {
      "id": "2ff58bb4-7079-44fe-a2ac-b4af9fa5b30e",
      "name": "When clicking ‘Test workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        300,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ec44d567-dfc8-4561-87df-903724225247",
      "name": "Generate Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        660,
        0
      ],
      "parameters": {
        "url": "https://api.piapi.ai/api/v1/task",
        "body": "={\n  \"model\": \"Qubico/flux1-dev\",\n  \"task_type\": \"txt2img\",\n  \"input\": {\n    \"prompt\": \"Ultra-realistic vertical nature landscape, {{ $json['Background (EN)'] }}, featuring {{ $json['Prompt (EN)'] }}, high detail, soft atmospheric lighting, cinematic golden hour glow, vertical composition, photorealistic texture, natural depth of field, calm and serene mood, no people, no buildings, HDR, 8k resolution, masterpiece\",\n    \"negative_prompt\": \"taking a photo of a room, recording a video of a room, photos app, video recorder, illegible text, blurry text, low quality text, DSLR, unnatural\",\n    \"width\": 540,\n    \"height\": 960\n  }\n}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "raw",
        "sendHeaders": true,
        "rawContentType": "application/json",
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-Key",
              "value": "=[Your PiAPI Key]"
            }
          ]
        }
      },
      "retryOnFail": false,
      "typeVersion": 4.2
    },
    {
      "id": "ad260a51-e981-47cc-8600-967c1c748814",
      "name": "Get image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1020,
        0
      ],
      "parameters": {
        "url": "=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-Key",
              "value": "=[Your PiAPI Key]"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "cddff673-15ce-47ec-a2d3-3d71437bfb1f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        600,
        -80
      ],
      "parameters": {
        "width": 820,
        "height": 240,
        "content": "## Create Image Background\nGenerate an image using prompt from Google Sheet via PiAPI Flux (Txt2img)."
      },
      "typeVersion": 1
    },
    {
      "id": "64132a39-ad42-4158-9eec-5b6bfdc7bca2",
      "name": "Update image background URL",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1240,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "Index": "={{ $('Get data from Google Sheet').item.json.Index }}",
            "Background Image": "={{ $json.data.output.image_url }}"
          },
          "schema": [
            {
              "id": "Index",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quote (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Quote (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pen Name (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Pen Name (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prompt (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Prompt (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Image",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Background Image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Video",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Video",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Video Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Index"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "Ra2f1dlqOJ13jTtb",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "801dd794-4cf8-42f7-8102-a3a4853cae39",
      "name": "Image-to-Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        260,
        280
      ],
      "parameters": {
        "url": "https://api.piapi.ai/api/v1/task",
        "body": "={\n  \"model\": \"kling\",\n  \"task_type\": \"video_generation\",\n  \"input\": {\n    \"prompt\": \"Cinematic vertical video from image of {{ $('Get data from Google Sheet').item.json['Background (EN)'] }}, with {{ $('Get data from Google Sheet').item.json['Prompt (EN)'] }}, animated subtly from image, with soft light, mist, swaying trees, slow zoom effect, no people or buildings\",\n    \"negative_prompt\": \"blurry motion, distorted faces, unnatural lighting, over produced, bad quality\",\n    \"cfg_scale\": 0.5,\n    \"duration\": 5,\n    \"mode\": \"std\",\n    \"image_url\": \"{{ $('Get image').item.json.data.output.image_url }}\",\n    \"version\": \"1.0\",\n    \"camera_control\": {\n      \"type\": \"simple\",\n      \"config\": {\n        \"horizontal\": 0,\n        \"vertical\": 0,\n        \"pan\": 0,\n        \"tilt\": 0,\n        \"roll\": 0,\n        \"zoom\": 5\n      }\n    }\n  }\n}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "raw",
        "sendHeaders": true,
        "rawContentType": "application/json",
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-Key",
              "value": "=[Your PiAPI Key]"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6f7d755f-73fb-474f-a2c4-4612317c4f5a",
      "name": "Wait image 2 min",
      "type": "n8n-nodes-base.wait",
      "position": [
        840,
        0
      ],
      "webhookId": "ccf58c3e-f91d-4f58-a4a7-aff58c9be226",
      "parameters": {
        "unit": "minutes",
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "d8de3a95-1a5b-4495-9a1f-8178c1be3d44",
      "name": "Wait video 5 min",
      "type": "n8n-nodes-base.wait",
      "position": [
        440,
        280
      ],
      "webhookId": "6df38e96-d5ec-4588-9569-db9b86539a34",
      "parameters": {
        "unit": "minutes"
      },
      "typeVersion": 1.1
    },
    {
      "id": "c3f97a19-9ea8-4489-8629-767542f0fddb",
      "name": "Get Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        620,
        280
      ],
      "parameters": {
        "url": "=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-Key",
              "value": "=[Your PiAPI Key]"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "eefa224d-2e3d-459e-a16d-8e2584b59cf0",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        200
      ],
      "parameters": {
        "color": 3,
        "width": 1180,
        "height": 240,
        "content": "## Create Video Background\nCreate a cinematic vertical video from the generated image using PiAPI Kling."
      },
      "typeVersion": 1
    },
    {
      "id": "8d2035a8-d4a0-4a33-bae3-c18b530487d4",
      "name": "Generate Audio",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        380,
        560
      ],
      "parameters": {
        "url": "https://api.elevenlabs.io/v1/sound-generation",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "={\n  \"text\": \"no voice, A peaceful soundscape unfolds as the sun begins to rise over misty {{ $('Get data from Google Sheet').item.json['Background (EN)'] }}, casting warm light across the scene. The crisp morning air is filled with ambient nature sounds like {{ $('Get data from Google Sheet').item.json['Prompt (EN)'] }} along with soft lofi beats, blending into a calm and immersive atmosphere.\",\n  \"duration_seconds\": 5,\n  \"model_id\": \"sound-effects-v1\",\n  \"output_format\": \"mp3\"\n}\n"
            },
            {
              "name": "duration_seconds",
              "value": "20"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "xi-api-key",
              "value": "[Your ElevenLab Key]"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "66af781a-2012-426e-a623-e90e21e8b2a1",
      "name": "Get data from Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        480,
        0
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupColumn": "Video Status"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "Ra2f1dlqOJ13jTtb",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "04074118-9f30-4648-8aab-9574156a76ba",
      "name": "Update Sound background URL",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1220,
        480
      ],
      "parameters": {
        "columns": {
          "value": {
            "Index": "={{ $('Get data from Google Sheet').item.json.Index }}",
            "Music Background": "={{ $json.webContentLink }}"
          },
          "schema": [
            {
              "id": "Index",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quote (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Quote (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pen Name (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Pen Name (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prompt (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Prompt (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Image",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Video",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Video",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Music Background",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Music Background",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Video Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Index"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "Ra2f1dlqOJ13jTtb",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "35ca939b-fb27-48cf-8036-f35618ceaee0",
      "name": "Update video background URL",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1240,
        280
      ],
      "parameters": {
        "columns": {
          "value": {
            "Index": "={{ $('Get data from Google Sheet').item.json.Index }}",
            "Background Video": "={{ $json.data.output.video_url }}"
          },
          "schema": [
            {
              "id": "Index",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quote (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Quote (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pen Name (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Pen Name (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prompt (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Prompt (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Image",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Video",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Background Video",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Video Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Index"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "Ra2f1dlqOJ13jTtb",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "54c8badf-a99a-4e5c-ad96-e1d982eb6855",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        480
      ],
      "parameters": {
        "color": 4,
        "width": 1180,
        "height": 240,
        "content": "## Create Sound Background\nGenerate ambient sound using ElevenLabs based on the scene prompt."
      },
      "typeVersion": 1
    },
    {
      "id": "15b9e2b1-72d9-42bf-a8a4-0ad0a01c5e5f",
      "name": "Upload Sound to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        780,
        480
      ],
      "parameters": {
        "name": "={{ $('Get data from Google Sheet').item.json['Background (EN)'] }}.mp3",
        "driveId": {
          "__rl": true,
          "mode": "id",
          "value": "1Sfv2PvIHF0J3-5IOYFdZp2-4LNPOoSX1"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "OEWvSsY5xiUhqOnx",
          "name": "Google Drive account - PeakWave"
        }
      },
      "typeVersion": 3,
      "alwaysOutputData": true
    },
    {
      "id": "2a628e8a-077a-4999-9ef7-8d28ac4433ac",
      "name": "Save Video Background Locally1",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        1040,
        280
      ],
      "parameters": {
        "options": {},
        "fileName": "=VideoBackground.mp4",
        "operation": "write"
      },
      "typeVersion": 1
    },
    {
      "id": "fa5cce8d-4b50-4221-9446-050f497b30a9",
      "name": "Get Binary Video Background",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        820,
        280
      ],
      "parameters": {
        "url": "={{ $json.data.output.video_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ea003577-5467-4acb-a33b-b4b30a03a35f",
      "name": "Save Music Background Locally1",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        980,
        560
      ],
      "parameters": {
        "options": {
          "append": false
        },
        "fileName": "=SoundBackground.mp3",
        "operation": "write"
      },
      "typeVersion": 1
    },
    {
      "id": "b9332740-c4e0-40f9-bc0d-c550c8f0f96d",
      "name": "Prepare Overlay Text (Quote & Author)1",
      "type": "n8n-nodes-base.code",
      "position": [
        300,
        860
      ],
      "parameters": {
        "jsCode": "// Define separate configuration for the quote and the author\nconst quoteFont = \"Kanit-Italic.ttf\";      \nconst quoteFontSize = 70;\nconst authorFont = \"Kanit-Italic.ttf\";     \nconst authorFontSize = 50;\nconst fontColor = \"white\";\nconst lineHeightMultiplier = 1.1;\nconst videoWidth = 1080;\nconst margin = 40;  \n\n// Effective width for the quote text\nconst effectiveVideoWidth = videoWidth - 2 * margin;\n\n// Estimate average character width based on quoteFontSize\nconst avgCharWidth = quoteFontSize * 0.6;\nconst maxCharsPerLine = Math.floor(effectiveVideoWidth / avgCharWidth);\n\n// Retrieve the quote and author from \"Select Random Video, Music & Quote\"\nconst transcript = $('Get data from Google Sheet').first().json['Quote (Thai)'];\nif (!transcript) {\n  throw new Error(\"Quote not found\");\n}\n\nconst author = $('Get data from Google Sheet').first().json['Pen Name (Thai)'];\nif (!author) {\n  throw new Error(\"Author not found\");\n}\n\n// Split transcript into words and group them into lines\nconst words = transcript.split(' ');\nconst lines = [];\nlet currentLine = \"\";\nlet currentCharCount = 0;\n\nwords.forEach(word => {\n  const wordLength = word.length;\n  const additionalSpace = currentLine ? 1 : 0;\n  const potentialLength = currentCharCount + additionalSpace + wordLength;\n  if (potentialLength <= maxCharsPerLine) {\n    currentLine += (currentLine ? \" \" : \"\") + word;\n    currentCharCount = potentialLength;\n  } else {\n    lines.push(currentLine);\n    currentLine = word;\n    currentCharCount = wordLength;\n  }\n});\nif (currentLine) {\n  lines.push(currentLine);\n}\n\n// Calculate layout for the quote block\nconst lineHeight = quoteFontSize * lineHeightMultiplier;\nconst totalHeight = lines.length * lineHeight;\n\n// Build drawtext commands for quote lines\nconst quoteCommands = lines.map((line, index) => {\n  const escapedLine = line.replace(/'/g, \"\\\\'\");\n  return `drawtext=fontfile=${quoteFont}:text='${escapedLine}':fontsize=${quoteFontSize}:fontcolor=${fontColor}:x=(w-text_w)/2:y=((h-${totalHeight})/2)+(${index}*${lineHeight})`;\n});\n\n// Build the drawtext command for author\nconst authorY = `((h-${totalHeight})/2)+(${lines.length}*${lineHeight})+20`;\nconst escapedAuthor = author.replace(/'/g, \"\\\\'\");\nconst authorCommand = `drawtext=fontfile=${authorFont}:text='${escapedAuthor}':fontsize=${authorFontSize}:fontcolor=${fontColor}:x=w-text_w-${margin}:y=${authorY}`;\n\n// Combine all commands into one drawtext filter string\nconst fullDrawTextFilter = quoteCommands.concat(authorCommand).join(\", \");\n\n// Return the prepared filter string\nreturn {\n  json: {\n    drawText: fullDrawTextFilter\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "79764093-f6ca-459b-a73c-3326fe82fafa",
      "name": "Generate Final Video Clip1",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        480,
        860
      ],
      "parameters": {
        "command": "=ffmpeg -i {{ $('Save Video Background Locally1').item.json.fileName }} -i {{ $('Save Music Background Locally1').item.json.fileName }} -filter_complex \"[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920[vid]; color=black@0.3:size=1080x1920:d=10[bg]; [vid][bg]overlay=shortest=1[bgvid]; [bgvid]{{ $json.drawText }}[outv]; [1:a]volume=0.8[aout]\" -map \"[outv]\" -map \"[aout]\" -aspect 9:16 -c:v libx264 -c:a aac -shortest output.mp4 -y"
      },
      "typeVersion": 1
    },
    {
      "id": "3c301b6b-d6cb-41af-ac52-5722bed8470d",
      "name": "Initiate YouTube Resumable Upload",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        700,
        860
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/upload/youtube/v3/videos?part=snippet,status&uploadType=resumable",
        "body": "={\n  \"snippet\": {\n    \"title\": \"{{ $('Get data from Google Sheet').item.json['Quote (Thai)'] }}\",\n    \"description\": \"{{ $('Get data from Google Sheet').item.json['Quote (Thai)'] }}\\n{{ $('Get data from Google Sheet').item.json['Pen Name (Thai)'] }}\",\n    \"defaultLanguage\": \"en\",\n    \"defaultAudioLanguage\": \"en\"\n  },\n  \"status\": {\n    \"privacyStatus\": \"public\",\n    \"license\": \"youtube\",\n    \"embeddable\": true,\n    \"publicStatsViewable\": true,\n    \"madeForKids\": false\n  }\n}",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        },
        "sendBody": true,
        "contentType": "raw",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "rawContentType": "RAW/JSON",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "X-Upload-Content-Type",
              "value": "video/webm"
            }
          ]
        },
        "nodeCredentialType": "youTubeOAuth2Api"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "f9uNp5YNQMnXrNw2",
          "name": "YouTube account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "dbde06b3-e7ba-4b7e-9d58-0a06f88b5176",
      "name": "Read output file",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        880,
        860
      ],
      "parameters": {
        "options": {},
        "fileSelector": "=output.mp4"
      },
      "typeVersion": 1
    },
    {
      "id": "0b9b92e0-5500-4dca-a622-f63b3cdf0878",
      "name": "Upload Video to YouTube",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1080,
        860
      ],
      "parameters": {
        "url": "={{ $('Initiate YouTube Resumable Upload').item.json.headers.location }}",
        "method": "PUT",
        "options": {},
        "sendBody": true,
        "contentType": "binaryData",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "video/webm"
            }
          ]
        },
        "inputDataFieldName": "data",
        "nodeCredentialType": "youTubeOAuth2Api"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "f9uNp5YNQMnXrNw2",
          "name": "YouTube account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "721078b6-b1e2-4077-b1ff-696cb3765675",
      "name": "Update Quote Upload Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1280,
        860
      ],
      "parameters": {
        "columns": {
          "value": {
            "Index": "={{ $('Get data from Google Sheet').item.json.Index }}",
            "Video Status": "=https://www.youtube.com/watch?v={{ $json.id }}"
          },
          "schema": [
            {
              "id": "Index",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Index",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quote (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Quote (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pen Name (Thai)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Pen Name (Thai)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prompt (EN)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Prompt (EN)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Image",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Background Video",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Background Video",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Music Background",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Music Background",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Video Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Index"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1p1iPoiu2uI3qGbHi0diS7QwsMcLuzDIqwo3AeSUVrGQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "Ra2f1dlqOJ13jTtb",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "8900abd9-9f35-46a3-9b59-883ff16b0764",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        660,
        760
      ],
      "parameters": {
        "color": 5,
        "width": 760,
        "height": 300,
        "content": "## Video Upload & Post-Processing\nUpload the final video to YouTube using the YouTube API and update your Google Sheets with upload statuses and YouTube links."
      },
      "typeVersion": 1
    },
    {
      "id": "07cdec2c-9677-46f0-8038-641c4c191059",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 340,
        "height": 240,
        "content": "## Get Quote\nRetrieve quote data from Google Sheets including text, author, and background prompts."
      },
      "typeVersion": 1
    },
    {
      "id": "aeadbc59-13d7-4755-b38d-6d4946ecfa78",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        760
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 300,
        "content": "## Combine All\nMerge video, sound, and quote text into final clip using FFmpeg."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "2c56841d-3045-4d6d-b643-0f3804bf2c3e",
  "connections": {
    "Get Video": {
      "main": [
        [
          {
            "node": "Get Binary Video Background",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get image": {
      "main": [
        [
          {
            "node": "Update image background URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Audio": {
      "main": [
        [
          {
            "node": "Upload Sound to Google Drive",
            "type": "main",
            "index": 0
          },
          {
            "node": "Save Music Background Locally1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Image": {
      "main": [
        [
          {
            "node": "Wait image 2 min",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image-to-Video": {
      "main": [
        [
          {
            "node": "Wait video 5 min",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read output file": {
      "main": [
        [
          {
            "node": "Upload Video to YouTube",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait image 2 min": {
      "main": [
        [
          {
            "node": "Get image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait video 5 min": {
      "main": [
        [
          {
            "node": "Get Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Video to YouTube": {
      "main": [
        [
          {
            "node": "Update Quote Upload Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Final Video Clip1": {
      "main": [
        [
          {
            "node": "Initiate YouTube Resumable Upload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get data from Google Sheet": {
      "main": [
        [
          {
            "node": "Generate Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Quote Upload Status": {
      "main": [
        []
      ]
    },
    "Get Binary Video Background": {
      "main": [
        [
          {
            "node": "Save Video Background Locally1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Sound background URL": {
      "main": [
        []
      ]
    },
    "Update image background URL": {
      "main": [
        [
          {
            "node": "Image-to-Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update video background URL": {
      "main": [
        [
          {
            "node": "Generate Audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Sound to Google Drive": {
      "main": [
        [
          {
            "node": "Update Sound background URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Music Background Locally1": {
      "main": [
        [
          {
            "node": "Prepare Overlay Text (Quote & Author)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Video Background Locally1": {
      "main": [
        [
          {
            "node": "Update video background URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initiate YouTube Resumable Upload": {
      "main": [
        [
          {
            "node": "Read output file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Get data from Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Overlay Text (Quote & Author)1": {
      "main": [
        [
          {
            "node": "Generate Final Video Clip1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Workflow n8n YouTube, Google Sheets, vidéo : pour qui est ce workflow ?

Ce workflow s'adresse aux créateurs de contenu, aux marketeurs et aux entreprises qui souhaitent automatiser la production de vidéos inspirantes. Il est idéal pour les équipes ayant un niveau technique intermédiaire et cherchant à optimiser leur processus de publication sur YouTube.

Workflow n8n YouTube, Google Sheets, vidéo : problème résolu

Ce workflow résout le problème de la création manuelle de vidéos, qui peut être chronophage et sujet à des erreurs. En automatisant le processus de génération de vidéos à partir de citations, les utilisateurs peuvent économiser du temps et garantir une publication régulière de contenu de qualité. Cela réduit également le stress lié à la gestion des ressources multimédias et à la mise à jour des statuts dans les feuilles de calcul.

Workflow n8n YouTube, Google Sheets, vidéo : étapes du workflow

Étape 1 : Le workflow est déclenché manuellement.

  • Étape 1 : Une image est générée via une requête HTTP.
  • Étape 2 : L'image est récupérée pour être utilisée dans la vidéo.
  • Étape 3 : Le workflow attend deux minutes pour le traitement de l'image.
  • Étape 4 : Un clip vidéo est généré en combinant l'image et le son.
  • Étape 5 : Le son est uploadé sur Google Drive.
  • Étape 6 : La vidéo est uploadée sur YouTube.
  • Étape 7 : Les statuts des uploads sont mis à jour dans Google Sheets.

Workflow n8n YouTube, Google Sheets, vidéo : guide de personnalisation

Pour personnaliser ce workflow, vous pouvez modifier l'URL de la requête HTTP pour générer des images spécifiques ou ajuster les paramètres de l'API YouTube pour l'upload. Il est également possible de changer le nom des fichiers audio et vidéo lors de leur sauvegarde sur Google Drive. Si vous souhaitez intégrer d'autres outils, vous pouvez ajouter des noeuds supplémentaires pour enrichir le contenu vidéo ou automatiser d'autres étapes du processus. Assurez-vous de sécuriser les accès aux API en utilisant des clés d'authentification appropriées.