Clonage de voix par conversion texte-parole via l'API Zonos (stockage local)
Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 18 nœuds.Utilise principalement des nœuds comme If, Set, Code, Webhook, HttpRequest. Cloner une voix de texte en parole avec l'API Zyphra Zonos
- •Point de terminaison HTTP Webhook (généré automatiquement par n8n)
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
Nœuds utilisés (18)
Catégorie
{
"id": "hqMRsze38RaTmgQh",
"meta": {
"instanceId": "f21406c1aebdcd02925535f333c258bfa61f9b4107a822ced8462b5dd631899b",
"templateCredsSetupCompleted": true
},
"name": "Text to speech Voice clone using Zonos via API(local storage)",
"tags": [],
"nodes": [
{
"id": "76f2c278-c769-443f-8aa5-541713323b51",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
-560,
60
],
"webhookId": "zyphra-voice-clone",
"parameters": {
"path": "voice-clone",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 1
},
{
"id": "0772d98e-7cd8-487d-a3db-26c3d6d50304",
"name": "Définir les paramètres de clonage",
"type": "n8n-nodes-base.set",
"position": [
-340,
60
],
"parameters": {
"values": {
"number": [
{
"name": "happiness",
"value": "={{ $json.body.emotion.happiness || 0.6}}"
},
{
"name": "neutral",
"value": "={{ $json.body.emotion.neutral || 0.6}}"
},
{
"name": "sadness",
"value": "={{ $json.body.emotion.sadness || 0.05}}"
},
{
"name": "disgust",
"value": "={{ $json.body.emotion.disgust || 0.05}}"
},
{
"name": "fear",
"value": "={{ $json.body.emotion.fear || 0.05}}"
},
{
"name": "surprise",
"value": "={{ $json.body.emotion.surprise || 0.05}}"
},
{
"name": "anger",
"value": "={{ $json.body.emotion.anger || 0.05}}"
},
{
"name": "other",
"value": "={{ $json.body.emotion.other || 0.5}}"
}
],
"string": [
{
"name": "text",
"value": "={{ $json.body.text || 'Hello, this is a test of voice cloning!' }}"
},
{
"name": "speaking_rate",
"value": "={{ $json.body.speaking_rate || 15 }}"
},
{
"name": "language_iso_code",
"value": "={{ $json.body.language_iso_code || 'en-us' }}"
},
{
"name": "mime_type",
"value": "={{ $json.body.mime_type || 'audio/wav'}}"
},
{
"name": "sample_voice_path",
"value": "={{ $json.body.sample_voice_path }}"
},
{
"name": "model",
"value": "={{ $json.body.model || 'zonos-v0.1-transformer' }}"
},
{
"name": "output_path",
"value": "={{ $json.body.output_path }}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"id": "b3dc1528-90d7-4397-83e6-18c5f2dbf495",
"name": "Lire l'échantillon vocal",
"type": "n8n-nodes-base.readWriteFile",
"onError": "continueErrorOutput",
"position": [
40,
60
],
"parameters": {
"options": {
"mimeType": "={{ $json.mime_type }}",
"dataPropertyName": ""
},
"fileSelector": "={{ $json.sample_voice_path }}"
},
"typeVersion": 1
},
{
"id": "86e0f9bf-ccec-4bb1-b9ce-7d1b94fdfcca",
"name": "Vérifier le chargement du fichier",
"type": "n8n-nodes-base.if",
"position": [
560,
-80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "file-exists-check",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $ifEmpty($binary.data, false) !== false }}\n",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "2980ae94-30e3-4065-8d2c-b607c73c3c5f",
"name": "Appeler Zyphra Clone API",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
980,
-120
],
"parameters": {
"url": "http://api.zyphra.com/v1/audio/text-to-speech",
"method": "POST",
"options": {
"response": {
"response": {}
}
},
"jsonBody": "={\n \"text\": \"{{ $('Set Clone Parameters').item.json.text }}\",\n \"speaking_rate\": {{ parseFloat($('Set Clone Parameters').item.json.speaking_rate) }},\n \"language_iso_code\": \"{{ $('Set Clone Parameters').item.json.language_iso_code }}\",\n \"mime_type\": \"{{ $('Set Clone Parameters').item.json.mime_type }}\",\n \"model\": \"{{ $('Set Clone Parameters').item.json.model }}\",\n \"emotion\": {\n \"happiness\": {{ $('Set Clone Parameters').item.json.happiness }},\n \"neutral\": {{ $('Set Clone Parameters').item.json.neutral }},\n \"sadness\": {{ $('Set Clone Parameters').item.json.sadness }},\n \"disgust\": {{ $('Set Clone Parameters').item.json.disgust }},\n \"fear\": {{ $('Set Clone Parameters').item.json.fear }},\n \"surprise\": {{ $('Set Clone Parameters').item.json.surprise }},\n \"anger\": {{ $('Set Clone Parameters').item.json.anger }},\n \"other\": {{ $('Set Clone Parameters').item.json.other }}\n },\n \"speaker_audio\": \"{{ $json.base64_content }}\"\n}\n",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "put-your-API-key-here"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "0f896518-98ce-4176-8977-1f0380b54469",
"name": "Sauvegarder l'audio cloné",
"type": "n8n-nodes-base.readWriteFile",
"position": [
1440,
0
],
"parameters": {
"options": {},
"fileName": "={{ $('Set Clone Parameters').item.json.output_path }}{{ 'cloned_voice_' + new Date().getTime() + '.webm' }}",
"operation": "write"
},
"typeVersion": 1
},
{
"id": "02f1b766-953a-4834-8d93-4cc596ffe77c",
"name": "Réponse de succès",
"type": "n8n-nodes-base.set",
"position": [
1660,
0
],
"parameters": {
"values": {
"string": [
{
"name": "success",
"value": "true"
},
{
"name": "message",
"value": "Voice cloning completed successfully!"
},
{
"name": "filename",
"value": "={{ $json.fileName }}"
},
{
"name": "text_processed",
"value": "={{ $('Set Clone Parameters').item.json.text }}"
},
{
"name": "sample_voice_used",
"value": "={{ $('Set Clone Parameters').item.json.sample_voice_path }}"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "7da98d65-08e3-4d6e-9957-ead2c8f1133f",
"name": "Réponse d'erreur de fichier",
"type": "n8n-nodes-base.set",
"position": [
860,
480
],
"parameters": {
"values": {
"string": [
{
"name": "success",
"value": "false"
},
{
"name": "error_type",
"value": "file_not_found"
},
{
"name": "message",
"value": "Sample voice file could not be read from: {{ $('Set Clone Parameters').item.json.sample_voice_path }}"
},
{
"name": "suggestion",
"value": "Please check the file path and ensure the file exists"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "44006f98-4241-436d-b8cf-1c586271a35a",
"name": "API Error Response",
"type": "n8n-nodes-base.set",
"position": [
1100,
480
],
"parameters": {
"values": {
"string": [
{
"name": "success",
"value": "false"
},
{
"name": "error_type",
"value": "api_error"
},
{
"name": "message",
"value": "Voice cloning API request failed"
},
{
"name": "error_details",
"value": "={{ $json.error ? $json.error.message : 'Unknown API error' }}"
},
{
"name": "suggestion",
"value": "Please check your API key and try again"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "e2c14808-e209-4daf-93dd-9c7049261e60",
"name": "Webhook Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1880,
100
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ $json }}"
},
"typeVersion": 1
},
{
"id": "8268fd4a-fd84-4462-9ad1-9af8152d0cf3",
"name": "Note autocollante",
"type": "n8n-nodes-base.stickyNote",
"position": [
-960,
-1200
],
"parameters": {
"color": 4,
"width": 780,
"height": 340,
"content": "🎙️ VOICE CLONING WORKFLOW - ZONOS API\n═══════════════════════════════════════\nThis workflow clones voices using Zyphra's Zonos API\n📋 Input: Text + sample voice file + parameters \n🎵 Output: Generated audio file with cloned voice\n⚡ Trigger: Webhook POST to /voice-clone endpoint\n\nBasic setup and use:\nConfigure your Zyphra API key in the \"Call Zyphra Clone API\" node under Header parameters → X-API-Key header parameter\n\nEnsure your sample voice files are accessible at the paths you'll specify\n\nTest the webhook endpoint is accessible\n\nSend valid POST request to your webhook\n"
},
"typeVersion": 1
},
{
"id": "cdbb775f-8408-43a9-89b1-1039315c6678",
"name": "Convertisseur Base64",
"type": "n8n-nodes-base.code",
"position": [
400,
-80
],
"parameters": {
"jsCode": "// Get binary data from previous node\nconst binaryData = $input.first().binary?.data;\n\nif (!binaryData) {\n throw new Error(\"No binary data found\");\n}\n\n// Binary data in n8n is already base64 encoded\nconst base64String = binaryData.data;\n\nreturn {\n json: {\n base64_content: base64String,\n // Add other fields as needed\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "88b0131c-f93b-4593-9c88-ed4f91b74c88",
"name": "Note autocollante 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-960,
-740
],
"parameters": {
"color": 6,
"width": 780,
"height": 1020,
"content": "📥 REQUIRED WEBHOOK PARAMETERS\n══════════════════════════════\n✅ text: Text to synthesize\n✅ sample_voice_path: Path to your voice sample file \n✅ output_path: Where to save generated audio\n\n🔧 OPTIONAL PARAMETERS (with defaults):\n• speaking_rate: 15 (speech speed)\n• language_iso_code: \"en-us\" \n• mime_type: \"audio/wav\"\n• model: \"zonos-v0.1-transformer\"\n• emotion: Various emotion levels (0-1 scale)\n"
},
"typeVersion": 1
},
{
"id": "3be24130-054d-4435-9aac-d5ad9c7b92d0",
"name": "Note autocollante 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
820,
-380
],
"parameters": {
"color": 6,
"width": 480,
"height": 460,
"content": "🔐 API KEY CONFIGURATION REQUIRED!\n═══════════════════════════════════\n1️⃣ Register account at: playground.zyphra.com \n2️⃣ Get API key from: playground.zyphra.com/settings/api-keys\n3️⃣ Add key to \"Call Zyphra Clone API\" node\n → Header parameters section\n → Header: X-API-Key\n → Value: [Your API Key]\n\n❌ Workflow will fail without proper API key setup!\n"
},
"typeVersion": 1
},
{
"id": "08780e5a-4663-4a0d-aeff-69f4059495ce",
"name": "Note autocollante 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
-280
],
"parameters": {
"color": 6,
"width": 740,
"height": 560,
"content": "📁 FILE HANDLING PROCESS\n════════════════════════\n1. Read sample voice from specified path\n2. Convert audio file to base64 format\n3. Validate file loaded successfully \n\n⚠️ IMPORTANT: Ensure sample voice file exists \n at the path specified in sample_voice_path!\n"
},
"typeVersion": 1
},
{
"id": "223743b2-aeb2-45cc-8094-9bef48fc815e",
"name": "Note autocollante 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
820,
180
],
"parameters": {
"color": 6,
"width": 480,
"height": 480,
"content": "🚨 ERROR HANDLING & RESPONSES\n═════════════════════════════\n✅ SUCCESS: Returns success message + filename\n❌ FILE_NOT_FOUND: Sample voice file missing/unreadable\n❌ API_ERROR: Zyphra API request failed\n❌ AUTH_ERROR: Invalid or missing API key\n\nAll errors return JSON with error details and suggestions\n"
},
"typeVersion": 1
},
{
"id": "939714c2-9feb-4ccb-b3b6-fd133c65c56a",
"name": "Note autocollante 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1400,
-220
],
"parameters": {
"color": 6,
"width": 660,
"height": 540,
"content": "🎵 OUTPUT DETAILS\n═════════════════\n📍 Location: [output_path]/cloned_voice_[timestamp].webm\n📊 Format: Specified by mime_type parameter\n🕐 Filename: Auto-generated with timestamp\n📝 Response: JSON with success status and file details\n\nGenerated audio ready for download!\n"
},
"typeVersion": 1
},
{
"id": "0a90485e-417a-415e-a9a4-f128aea6b9f1",
"name": "Note autocollante 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-940,
-440
],
"parameters": {
"color": 5,
"width": 700,
"height": 440,
"content": "POST http://localhost:5678/webhook-test/voice-clone\nContent-Type: application/json\n\n{\n \"text\": \"Hello there, kupo! This voice sounds just like the sample!\",\n \"speaking_rate\": 18,\n \"sample_voice_path\": \"/data/output/sampleVoice.wav\",\n \"output_path\": \"/data/output/\",\n \"language_iso_code\": \"en-us\",\n \"mime_type\": \"audio/wav\",\n \"model\": \"zonos-v0.1-transformer\",\n \"emotion\": {\n \"happiness\": 0.8,\n \"neutral\": 0.3,\n \"sadness\": 0.05,\n \"disgust\": 0.05,\n \"fear\": 0.05,\n \"surprise\": 0.05,\n \"anger\": 0.05,\n \"other\": 0.5\n }\n}\n"
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "c4a644b3-3029-47ed-9dad-6396d22a9841",
"connections": {
"76f2c278-c769-443f-8aa5-541713323b51": {
"main": [
[
{
"node": "0772d98e-7cd8-487d-a3db-26c3d6d50304",
"type": "main",
"index": 0
}
]
]
},
"cdbb775f-8408-43a9-89b1-1039315c6678": {
"main": [
[
{
"node": "86e0f9bf-ccec-4bb1-b9ce-7d1b94fdfcca",
"type": "main",
"index": 0
}
]
]
},
"02f1b766-953a-4834-8d93-4cc596ffe77c": {
"main": [
[
{
"node": "e2c14808-e209-4daf-93dd-9c7049261e60",
"type": "main",
"index": 0
}
]
]
},
"86e0f9bf-ccec-4bb1-b9ce-7d1b94fdfcca": {
"main": [
[
{
"node": "2980ae94-30e3-4065-8d2c-b607c73c3c5f",
"type": "main",
"index": 0
}
],
[
{
"node": "7da98d65-08e3-4d6e-9957-ead2c8f1133f",
"type": "main",
"index": 0
}
]
]
},
"b3dc1528-90d7-4397-83e6-18c5f2dbf495": {
"main": [
[
{
"node": "cdbb775f-8408-43a9-89b1-1039315c6678",
"type": "main",
"index": 0
}
],
[
{
"node": "7da98d65-08e3-4d6e-9957-ead2c8f1133f",
"type": "main",
"index": 0
}
]
]
},
"0f896518-98ce-4176-8977-1f0380b54469": {
"main": [
[
{
"node": "02f1b766-953a-4834-8d93-4cc596ffe77c",
"type": "main",
"index": 0
}
]
]
},
"44006f98-4241-436d-b8cf-1c586271a35a": {
"main": [
[
{
"node": "e2c14808-e209-4daf-93dd-9c7049261e60",
"type": "main",
"index": 0
}
]
]
},
"7da98d65-08e3-4d6e-9957-ead2c8f1133f": {
"main": [
[
{
"node": "e2c14808-e209-4daf-93dd-9c7049261e60",
"type": "main",
"index": 0
}
]
]
},
"0772d98e-7cd8-487d-a3db-26c3d6d50304": {
"main": [
[
{
"node": "b3dc1528-90d7-4397-83e6-18c5f2dbf495",
"type": "main",
"index": 0
}
]
]
},
"2980ae94-30e3-4065-8d2c-b607c73c3c5f": {
"main": [
[
{
"node": "0f896518-98ce-4176-8977-1f0380b54469",
"type": "main",
"index": 0
}
],
[
{
"node": "44006f98-4241-436d-b8cf-1c586271a35a",
"type": "main",
"index": 0
}
]
]
}
}
}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.
Workflows recommandés
Tiartyos
@tiartyos🎮 Gaming // 💻 Coding // 🎨 Creating Pro-AI 🤖 | Open Source 🌟 | 🧟♂️ Horror junkie | 🍜 Anime lover Turning caffeine into questionable code since 2017 ☕
Partager ce workflow