UNPKG

@thaleslaray/n8n-nodes-elevenlabs

Version:

Nó n8n para integração com a API da ElevenLabs incluindo Speech-to-Text, Text-to-Speech e Conversational AI

309 lines (308 loc) 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ElevenLabsSpeechToSpeech = void 0; const n8n_workflow_1 = require("n8n-workflow"); const utils_1 = require("../../utils"); class ElevenLabsSpeechToSpeech { constructor() { this.description = { displayName: 'ElevenLabs Speech to Speech', name: 'elevenLabsSpeechToSpeech', icon: 'file:../../elevenlabs.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"]}}', description: 'Converte áudio de uma voz para outra usando a API da ElevenLabs', defaults: { name: 'ElevenLabs Speech to Speech', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'elevenLabsApi', required: true, }, ], properties: [ { displayName: 'Operação', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Converter Voz', value: 'convertSpeech', description: 'Converter áudio de uma voz para outra', action: 'Convert speech from one voice to another', }, ], default: 'convertSpeech', }, { displayName: 'Fonte do Áudio', name: 'audioSource', type: 'options', options: [ { name: 'Arquivo Binário', value: 'binaryFile', }, { name: 'URL', value: 'url', }, ], default: 'binaryFile', description: 'Fonte do arquivo de áudio para processamento', }, { displayName: 'Campo Binário', name: 'binaryPropertyName', type: 'string', default: 'data', required: true, displayOptions: { show: { audioSource: ['binaryFile'], }, }, description: 'Nome do campo binário que contém o arquivo de áudio', }, { displayName: 'URL do Áudio', name: 'audioUrl', type: 'string', default: '', required: true, displayOptions: { show: { audioSource: ['url'], }, }, description: 'URL do arquivo de áudio para processamento', }, { displayName: 'ID da Voz', name: 'voiceId', type: 'string', default: '', required: true, description: 'ID da voz para a qual o áudio será convertido', }, { displayName: 'Nome do Campo Binário de Saída', name: 'outputBinaryPropertyName', type: 'string', default: 'data', required: true, description: 'Nome do campo binário onde o áudio processado será armazenado', }, { displayName: 'Opções Avançadas', name: 'advancedOptions', type: 'collection', placeholder: 'Adicionar Opção', default: {}, options: [ { displayName: 'Aumento de Similaridade', name: 'similarityBoost', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2, }, default: 0.75, description: 'Quanto maior o valor, mais a voz resultante se parecerá com a voz original (0-1)', }, { displayName: 'Estabilidade', name: 'stability', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2, }, default: 0.5, description: 'Quanto maior o valor, mais estável e menos variável será a voz (0-1)', }, { displayName: 'Formato de Saída', name: 'outputFormat', type: 'options', options: [ { name: 'MP3', value: 'mp3_44100_128', }, { name: 'FLAC', value: 'flac', }, { name: 'WAV', value: 'pcm_16000', }, { name: 'PCM 16-bit 22.05kHz', value: 'pcm_22050', }, { name: 'PCM 16-bit 24kHz', value: 'pcm_24000', }, { name: 'PCM 16-bit 44.1kHz', value: 'pcm_44100', }, ], default: 'mp3_44100_128', description: 'Formato do arquivo de áudio gerado', }, { displayName: 'Idioma de Origem', name: 'sourceLanguage', type: 'options', options: [ { name: 'Automático', value: 'auto' }, { name: 'Inglês', value: 'en' }, { name: 'Espanhol', value: 'es' }, { name: 'Português', value: 'pt' }, { name: 'Francês', value: 'fr' }, { name: 'Alemão', value: 'de' }, { name: 'Italiano', value: 'it' }, { name: 'Holandês', value: 'nl' }, { name: 'Japonês', value: 'ja' }, { name: 'Coreano', value: 'ko' }, { name: 'Chinês', value: 'zh' }, { name: 'Russo', value: 'ru' }, { name: 'Turco', value: 'tr' }, { name: 'Polonês', value: 'pl' }, { name: 'Árabe', value: 'ar' }, ], default: 'auto', description: 'Idioma do áudio de entrada', }, { displayName: 'Idioma de Destino', name: 'targetLanguage', type: 'options', options: [ { name: 'Mesmo do Idioma de Origem', value: 'same' }, { name: 'Inglês', value: 'en' }, { name: 'Espanhol', value: 'es' }, { name: 'Português', value: 'pt' }, { name: 'Francês', value: 'fr' }, { name: 'Alemão', value: 'de' }, { name: 'Italiano', value: 'it' }, { name: 'Holandês', value: 'nl' }, { name: 'Japonês', value: 'ja' }, { name: 'Coreano', value: 'ko' }, { name: 'Chinês', value: 'zh' }, { name: 'Russo', value: 'ru' }, { name: 'Turco', value: 'tr' }, { name: 'Polonês', value: 'pl' }, { name: 'Árabe', value: 'ar' }, ], default: 'same', description: 'Idioma no qual o áudio será gerado', }, ], }, ], }; } async execute() { var _a; const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const audioSource = this.getNodeParameter('audioSource', i); const voiceId = this.getNodeParameter('voiceId', i); const outputBinaryPropertyName = this.getNodeParameter('outputBinaryPropertyName', i); const advancedOptions = this.getNodeParameter('advancedOptions', i); const formData = { voice_id: voiceId, }; if (advancedOptions.similarityBoost !== undefined) { formData.similarity_boost = advancedOptions.similarityBoost; } if (advancedOptions.stability !== undefined) { formData.stability = advancedOptions.stability; } if (advancedOptions.outputFormat !== undefined) { formData.output_format = advancedOptions.outputFormat; } if (advancedOptions.sourceLanguage !== undefined && advancedOptions.sourceLanguage !== 'auto') { formData.source_language = advancedOptions.sourceLanguage; } if (advancedOptions.targetLanguage !== undefined && advancedOptions.targetLanguage !== 'same') { formData.target_language = advancedOptions.targetLanguage; } const options = await utils_1.createBaseOptions.call(this, 'speech-to-speech', 'POST', undefined, formData); options.json = false; options.encoding = null; options.headers['Accept'] = '*/*'; if (audioSource === 'binaryFile') { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const binaryData = (_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[binaryPropertyName]; if (!binaryData) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Nenhum dado binário encontrado'); } const buffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); options.formData.audio = { value: buffer, options: { filename: binaryData.fileName || 'audio.mp3', contentType: binaryData.mimeType, }, }; } else { const audioUrl = this.getNodeParameter('audioUrl', i); options.formData.audio_url = audioUrl; } const response = await this.helpers.request(options); let mimeType = 'audio/mpeg'; let fileExtension = 'mp3'; if (advancedOptions.outputFormat) { if (advancedOptions.outputFormat === 'flac') { mimeType = 'audio/flac'; fileExtension = 'flac'; } else if (advancedOptions.outputFormat.startsWith('pcm_')) { mimeType = 'audio/wav'; fileExtension = 'wav'; } } const filename = `speech_to_speech_${Date.now()}.${fileExtension}`; const newItem = { json: { success: true, voiceId, ...advancedOptions, }, binary: {}, pairedItem: { item: i }, }; newItem.binary[outputBinaryPropertyName] = await this.helpers.prepareBinaryData(response, filename, mimeType); returnData.push(newItem); } catch (error) { const errorResult = utils_1.handleApiError.call(this, error, i); if (errorResult) { returnData.push(errorResult); continue; } throw error; } } return [returnData]; } } exports.ElevenLabsSpeechToSpeech = ElevenLabsSpeechToSpeech;