电子书转有声书
高级
这是一个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": "电子书",
"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": "## 电子书提取模块"
},
"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": "## 电子书转有声书转换模块"
},
"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": "## 音频合并模块"
},
"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": "## 将电子书上传至云端硬盘"
},
"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 文本转语音",
"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": "# 观看 [YouTube 演示视频](https://img.youtube.com/vi/xKqkjXIPZoM/0.jpg)"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "d82d1c3b-0657-4fc5-8691-40ef2fe01121",
"connections": {
"FORM": {
"main": [
[
{
"node": "EXTRACT TEXT",
"type": "main",
"index": 0
}
]
]
},
"MINIMAX TTS": {
"main": [
[
{
"node": "WAITS FOR 5 SECONDS",
"type": "main",
"index": 0
}
]
]
},
"EXTRACT TEXT": {
"main": [
[
{
"node": "SPLITS THE TEXT ACCORGING TO RULES",
"type": "main",
"index": 0
}
]
]
},
"Save concat_list": {
"main": [
[
{
"node": "Join audio chucks and delete all files",
"type": "main",
"index": 0
}
]
]
},
"Save Audio Chucks": {
"main": [
[
{
"node": "Generate `concat_list.txt`",
"type": "main",
"index": 0
}
]
]
},
"read final_merged": {
"main": [
[
{
"node": "Uploads Ebook",
"type": "main",
"index": 0
}
]
]
},
"WAITS FOR 5 SECONDS": {
"main": [
[
{
"node": "Loop Over Text chunks (5) at a time",
"type": "main",
"index": 0
}
]
]
},
"Generate `concat_list.txt`": {
"main": [
[
{
"node": "Save concat_list",
"type": "main",
"index": 0
}
]
]
},
"CONVERTS URL TO AUDIO FILES": {
"main": [
[
{
"node": "GIVES INDEXES TO AUDIO FILES",
"type": "main",
"index": 0
}
]
]
},
"GIVES INDEXES TO AUDIO FILES": {
"main": [
[
{
"node": "Save Audio Chucks",
"type": "main",
"index": 0
}
]
]
},
"SPLITS THE TEXT ACCORGING TO RULES": {
"main": [
[
{
"node": "Loop Over Text chunks (5) at a time",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Text chunks (5) at a time": {
"main": [
[
{
"node": "CONVERTS URL TO AUDIO FILES",
"type": "main",
"index": 0
}
],
[
{
"node": "MINIMAX TTS",
"type": "main",
"index": 0
}
]
]
},
"Join audio chucks and delete all files": {
"main": [
[
{
"node": "read final_merged",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
自动化视频生成器
使用 DeepSeek、TTS 和 Together.ai 从脚本生成 AI 视频
Set
Code
Wait
+15
81 节点Lakindu Siriwardana
内容创作
使用Replicate和OpenAI制作无面孔恐怖短片
通过OpenAI TTS、Replicate视频生成和YouTube上传制作无面孔恐怖短片
If
Code
Wait
+13
50 节点Deb Mukherjee
内容创作
Recap AI - Veo 3.1 电商产品动画生成器
基于Veo 3.1的电商产品目录AI视频生成器
If
Set
Wait
+10
18 节点Lucas Walter
内容创作
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
内容创作
使用 OpenAI、ElevenLabs 和 Fal.ai 自动化病毒式内容创作,适用于视频、播客和 ASMR
使用 OpenAI、ElevenLabs 和 Fal.ai 自动化病毒式内容创作,适用于视频、播客和 ASMR
Set
Code
Wait
+16
97 节点Adam Crafts
内容创作
使用 Creatomate 生成短视频
使用 Creatomate、ElevenLabs 和 Pexels 素材库生成 AI 短视频
If
Code
Wait
+9
31 节点Matty Reed
内容创作
工作流信息
难度等级
高级
节点数量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 查看 →
分享此工作流