UNPKG

n8n-nodes-piapi

Version:

Community n8n nodes for PiAPI - integrate generative AI capabilities (image, video, audio, 3D) into your workflows

425 lines 17.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KlingImageToVideo = void 0; const GenericFunctions_1 = require("../shared/GenericFunctions"); class KlingImageToVideo { constructor() { this.description = { displayName: 'PiAPI Kling Image to Video', name: 'klingImageToVideo', icon: 'file:../piapi.svg', group: ['transform'], version: 1, description: 'Generate videos from images using PiAPI Kling', defaults: { name: 'Kling Image to Video', }, inputs: ["main"], outputs: ["main"], credentials: [ { name: 'piAPIApi', required: true, }, ], properties: [ { displayName: 'Image Source', name: 'imageSource', type: 'options', options: [ { name: 'URL', value: 'url', description: 'Load image from URL', }, { name: 'Binary Data', value: 'binaryData', description: 'Use image from binary field', }, ], default: 'url', description: 'Where to get the image from', }, { displayName: 'Image URL', name: 'imageUrl', type: 'string', default: '', required: true, displayOptions: { show: { imageSource: ['url'], }, }, description: 'URL of the image to transform into a video', }, { displayName: 'Binary Property', name: 'binaryPropertyName', type: 'string', default: 'data', required: true, displayOptions: { show: { imageSource: ['binaryData'], }, }, description: 'Name of the binary property containing the image', }, { displayName: 'End Frame Image Source', name: 'endFrameImageSource', type: 'options', options: [ { name: 'None', value: 'none', description: 'Do not use an end frame image', }, { name: 'URL', value: 'url', description: 'Load end frame image from URL', }, { name: 'Binary Data', value: 'binaryData', description: 'Use end frame image from binary field', }, ], default: 'none', description: 'Whether to use an end frame image', }, { displayName: 'End Frame Image URL', name: 'endFrameImageUrl', type: 'string', default: '', required: true, displayOptions: { show: { endFrameImageSource: ['url'], }, }, description: 'URL of the end frame image', }, { displayName: 'End Frame Binary Property', name: 'endFrameBinaryPropertyName', type: 'string', default: 'endFrame', required: true, displayOptions: { show: { endFrameImageSource: ['binaryData'], }, }, description: 'Name of the binary property containing the end frame image', }, { displayName: 'Prompt', name: 'prompt', type: 'string', typeOptions: { rows: 4, }, default: '', required: false, description: 'Text prompt to guide the video generation', }, { displayName: 'Negative Prompt', name: 'negativePrompt', type: 'string', typeOptions: { rows: 4, }, default: '', description: 'Negative prompt to avoid certain elements in the video', }, { displayName: 'Use Elements', name: 'useElements', type: 'boolean', default: false, description: 'Whether to use elements feature (V1.6 only)', }, { displayName: 'Elements', name: 'elements', type: 'fixedCollection', typeOptions: { multipleValues: true, sortable: true, }, default: {}, displayOptions: { show: { useElements: [true], }, }, options: [ { name: 'elementsList', displayName: 'Element', values: [ { displayName: 'Element Image URL', name: 'elementImageUrl', type: 'string', default: '', description: 'URL of the element image', }, ], }, ], description: 'Elements to include in the video (1-4 images)', }, { displayName: 'Duration', name: 'duration', type: 'options', options: [ { name: '5 Seconds', value: 5, }, { name: '10 Seconds', value: 10, }, ], default: 5, description: 'Duration of the generated video', }, { displayName: 'Aspect Ratio', name: 'aspectRatio', type: 'options', options: [ { name: 'Landscape (16:9)', value: '16:9', }, { name: 'Portrait (9:16)', value: '9:16', }, { name: 'Square (1:1)', value: '1:1', }, ], default: '16:9', description: 'Aspect ratio of the generated video', }, { displayName: 'Mode', name: 'mode', type: 'options', options: [ { name: 'Standard', value: 'std', }, { name: 'Professional', value: 'pro', }, ], default: 'std', description: 'Generation mode of the video', }, { displayName: 'Version', name: 'version', type: 'options', options: [ { name: 'V1.0', value: '1.0', }, { name: 'V1.5', value: '1.5', }, { name: 'V1.6', value: '1.6', }, { name: 'V2.0 ($0.96 for 5s, $1.92 for 10s)', value: '2.0', description: 'Warning: Higher price', }, { name: 'V2.1', value: '2.1', }, { name: 'V2.1 Master', value: '2.1-master', description: 'Warning: Higher price', }, ], default: '1.6', description: 'Model version to use', }, { displayName: 'CFG Scale', name: 'cfgScale', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2, }, default: 0.5, description: 'How strongly the video adheres to the prompt (between 0-1, recommended: 0.5)', }, { displayName: 'Wait for Completion', name: 'waitForCompletion', type: 'boolean', default: false, description: 'Whether to wait for the task to complete before returning', }, ], }; } async execute() { var _a, _b; const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const imageSource = this.getNodeParameter('imageSource', i); const endFrameImageSource = this.getNodeParameter('endFrameImageSource', i); const prompt = this.getNodeParameter('prompt', i, ''); const negativePrompt = this.getNodeParameter('negativePrompt', i, ''); const duration = this.getNodeParameter('duration', i); const aspectRatio = this.getNodeParameter('aspectRatio', i); const mode = this.getNodeParameter('mode', i); const version = this.getNodeParameter('version', i); const cfgScale = this.getNodeParameter('cfgScale', i); const useElements = this.getNodeParameter('useElements', i, false); const waitForCompletion = this.getNodeParameter('waitForCompletion', i, false); let imageUrl = ''; let endFrameImageUrl = ''; let elements = []; if (imageSource === 'url') { imageUrl = this.getNodeParameter('imageUrl', i); try { new URL(imageUrl); } catch (error) { throw new Error(`Invalid image URL: ${error.message}`); } } else if (imageSource === 'binaryData') { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const binaryItem = (_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[binaryPropertyName]; if (!binaryItem) { throw new Error(`No binary data found in property ${binaryPropertyName}`); } const binaryData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); if (!binaryData) { throw new Error(`No binary data found in property ${binaryPropertyName}`); } const binaryMimeType = binaryItem.mimeType || 'image/png'; imageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`; } if (endFrameImageSource === 'url') { endFrameImageUrl = this.getNodeParameter('endFrameImageUrl', i); try { new URL(endFrameImageUrl); } catch (error) { throw new Error(`Invalid end frame image URL: ${error.message}`); } } else if (endFrameImageSource === 'binaryData') { const endFrameBinaryPropertyName = this.getNodeParameter('endFrameBinaryPropertyName', i); const binaryItem = (_b = items[i].binary) === null || _b === void 0 ? void 0 : _b[endFrameBinaryPropertyName]; if (!binaryItem) { throw new Error(`No binary data found in property ${endFrameBinaryPropertyName}`); } const binaryData = await this.helpers.getBinaryDataBuffer(i, endFrameBinaryPropertyName); if (!binaryData) { throw new Error(`No binary data found in property ${endFrameBinaryPropertyName}`); } const binaryMimeType = binaryItem.mimeType || 'image/png'; endFrameImageUrl = `data:${binaryMimeType};base64,${binaryData.toString('base64')}`; } if (useElements) { const elementsList = this.getNodeParameter('elements.elementsList', i, []); if (elementsList.length === 0) { throw new Error('Elements feature requires at least one element image'); } else if (elementsList.length > 4) { throw new Error('Elements feature supports a maximum of 4 element images'); } elements = elementsList.map(element => ({ image_url: element.elementImageUrl, })); } const body = { model: 'kling', task_type: 'video_generation', input: { prompt, negative_prompt: negativePrompt, duration, aspect_ratio: aspectRatio, mode, version, cfg_scale: cfgScale, }, config: { webhook_config: { endpoint: '', secret: '', }, }, }; if (!useElements) { body.input.image_url = imageUrl; if (endFrameImageSource !== 'none' && endFrameImageUrl) { body.input.image_tail_url = endFrameImageUrl; } } else { body.input.elements = elements; } const response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', body); if (response.code !== 200) { throw new Error(`API Error: ${response.message}`); } const taskId = response.data.task_id; let taskData = response.data; if (waitForCompletion) { taskData = await GenericFunctions_1.waitForTaskCompletion.call(this, taskId); } returnData.push({ json: taskData, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message, }, }); continue; } throw error; } } return [returnData]; } } exports.KlingImageToVideo = KlingImageToVideo; //# sourceMappingURL=KlingImageToVideo.node.js.map