Téléchargement automatisé de vidéos YouTube, planification avec un intervalle de 12 heures selon le fuseau horaire JST

Intermédiaire

Ceci est unSocial Mediaworkflow d'automatisation du domainecontenant 14 nœuds.Utilise principalement des nœuds comme Code, YouTube, ManualTrigger, ReadWriteFile, ExecuteCommand. Téléchargement automatisé de vidéos YouTube, planification d'intervalle de 12 heures dans le fuseau horaire JST

Prérequis
  • Aucun prérequis spécial, prêt à l'emploi après importation
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "4acf4aaf155ef1444d1a0e89138bdc36df3deeb328e5be768fe60b8b9b336e06",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "8614b18c-d37b-44cf-859a-61963f81d495",
      "name": "Déclencheur Manuel",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -272,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2a864e15-008d-460c-b002-c7e6369b393a",
      "name": "Lister les Fichiers Vidéo",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        -64,
        0
      ],
      "parameters": {
        "command": "find /opt/downloads/单词卡/A1-A2 -type f -name '*.mp4' -print0"
      },
      "typeVersion": 1
    },
    {
      "id": "89a41e82-e8e5-41d1-9077-55441e0f44b9",
      "name": "Trier et Générer les Éléments",
      "type": "n8n-nodes-base.code",
      "position": [
        144,
        0
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.stdout ?? '';\nconst paths = raw.split('\\u0000').filter(Boolean);\n\nfunction extractDayNum(p) {\n  const name = p.split('/').pop();\n  const m = name.match(/day[-_ ]*(\\d+)/i);\n  return m ? parseInt(m[1], 10) : Number.POSITIVE_INFINITY;\n}\n\nconst sorted = paths\n  .filter(p => p.toLowerCase().endsWith('.mp4'))\n  .map(p => ({\n    path: p,\n    filename: p.split('/').pop(),\n    day: extractDayNum(p),\n  }))\n  .sort((a, b) => (a.day - b.day) || a.filename.localeCompare(b.filename));\n\nreturn sorted.map((it, i) => ({\n  json: {\n    path: it.path,\n    filename: it.filename,\n    day: it.day,\n    order: i\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ab5c0131-dc14-4207-9256-b181343b0118",
      "name": "Calculer le Planning de Publication (+12h d'intervalle)",
      "type": "n8n-nodes-base.code",
      "position": [
        368,
        0
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// === Parameters (can be changed) ===\nconst SPAN_HOURS   = 12;          // Each interval hour\nconst TZ_OFFSET_MS = 9 * 3600e3;  // JST +09:00\nconst BUFFER_MIN   = 30;          // Buffer minutes for processing the platform\n\n// === Read and check the serial number ===\nconst rawOrder = $json.order ?? $json.index ?? 0;\nconst order = Number(rawOrder);\nif (!Number.isFinite(order) || order < 0) {\n  throw new Error(`Invalid order/index: ${rawOrder}`);\n}\n\n// === Calculate \"the next whole point of JST + buffer\" in pure milliseconds ===\n// Move the current UTC time to the \"wall clock time\" of JST\nconst nowUtcMs   = Date.now();\nconst nowJstMs   = nowUtcMs + TZ_OFFSET_MS;\n\n// Align to the next whole point of JST (up to the next hour)\nconst HOUR_MS    = 3600e3;\nconst MIN_MS     = 60e3;\nconst nextHourJstMs = Math.ceil(nowJstMs / HOUR_MS) * HOUR_MS;\n\n// Add buffer minutes\nconst baseJstMs  = nextHourJstMs + BUFFER_MIN * MIN_MS;\n\n// JST release time of the current entry (overlay interval by serial number)\nconst publishJstMs = baseJstMs + order * SPAN_HOURS * HOUR_MS;\n\n// Then move back to UTC and give YouTube's publishAt\nconst publishUtcMs  = publishJstMs - TZ_OFFSET_MS;\nconst publishAtUtc  = new Date(publishUtcMs).toISOString();\n\n// Log only (JST readable)\nconst publishAtLocal = new Date(publishJstMs).toISOString().slice(0,19) + '+09:00';\n\nreturn {\n  publishAtUtc,            // To the YouTube node\n  publishAtLocal,          // Log only\n  filename: ($json.path ?? '').split('/').pop(),\n  order\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b4fafaac-c6aa-46a2-bba7-67d9552ca667",
      "name": "Diviser en Lots (1 par vidéo)",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        576,
        0
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "b077ea9f-5e76-48da-a3d0-09cf548c0da4",
      "name": "Lire le Fichier Vidéo",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        832,
        16
      ],
      "parameters": {
        "options": {},
        "fileSelector": "=/opt/downloads/单词卡/A1-A2/{{ $json.filename }}"
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "3e2cd625-012a-4451-aa2a-f3f049f82c0f",
      "name": "Télécharger vers YouTube (Planifié)",
      "type": "n8n-nodes-base.youTube",
      "position": [
        1072,
        16
      ],
      "parameters": {
        "title": "A1–A2单词打卡计划 #轻松学英语 #英语学习 #英语单词 #英语打卡 #零基础英语",
        "options": {
          "tags": "轻松学英语,英语学习,英语单词,英语打卡,零基础英语",
          "publishAt": "={{ $('Split in Batches (1 per video)').item.json.publishAtUtc }}",
          "description": "=A1–A2 英语单词学习系列 | 零基础英语 | 每天10分钟掌握核心词汇 帮助初学者系统学习基础英语词汇,从A1到A2逐步提升。 轻松学英语、英语打卡、自学复习必备。 #英语学习 #英语单词 #零基础英语 #EnglishVocabulary #A1A2English",
          "privacyStatus": "private"
        },
        "resource": "video",
        "operation": "upload",
        "categoryId": "27",
        "regionCode": "CN"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "VM0cz4mwPyGDwQHo",
          "name": "YouTube account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 3000
    },
    {
      "id": "ee967e9e-66b7-475c-b4c6-cb1f194a2304",
      "name": "Ajouter à la Playlist",
      "type": "n8n-nodes-base.youTube",
      "position": [
        1280,
        16
      ],
      "parameters": {
        "options": {},
        "videoId": "={{ $json.uploadId }}",
        "resource": "playlistItem",
        "playlistId": "PLJ3aD-smyb90ZmBJ9jcuW7AcnGeHF_jfF"
      },
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "VM0cz4mwPyGDwQHo",
          "name": "YouTube account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 3000
    },
    {
      "id": "a52f2b0e-546a-4dd9-b929-a3ed35a28b31",
      "name": "Note Adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -464
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 224,
        "content": "# Overview\n\n\nThis workflow automates video publishing to YouTube.\nIt lists local video files, generates upload metadata, schedules each upload every 12 hours, then uploads and adds them to a YouTube playlist."
      },
      "typeVersion": 1
    },
    {
      "id": "7bfa8a61-3eab-42eb-a3fe-52bf180cf7b0",
      "name": "Note Adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 176,
        "content": "## List & Prepare Files\n\nRetrieves all video files from the local folder and prepares them as workflow items.\nEach item includes the file path and basic information for later processing."
      },
      "typeVersion": 1
    },
    {
      "id": "2ff489ca-c9ff-4f99-b0ce-849a05b21ccc",
      "name": "Note Adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        176
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 192,
        "content": "## Sort & Schedule Uploads\n\nSorts videos in the correct order and calculates a publish schedule.\nEach video is assigned a publishAt time spaced 12 hours apart from the previous one."
      },
      "typeVersion": 1
    },
    {
      "id": "9d4dec38-c545-4e79-8607-eaddf83ff697",
      "name": "Note Adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 192,
        "content": "## Process in Batches\n\nEnsures videos are handled one by one.\nPrevents large uploads from overloading memory and makes error recovery easier."
      },
      "typeVersion": 1
    },
    {
      "id": "e1ea7552-4668-4d16-bd9c-d47464bdd3d9",
      "name": "Note Adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 192,
        "content": "## Upload to YouTube\n\nReads each video from disk and uploads it to YouTube as a scheduled private upload.\nThe video becomes public automatically at its scheduled publishAt time."
      },
      "typeVersion": 1
    },
    {
      "id": "f9380df2-f7e4-439c-a07c-cdf679ff01e7",
      "name": "Note Adhésive5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 192,
        "content": "## Add to Playlist\n\nAfter upload, each video is automatically added to the specified YouTube playlist to keep the channel content organized."
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "8614b18c-d37b-44cf-859a-61963f81d495": {
      "main": [
        [
          {
            "node": "2a864e15-008d-460c-b002-c7e6369b393a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ee967e9e-66b7-475c-b4c6-cb1f194a2304": {
      "main": [
        [
          {
            "node": "b4fafaac-c6aa-46a2-bba7-67d9552ca667",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b077ea9f-5e76-48da-a3d0-09cf548c0da4": {
      "main": [
        [
          {
            "node": "3e2cd625-012a-4451-aa2a-f3f049f82c0f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2a864e15-008d-460c-b002-c7e6369b393a": {
      "main": [
        [
          {
            "node": "89a41e82-e8e5-41d1-9077-55441e0f44b9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "89a41e82-e8e5-41d1-9077-55441e0f44b9": {
      "main": [
        [
          {
            "node": "ab5c0131-dc14-4207-9256-b181343b0118",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3e2cd625-012a-4451-aa2a-f3f049f82c0f": {
      "main": [
        [
          {
            "node": "ee967e9e-66b7-475c-b4c6-cb1f194a2304",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b4fafaac-c6aa-46a2-bba7-67d9552ca667": {
      "main": [
        [],
        [
          {
            "node": "b077ea9f-5e76-48da-a3d0-09cf548c0da4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ab5c0131-dc14-4207-9256-b181343b0118": {
      "main": [
        [
          {
            "node": "b4fafaac-c6aa-46a2-bba7-67d9552ca667",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Intermédiaire - Réseaux sociaux

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Intermédiaire
Nombre de nœuds14
Catégorie1
Types de nœuds7
Description de la difficulté

Adapté aux utilisateurs expérimentés, avec des workflows de complexité moyenne contenant 6-15 nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34