Conversion de livres électroniques en audio

Avancé

Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 19 nœuds.Utilise principalement des nœuds comme Code, Wait, FormTrigger, GoogleDrive, HttpRequest. Conversion de livres électroniques en audiobooks avec MiniMax et FFmpeg

Prérequis
  • Informations d'identification Google Drive API
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
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
{
  "id": "bX6cyG6u0dUYo1gM",
  "meta": {
    "instanceId": "90d03af248d07e2ebe7c0ecf1b18f488f6465e5560f151e375f9e5ab447ab951",
    "templateCredsSetupCompleted": true
  },
  "name": "EBOOK",
  "tags": [],
  "nodes": [
    {
      "id": "7d65ca00-5f29-4e11-aaa8-77f8680add0c",
      "name": "Enregistrer les extraits audio",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        64,
        0
      ],
      "parameters": {
        "options": {},
        "fileName": "=/tmp/audio {{$itemIndex}}.mp3",
        "operation": "write",
        "dataPropertyName": "=audio {{ $itemIndex }}"
      },
      "typeVersion": 1
    },
    {
      "id": "0adc9201-3479-450f-8b5e-6bbf16cf01d2",
      "name": "Générer `concat_list.txt`",
      "type": "n8n-nodes-base.code",
      "position": [
        -240,
        192
      ],
      "parameters": {
        "jsCode": "/**\n * This Code node will:\n * 1. Gather all file paths from the incoming items (assuming each item has `item.json.filePath`).\n * 2. Build a single text string, each line in FFmpeg concat format: `file '/path/to/audio.mp3'`\n * 3. Convert that text to binary (Base64) so the next node (\"Write Binary File\") can save it as `concat_list.txt`.\n */\n\nconst items = $input.all();\n\n// Build the concat list\nlet concatListText = '';\n\nitems.forEach((item, index) => {\n  let filePath;\n\n\n  // Use only fileName for the rest\n    filePath = item.json.fileName;\n\n\n  if (filePath) {\n    concatListText += `file '${filePath}'\\n`;\n  }\n});\n\n// Convert the text to a Buffer, then to Base64\nconst buffer = Buffer.from(concatListText, 'utf-8');\nconst base64Data = buffer.toString('base64');\n\n// Return a single item containing the binary data\nreturn [\n  {\n    json: {},\n    binary: {\n      data: {\n        data: base64Data,\n        mimeType: 'text/plain',\n        fileName: 'concat_list.txt'\n      }\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "c9aa3a38-449f-44a4-92d3-f28c1c29114c",
      "name": "Enregistrer concat_list",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        96,
        192
      ],
      "parameters": {
        "options": {},
        "fileName": "/tmp/concat_list.txt",
        "operation": "write"
      },
      "typeVersion": 1
    },
    {
      "id": "956de46d-86b8-40ec-81c0-91fe87113d75",
      "name": "Joindre les extraits audio et supprimer tous les fichiers",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        -240,
        400
      ],
      "parameters": {
        "command": "ffmpeg -y -f concat -safe 0 -i /tmp/concat_list.txt \\\n-c copy /tmp/final_merged.mp3\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1405b1fb-7a4f-45d9-976c-121437ece794",
      "name": "Lire final_merged",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        96,
        400
      ],
      "parameters": {
        "options": {},
        "fileSelector": "/tmp/final_merged.mp3"
      },
      "typeVersion": 1
    },
    {
      "id": "13749486-4e35-4444-9734-3be869668540",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1680,
        -144
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 1024,
        "content": "## EBOOK EXTRACTION MODULE\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nA sample [Little Red Riding Hood.pdf](https://www.laburnumps.vic.edu.au/uploaded_files/media/little_red_riding_hood.pdf)\n\n![Ebook](https://articles.emp0.com/wp-content/uploads/2025/10/Screenshot-from-2025-10-20-18-59-28.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "f7a4e41c-3d00-4918-af1c-e1a772905671",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        -144
      ],
      "parameters": {
        "color": 3,
        "width": 704,
        "height": 1024,
        "content": "## EBOOK TO AUDIOBOOK CONVERSION MODULE\n\nBreaks the large chunk of text into paragraphs and translate in batches of 5 paragraphs each\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n```json\n[\n  {\n    \"order\": 1,\n    \"text\": \"Little Red Riding Hood by Leanne Guenther Once upon a time, there was a little girl who lived in a village near the forest. Whenever she went out, the little girl wore a red riding cloak, so everyone in the village called her Little Red Riding Hood. One morning, Little Red Riding Hood’s mother asked her to take some food to her grandmother, as she had been ill. So they packed a nice basket for Little Red Riding Hood to take to her grandmother.\"\n  },\n  {\n    \"order\": 2,\n    \"text\": \"When the basket was ready, the little girl put on her red cloak and kissed her mother goodbye. \\\\\\\"Remember, go straight to Grandma's house,\\\\\\\" her mother cautioned. \\\\\\\"Don't dawdle along the way and please don't talk to strangers! The woods are dangerous.\\\\\\\" \\\\\\\"Don't worry, mommy,\\\\\\\" said Little Red Riding Hood, \\\\\\\"I'll be careful.\\\\\\\" But when Little Red Riding Hood noticed some lovely flowers in the woods, she forgot her promise to her mother.\"\n  },\n  {\n    \"order\": 3,\n    \"text\": \"She picked a few, watched the butterflies flit about for awhile, listened to the frogs croaking and then picked a few more. Little Red Riding Hood was enjoying the warm summer day so much, that she didn't notice a dark shadow approaching out of the forest behind her... Suddenly, the wolf appeared beside her. \\\\\\\"What are you doing out here, little girl and where are you going?\\\\\\\" the wolf asked in a voice as friendly as he could muster.\"\n  },\n  {\n    \"order\": 4,\n    \"text\": \"\\\\\\\"I'm on my way to see my Grandma who lives through the forest, near the brook,\\\\\\\" Little Red Riding Hood replied. Then she realized how late she was and quickly excused herself, rushing down the path to her Grandma's house. The wolf, in the meantime, took a shortcut... The wolf, a little out of breath from running, arrived at Grandma's and knocked lightly at the door. \\\\\\\"Oh thank goodness dear. Come in. Come in.\"\n  },\n  {\n    \"order\": 5,\n    \"text\": \"I was worried that something had happened to you in the forest,\\\\\\\" said Grandma thinking that the knock was her granddaughter. The wolf let himself in. Poor Granny did not have time to say another word, before the wolf gobbled her up! The wolf let out a satisfied burp, and then poked through Granny's wardrobe to find a nightgown that he liked. He added a frilly sleeping cap, and for good measure, dabbed some of Granny's perfume behind his pointy ears.\"\n  }\n]\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "cf4982e5-e3ac-4ade-8fac-557a54c93a68",
      "name": "Note adhésive 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        -144
      ],
      "parameters": {
        "color": 5,
        "width": 656,
        "height": 1024,
        "content": "## AUDIO MERGING MODULE\n\n\nUses FFMPEG to combine multiple audio files into one \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nCan only work in self hosted n8n with ffmpeg installed. You cannot install the library on n8n cloud\n```json\nffmpeg -y -f concat -safe 0 -i /tmp/concat_list.txt \\\n-c copy /tmp/final_merged.mp3\n``"
      },
      "typeVersion": 1
    },
    {
      "id": "0b98b51d-f5a1-4107-903d-7d419cd6b75e",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 400,
        "content": "## UPLOADS THE EBOOK TO DRIVE.\n\n[Resulting output](https://drive.google.com/file/d/12aVR2p-ZQ2DyqXCUgJPouzy-acoAB7WO/view?usp=sharing)"
      },
      "typeVersion": 1
    },
    {
      "id": "57a896d1-6d7e-4cba-b55a-d3ab31742f7c",
      "name": "FORMULAIRE",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1632,
        -48
      ],
      "webhookId": "d95584f4-a526-4218-8f75-2b17272ebba9",
      "parameters": {
        "options": {
          "appendAttribution": false
        },
        "formTitle": "Ebook to Audiobook",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "UPLOAD",
              "multipleFiles": false,
              "requiredField": true
            }
          ]
        },
        "formDescription": "Upload your Ebook here"
      },
      "typeVersion": 2.3
    },
    {
      "id": "ad8b130e-e51d-40ad-85a1-9ce98e978422",
      "name": "EXTRAIRE LE TEXTE",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1456,
        -48
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "UPLOAD"
      },
      "typeVersion": 1
    },
    {
      "id": "3e47b303-ea16-4b57-9df3-227a4c3f7566",
      "name": "DIVISER LE TEXTE SELON LES RÈGLES",
      "type": "n8n-nodes-base.code",
      "position": [
        -1264,
        -48
      ],
      "parameters": {
        "jsCode": "const rawText = $input.first().json.text || \"\";\n\n// Clean function for JSON/TTS\nfunction cleanText(str) {\n    return str\n        .replace(/\\\\\\\\n/g, \" \")\n        .replace(/\\\\n/g, \" \")\n        .replace(/\\\\/g, \"\\\\\\\\\")\n        .replace(/\"/g, '\\\\\"')\n        .replace(/(\\r\\n|\\r|\\n)+/g, \" \")\n        .replace(/\\s+/g, \" \")\n        .trim();\n}\n\nconst text = cleanText(rawText);\n\nconst sentences = text.split(/(?<=[.!?])\\s+/).filter(Boolean);\n\nconst maxChars = 500;\nlet parts = [];\nlet chunk = \"\";\n\nfor (let sentence of sentences) {\n    if (sentence.length > maxChars) {\n        // Split very long sentence into smaller pieces\n        let start = 0;\n        while (start < sentence.length) {\n            const sub = sentence.slice(start, start + maxChars);\n            if (chunk) parts.push(chunk);\n            parts.push(sub);\n            chunk = \"\";\n            start += maxChars;\n        }\n        continue;\n    }\n\n    const space = chunk ? \" \" : \"\";\n    if ((chunk + space + sentence).length > maxChars) {\n        if (chunk) parts.push(chunk);\n        chunk = sentence;\n    } else {\n        chunk += space + sentence;\n    }\n}\n\nif (chunk) parts.push(chunk);\nconst result = parts.map((p, i) => ({ order: i + 1, text: p }));\n\nreturn result.map(r => ({ json: r }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "40d0a3d3-e4d0-4b0a-82d4-393aa5ad3aa2",
      "name": "Boucler sur les segments de texte (5) à la fois",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -1024,
        144
      ],
      "parameters": {
        "options": {},
        "batchSize": 5
      },
      "typeVersion": 3
    },
    {
      "id": "2c369974-0d97-405d-9121-cbcb5648c00c",
      "name": "ATTENDRE 5 SECONDES",
      "type": "n8n-nodes-base.wait",
      "position": [
        -544,
        208
      ],
      "webhookId": "865809f7-7aea-40bd-9a0e-104a2ee18d73",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "c606fc3d-c0fc-41f7-a646-8f369ebea7ea",
      "name": "CONVERTIR L'URL EN FICHIERS AUDIO",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -800,
        0
      ],
      "parameters": {
        "url": "={{ $json.output }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "78cec513-0fe5-4325-93aa-198f63afdcd8",
      "name": "ASSIGNER DES INDEX AUX FICHIERS AUDIO",
      "type": "n8n-nodes-base.code",
      "position": [
        -240,
        0
      ],
      "parameters": {
        "jsCode": "return items.map((item, index) => {\n  // Make a new item\n  const newItem = { json: {}, binary: {} };\n\n  // Copy the JSON data if you have any\n  newItem.json = { ...item.json };\n\n  // Loop through all binary properties\n  for (let key in item.binary) {\n    // Rename the binary key\n    const newKey = `audio ${index}`;\n\n    // Copy the binary data\n    newItem.binary[newKey] = { ...item.binary[key] };\n\n    // Rename the file itself\n    newItem.binary[newKey].fileName = `${newKey}.mp3`; // change extension if needed\n  }\n\n  return newItem;\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d7b3d611-98d0-44fc-8ded-597f1e5ad916",
      "name": "Télécharger le livre électronique",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        432,
        0
      ],
      "parameters": {
        "name": "audiobook.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": "list",
          "value": "11eIODBtLZwiUjUVJvK97_Z42uPmEnMMu",
          "cachedResultUrl": "https://drive.google.com/drive/folders/11eIODBtLZwiUjUVJvK97_Z42uPmEnMMu",
          "cachedResultName": "Audiobook"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "4pJ4FbSsj82fOkbU",
          "name": "Gridve"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "33160ec4-53df-4a5c-95be-029065d4e2f7",
      "name": "MINIMAX TTS",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -768,
        208
      ],
      "parameters": {
        "url": "https://api.replicate.com/v1/models/minimax/speech-02-hd/predictions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"input\": {\n    \"text\": \"{{ $json.text }}\",\n    \"pitch\": 0,\n    \"speed\": 1,\n    \"volume\": 1,\n    \"bitrate\": 128000,\n    \"channel\": \"mono\",\n    \"emotion\": \"happy\",\n    \"voice_id\": \"Friendly_Person\",\n    \"sample_rate\": 32000,\n    \"language_boost\": \"English\",\n    \"english_normalization\": true\n  }\n} ",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Prefer",
              "value": "wait"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "w56BeWYVDLf1uQQ9",
          "name": "Bearer YOUR_TOKEN_HERE account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "88c3f2dc-5690-45ac-90d6-86c27bfeb04e",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2256,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 528,
        "height": 528,
        "content": "# Watch the [Youtube Demo Video](https://img.youtube.com/vi/xKqkjXIPZoM/0.jpg)\n\n![Youtube Demo](https://img.youtube.com/vi/xKqkjXIPZoM/0.jpg)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d82d1c3b-0657-4fc5-8691-40ef2fe01121",
  "connections": {
    "57a896d1-6d7e-4cba-b55a-d3ab31742f7c": {
      "main": [
        [
          {
            "node": "ad8b130e-e51d-40ad-85a1-9ce98e978422",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "33160ec4-53df-4a5c-95be-029065d4e2f7": {
      "main": [
        [
          {
            "node": "2c369974-0d97-405d-9121-cbcb5648c00c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ad8b130e-e51d-40ad-85a1-9ce98e978422": {
      "main": [
        [
          {
            "node": "3e47b303-ea16-4b57-9df3-227a4c3f7566",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c9aa3a38-449f-44a4-92d3-f28c1c29114c": {
      "main": [
        [
          {
            "node": "956de46d-86b8-40ec-81c0-91fe87113d75",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7d65ca00-5f29-4e11-aaa8-77f8680add0c": {
      "main": [
        [
          {
            "node": "0adc9201-3479-450f-8b5e-6bbf16cf01d2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1405b1fb-7a4f-45d9-976c-121437ece794": {
      "main": [
        [
          {
            "node": "d7b3d611-98d0-44fc-8ded-597f1e5ad916",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2c369974-0d97-405d-9121-cbcb5648c00c": {
      "main": [
        [
          {
            "node": "40d0a3d3-e4d0-4b0a-82d4-393aa5ad3aa2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0adc9201-3479-450f-8b5e-6bbf16cf01d2": {
      "main": [
        [
          {
            "node": "c9aa3a38-449f-44a4-92d3-f28c1c29114c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c606fc3d-c0fc-41f7-a646-8f369ebea7ea": {
      "main": [
        [
          {
            "node": "78cec513-0fe5-4325-93aa-198f63afdcd8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "78cec513-0fe5-4325-93aa-198f63afdcd8": {
      "main": [
        [
          {
            "node": "7d65ca00-5f29-4e11-aaa8-77f8680add0c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3e47b303-ea16-4b57-9df3-227a4c3f7566": {
      "main": [
        [
          {
            "node": "40d0a3d3-e4d0-4b0a-82d4-393aa5ad3aa2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "40d0a3d3-e4d0-4b0a-82d4-393aa5ad3aa2": {
      "main": [
        [
          {
            "node": "c606fc3d-c0fc-41f7-a646-8f369ebea7ea",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "33160ec4-53df-4a5c-95be-029065d4e2f7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "956de46d-86b8-40ec-81c0-91fe87113d75": {
      "main": [
        [
          {
            "node": "1405b1fb-7a4f-45d9-976c-121437ece794",
            "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é ?

Avancé - Création de contenu, IA Multimodale

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é
Avancé
Nombre de nœuds19
Catégorie2
Types de nœuds10
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Jay Emp0

Jay Emp0

@jay-emp0

AI and Automation developer. Im implementing n8n and ai tools to automate marketing and sales in companies

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34