電子書籍をオーディオブックに変換
上級
これはContent Creation, Multimodal AI分野の自動化ワークフローで、19個のノードを含みます。主にCode, Wait, FormTrigger, GoogleDrive, HttpRequestなどのノードを使用。 MiniMax と FFmpeg を使用して電子書籍をオーディオブックに変換する
前提条件
- •Google Drive API認証情報
- •ターゲットAPIの認証情報が必要な場合あり
使用ノード (19)
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
"id": "bX6cyG6u0dUYo1gM",
"meta": {
"instanceId": "90d03af248d07e2ebe7c0ecf1b18f488f6465e5560f151e375f9e5ab447ab951",
"templateCredsSetupCompleted": true
},
"name": "EBOOK",
"tags": [],
"nodes": [
{
"id": "7d65ca00-5f29-4e11-aaa8-77f8680add0c",
"name": "音声チャンクを保存",
"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": "`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": "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": "音声チャンクを結合し全ファイルを削除",
"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": "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": "付箋",
"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"
},
"typeVersion": 1
},
{
"id": "f7a4e41c-3d00-4918-af1c-e1a772905671",
"name": "付箋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": "付箋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": "付箋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": "フォーム",
"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": "テキストを抽出",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1456,
-48
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "UPLOAD"
},
"typeVersion": 1
},
{
"id": "3e47b303-ea16-4b57-9df3-227a4c3f7566",
"name": "ルールに従いテキストを分割",
"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": "テキストチャンクをループ処理(5つ毎)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-1024,
144
],
"parameters": {
"options": {},
"batchSize": 5
},
"typeVersion": 3
},
{
"id": "2c369974-0d97-405d-9121-cbcb5648c00c",
"name": "5秒間待機",
"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": "URLを音声ファイルに変換",
"type": "n8n-nodes-base.httpRequest",
"position": [
-800,
0
],
"parameters": {
"url": "={{ $json.output }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "78cec513-0fe5-4325-93aa-198f63afdcd8",
"name": "音声ファイルにインデックスを付与",
"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": "電子書籍をアップロード",
"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": "付箋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"
},
"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
}
]
]
}
}
}よくある質問
このワークフローの使い方は?
上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。
このワークフローはどんな場面に適していますか?
上級 - コンテンツ作成, マルチモーダルAI
有料ですか?
このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。
関連ワークフロー
オートメーション動画ジェネレーター
DeepSeek、TTS、Together.ai を使ってスクリプトから AI 動画を生成
Set
Code
Wait
+
Set
Code
Wait
81 ノードLakindu Siriwardana
コンテンツ作成
顔なし恐怖ショートビデオを Replicate と OpenAI で制作
OpenAI TTS、Replicateビデオ生成、YouTubeアップロードを使って無顔のホラーショート動画を作成
If
Code
Wait
+
If
Code
Wait
50 ノードDeb Mukherjee
コンテンツ作成
WordPressブログの自動化プロフェッショナル版(先端研究)v2.1マーケットプラグイン
GPT-4o、Perplexity AI、そして多言語対応を使ったSEO最適化ブログ作成の自動化
If
Set
Xml
+
If
Set
Xml
125 ノードDaniel Ng
コンテンツ作成
OpenAI、ElevenLabs、Fal.ai を使用した動画・パ odcast・ASM R向けのウイルス性コンテンツ自動作成
OpenAI、ElevenLabs、そして Fal.ai を使って動画、ポッドキャスト、ASMR に向けたウイルスのコンテンツ作成を自動化
Set
Code
Wait
+
Set
Code
Wait
97 ノードAdam Crafts
コンテンツ作成
Creatomate を使って短い動画を生成する
Creatomate、ElevenLabs、Pexels 素材ライブラリを使って AI ショートビデオを生成
If
Code
Wait
+
If
Code
Wait
31 ノードMatty Reed
コンテンツ作成
スクリプトからAIボイスを生成してGoogleドライブにアップロード
Gemini TTSでスクリプトからAI音声を生成し、Googleドライブにアップロード
Set
Code
Filter
+
Set
Code
Filter
20 ノードJJ Tham
コンテンツ作成
ワークフロー情報
難易度
上級
ノード数19
カテゴリー2
ノードタイプ10
作成者
Jay Emp0
@jay-emp0AI and Automation developer. Im implementing n8n and ai tools to automate marketing and sales in companies
外部リンク
n8n.ioで表示 →
このワークフローを共有