{
  "id": "BJqsw0zgznLQCTeU",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "\ud83d\udca5 Generate AI Music & Publish to YouTube Automatically with Blotato - Mise en forme - vide",
  "tags": [],
  "nodes": [
    {
      "id": "7ba890c3-63d3-4880-9b48-c5b3b14e2c89",
      "name": "Music Generation Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -48,
        448
      ],
      "parameters": {
        "options": {
          "appendAttribution": false
        },
        "formTitle": "AI Music Generator for YouTube",
        "formFields": {
          "values": [
            {
              "fieldName": "duration",
              "fieldType": "dropdown",
              "fieldLabel": "Music Duration",
              "fieldOptions": {
                "values": [
                  {
                    "option": "30s"
                  },
                  {
                    "option": "1min"
                  },
                  {
                    "option": "2min"
                  },
                  {
                    "option": "3min"
                  },
                  {
                    "option": "5min"
                  }
                ]
              }
            },
            {
              "fieldName": "description",
              "fieldType": "textarea",
              "fieldLabel": "Music Description",
              "placeholder": "Describe the style, mood, and feel of the music you want..."
            },
            {
              "fieldName": "lyrics_type",
              "fieldType": "radio",
              "fieldLabel": "Vocal Type",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Instrumental"
                  },
                  {
                    "option": "With Lyrics"
                  }
                ]
              }
            }
          ]
        },
        "formDescription": "Generate custom AI music and publish it automatically to YouTube"
      },
      "typeVersion": 2.5
    },
    {
      "id": "4671d9e0-831c-4405-8f16-e03df4067363",
      "name": "Generate ElevenLabs Prompt",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        176,
        448
      ],
      "parameters": {
        "text": "=Dur\u00e9e : {{ $json.duration }}\nLyrics type : {{ $json.lyrics_type }}\nDescription :{{ $json.description }}",
        "options": {
          "systemMessage": "You are a music prompt optimizer. Transform user input into optimized ElevenLabs music generation parameters. Return a JSON object with: 1) prompt (string): an optimized musical description in English, 2) duration_ms (number): duration in milliseconds, 3) force_instrumental (boolean): true if instrumental, false if with lyrics, 4) youtube_title (string): an SEO-optimized YouTube title based on the music description."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "a96f0232-2a5a-4bb6-bfc5-7843b4a8f5e8",
      "name": "OpenAI gpt-4o-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        64,
        816
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.3
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "8abe3445-561d-4d32-adb7-bbcbf5490539",
      "name": "JSON Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        416,
        800
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"prompt\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"description\": \"Optimized music prompt\"\n\t\t},\n\t\t\"duration_ms\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"description\": \"Duration in milliseconds\"\n\t\t},\n\t\t\"force_instrumental\": {\n\t\t\t\"type\": \"boolean\",\n\t\t\t\"description\": \"True for instrumental, false for vocals\"\n\t\t},\n\t\t\"youtube_title\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"description\": \"SEO-optimized YouTube title\"\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "02cea2e4-4b04-4266-bf59-9b57fae3ce07",
      "name": "Generate Music - ElevenLabs",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        528,
        448
      ],
      "parameters": {
        "url": "https://api.elevenlabs.io/v1/music",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $('Generate ElevenLabs Prompt').item.json.output.prompt }}"
            },
            {
              "name": "duration_ms",
              "value": "={{ $('Generate ElevenLabs Prompt').item.json.output.duration_ms }}"
            },
            {
              "name": "force_instrumental",
              "value": "={{ $('Generate ElevenLabs Prompt').item.json.output.force_instrumental }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "d41d120c-5247-4703-9479-2df26cbdaefd",
      "name": "Generate Image Prompt",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        976,
        592
      ],
      "parameters": {
        "text": "=Based on this YouTube title: {{ $('Generate ElevenLabs Prompt').item.json.output.youtube_title }} and music description: {{ $('Music Generation Form').item.json.description }}, create a visual prompt for a YouTube thumbnail.",
        "options": {
          "systemMessage": "You are a visual prompt expert for AI image generation. Create a detailed, vivid prompt in English for generating a YouTube thumbnail (16:9 aspect ratio, 1280x720). The image should be eye-catching, professional, and related to the music theme. Focus on colors, composition, and visual elements that work well for YouTube thumbnails."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "89aff1d0-d705-4989-8a6a-2f535e0fbcd3",
      "name": "OpenAI gpt-4o-mini Image",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        976,
        848
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.7
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "31b0da6c-7533-4945-a651-f80138555b5c",
      "name": "Generate Thumbnail - Atlas Cloud",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1328,
        592
      ],
      "parameters": {
        "url": "https://api.atlascloud.ai/api/v1/model/generateImage",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $('Generate Image Prompt').item.json.output }}"
            },
            {
              "name": "aspect_ratio",
              "value": "16:9"
            },
            {
              "name": "model",
              "value": "google/nano-banana-2/text-to-image"
            },
            {
              "name": "output_format",
              "value": "png"
            },
            {
              "name": "resolution",
              "value": "1k"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "41820733-4843-4129-9c9b-0f683349c15c",
      "name": "Merge Audio & Image Paths",
      "type": "n8n-nodes-base.merge",
      "position": [
        1984,
        304
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "92c5ce04-5a7f-4163-9125-ff82bf46275c",
      "name": "Create post Youtube",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        3072,
        304
      ],
      "parameters": {
        "options": {},
        "platform": "youtube",
        "accountId": {
          "__rl": true,
          "mode": "list",
          "value": "30379",
          "cachedResultUrl": "https://backend.blotato.com/v2/accounts/30379",
          "cachedResultName": "Dr. Firas (PlayKids - English)"
        },
        "postContentText": "={{ $('Generate ElevenLabs Prompt').item.json.output.youtube_title }}",
        "postContentMediaUrls": "={{ $json.response.url }}",
        "postCreateYoutubeOptionTitle": "={{ $('Generate ElevenLabs Prompt').item.json.output.youtube_title }}"
      },
      "credentials": {
        "blotatoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "3fdf2e13-21d4-4693-919e-2400c0c93a84",
      "name": "Upload an asset from file data",
      "type": "n8n-nodes-cloudinary.cloudinary",
      "position": [
        768,
        288
      ],
      "parameters": {
        "operation": "uploadFile",
        "resource_type_file": "video",
        "additionalFieldsFile": {}
      },
      "credentials": {
        "cloudinaryApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8ba15d33-e629-41aa-a670-1e1a55ad75c8",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1568,
        848
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "60553b0c-47f7-4aef-9d4e-e1b53f246509",
      "name": "Check Image Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1808,
        592
      ],
      "parameters": {
        "url": "=https://api.atlascloud.ai/api/v1/model/prediction/{{ $('Extract Prediction ID').item.json.predictionId }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "ef055494-cc7e-49ca-9bf2-38acd85a382c",
      "name": "Extract Prediction ID",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        848
      ],
      "parameters": {
        "jsCode": "const response = $input.first().json;\n\nreturn [{\n  json: {\n    predictionId: response.data.id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "87f07a17-e408-436e-8719-66164a352af7",
      "name": "Wait2",
      "type": "n8n-nodes-base.wait",
      "position": [
        2672,
        304
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 1
      },
      "typeVersion": 1.1
    },
    {
      "id": "202f3412-307c-4ec4-807e-d34d205bfa6e",
      "name": "Shotstack Render",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2464,
        304
      ],
      "parameters": {
        "url": "https://api.shotstack.io/edit/v1/render",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"timeline\": {\n    \"soundtrack\": {\n      \"src\": \"{{$json.audioUrl}}\"\n    },\n    \"tracks\": [\n      {\n        \"clips\": [\n          {\n            \"asset\": {\n              \"type\": \"image\",\n              \"src\": \"{{$json.imageUrl}}\"\n            },\n            \"start\": 0,\n            \"length\": {{$json.duration}}\n          }\n        ]\n      }\n    ]\n  },\n  \"output\": {\n    \"format\": \"mp4\",\n    \"resolution\": \"sd\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_API"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "03fe7fb9-d00e-4093-9f4d-d29114bb4052",
      "name": "Shotstack Poll Result",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2864,
        304
      ],
      "parameters": {
        "url": "=https://api.shotstack.io/edit/v1/render/{{ $json.response.id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_API"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "e58d2c67-7357-49e4-9d0f-dace3f1c635c",
      "name": "Code clean urls",
      "type": "n8n-nodes-base.code",
      "position": [
        2224,
        304
      ],
      "parameters": {
        "jsCode": "const audioItem = items.find(item => item.json.secure_url || item.json.url);\nconst imageItem = items.find(item => item.json.imageUrl);\n\nif (!audioItem || !imageItem) {\n  return [];\n}\n\nreturn [\n  {\n    json: {\n      audioUrl: audioItem.json.secure_url || audioItem.json.url,\n      imageUrl: imageItem.json.imageUrl,\n      duration: audioItem.json.duration || 10\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "81354b07-87a7-4b14-8953-881302dae285",
      "name": "Code clear imageUrl",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        592
      ],
      "parameters": {
        "jsCode": "// Extract Final Image URL\n\nreturn items.map(item => {\n  const imageUrl =\n    item.json?.data?.outputs?.[0] || null;\n\n  return {\n    json: {\n      imageUrl\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b877b259-94a1-4f9a-8a09-d81444f44133",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        -416
      ],
      "parameters": {
        "width": 816,
        "height": 1904,
        "content": "# \ud83d\ude80  Generate AI Music & Publish to YouTube Automatically with Blotato\n## (By Dr. Firas)\n\nThis workflow generates AI music and publishes it to YouTube automatically\n---\n## \ud83c\udfa5 Tutorial :\n@[youtube](yit-6fuKAVU)\n\n---\n## \u2699\ufe0f How It Works\n1. Music Generation Form - Collects user input (duration, description, vocal type)\n2. Generate ElevenLabs Prompt - AI Agent transforms input into optimized parameters\n3. Generate Music - ElevenLabs - Calls ElevenLabs API to create the music audio\n4. Generate Image Prompt - AI Agent creates a visual prompt for the thumbnail\n5. Generate Thumbnail - Atlas Cloud - Generates a 16:9 YouTube thumbnail image\n6. Save Audio File & Save Image File - Writes files to /tmp/ directory\n7. FFmpeg - Create Video - Combines static image + audio into MP4 video\n8. Read Final Video - Loads the final MP4 file\n9. Publish to YouTube - Blotato - Uploads video to YouTube with title and description\n---\n\n## \ud83d\udd10 Credentials Needed\nRequired Credentials:\n\n1. OpenAI API Key\n   - Type: OpenAI API credentials\n   - Get it at: https://platform.openai.com/api-keys\n   - Used for: AI Agent nodes (prompt generation)\n\n2. ElevenLabs API Key\n   - Type: Header Auth (X-API-Key)\n   - Get it at: **[elevenlabs](https://elevenlabs.io/?from=drfirass2382)**\n   - Used for: Generate Music HTTP Request\n\n3. Atlas Cloud API Key\n   - Type: Header Auth (Authorization: Bearer)\n   - Get it at: **[AtlasCloud](https://www.atlascloud.ai?ref=8QKPJE)**\n   - Used for: Generate Thumbnail HTTP Request\n\n4. Blotato API Key\n   - Type: Blotato credentials\n   - Get it at: **[Blotato](https://blotato.com/?ref=firas)** \n   - Used for: YouTube video upload\n   - Install: npm install @blotato/n8n-nodes-blotato\n\n5. SSH Credentials (for FFmpeg)\n   - Type: SSH credentials (localhost)\n   - Required: FFmpeg installed on n8n server\n---\n\n## \ud83d\ude80 Setup Steps\n1- Add OpenAI credentials for prompt and content generation\n2- Add ElevenLabs credentials for music generation\n3- Add AtlasCloud credentials for image and thumbnail generation\n4- Add Shotstack credentials for video rendering\n5- Configure Upload & Merge nodes (audio + image paths)\n6- Add YouTube credentials and configure post settings\n7- Run a test and activate the workflow \ud83d\ude80"
      },
      "typeVersion": 1
    },
    {
      "id": "0b164baa-5f54-4eb0-b4c1-be4fbbfe5378",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 784,
        "content": "## \ud83c\udfb5 Generate Content Inputs\nCreates the base inputs for the workflow including prompts and music generation."
      },
      "typeVersion": 1
    },
    {
      "id": "bd17621c-8e1a-4a6f-8d44-0604f8cb481e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 1296,
        "height": 512,
        "content": "## \ud83d\uddbc\ufe0f AI Thumbnail Generation\nGenerates AI thumbnail using AtlasCloud and prepares image assets."
      },
      "typeVersion": 1
    },
    {
      "id": "4ea6d90e-03d4-4c53-a8ee-f4d53b0ed899",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2384,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 288,
        "content": "## \ud83c\udfac Video Rendering\nBuilds and renders the final video using Shotstack."
      },
      "typeVersion": 1
    },
    {
      "id": "46cdd430-e232-47ae-8c17-f7d57bace776",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3008,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 288,
        "content": "## \ud83d\udcfa YouTube Publishing\nPublishes the generated video automatically to YouTube."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "faafcee1-9b13-4dac-828a-1a345e7ea64e",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Check Image Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait2": {
      "main": [
        [
          {
            "node": "Shotstack Poll Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code clean urls": {
      "main": [
        [
          {
            "node": "Shotstack Render",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shotstack Render": {
      "main": [
        [
          {
            "node": "Wait2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Image Status": {
      "main": [
        [
          {
            "node": "Code clear imageUrl",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JSON Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Generate ElevenLabs Prompt",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI gpt-4o-mini": {
      "ai_languageModel": [
        [
          {
            "node": "Generate ElevenLabs Prompt",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code clear imageUrl": {
      "main": [
        [
          {
            "node": "Merge Audio & Image Paths",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Extract Prediction ID": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Image Prompt": {
      "main": [
        [
          {
            "node": "Generate Thumbnail - Atlas Cloud",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Music Generation Form": {
      "main": [
        [
          {
            "node": "Generate ElevenLabs Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shotstack Poll Result": {
      "main": [
        [
          {
            "node": "Create post Youtube",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI gpt-4o-mini Image": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Image Prompt",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Merge Audio & Image Paths": {
      "main": [
        [
          {
            "node": "Code clean urls",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate ElevenLabs Prompt": {
      "main": [
        [
          {
            "node": "Generate Music - ElevenLabs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Music - ElevenLabs": {
      "main": [
        [
          {
            "node": "Generate Image Prompt",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload an asset from file data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload an asset from file data": {
      "main": [
        [
          {
            "node": "Merge Audio & Image Paths",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Thumbnail - Atlas Cloud": {
      "main": [
        [
          {
            "node": "Extract Prediction ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}