n8n-nodes-comfyui-image-to-image
Version:
n8n nodes to integrate with ComfyUI for image transformations, dual image processing, image+video processing, and text-to-video generation using stable diffusion workflows
175 lines • 8.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComfyuiTextToVideo = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class ComfyuiTextToVideo {
constructor() {
this.description = {
displayName: 'ComfyUI Text To Video',
name: 'comfyuiTextToVideo',
icon: 'file:comfyui.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["textPrompt"]}}',
description: 'Generate video from text prompt using ComfyUI',
defaults: {
name: 'ComfyUI Text To Video',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'comfyUIApi',
required: true,
},
],
properties: [
{
displayName: 'Workflow JSON',
name: 'workflow',
type: 'string',
typeOptions: {
rows: 10,
},
default: '',
required: true,
description: 'The ComfyUI workflow in JSON format',
},
{
displayName: 'Timeout',
name: 'timeout',
type: 'number',
default: 30,
description: 'Maximum time in minutes to wait for video generation',
},
],
};
}
async execute() {
var _a;
const credentials = await this.getCredentials('comfyUIApi');
const workflow = this.getNodeParameter('workflow', 0);
const timeout = this.getNodeParameter('timeout', 0);
const apiUrl = credentials.apiUrl;
const apiKey = credentials.apiKey;
console.log('[ComfyUI Text-to-Video] Executing video generation with API URL:', apiUrl);
const headers = {
'Content-Type': 'application/json',
};
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`;
}
try {
let workflowData;
try {
workflowData = JSON.parse(workflow);
}
catch (error) {
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: 'Invalid workflow JSON. Please check the JSON syntax and try again.',
description: error.message
});
}
if (typeof workflowData !== 'object' || workflowData === null) {
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: 'Invalid workflow structure. The workflow must be a valid JSON object.'
});
}
console.log('[ComfyUI Text-to-Video] Using provided workflow as-is');
console.log('[ComfyUI Text-to-Video] Queueing video generation...');
const response = await this.helpers.request({
method: 'POST',
url: `${apiUrl}/prompt`,
headers,
body: {
prompt: workflowData,
},
json: true,
});
if (!response.prompt_id) {
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Failed to get prompt ID from ComfyUI' });
}
const promptId = response.prompt_id;
console.log('[ComfyUI Text-to-Video] Video generation queued with prompt ID:', promptId);
const startTime = Date.now();
const timeoutMs = timeout * 60 * 1000;
while (Date.now() - startTime < timeoutMs) {
await new Promise(resolve => setTimeout(resolve, 2000));
try {
const statusResponse = await this.helpers.request({
method: 'GET',
url: `${apiUrl}/history/${promptId}`,
headers,
json: true,
});
if (statusResponse[promptId] && statusResponse[promptId].status) {
const status = statusResponse[promptId].status;
console.log('[ComfyUI Text-to-Video] Status:', status.status_str);
if (status.status_str === 'success') {
const outputs = status.outputs;
let videoData = null;
for (const nodeId in outputs) {
const output = outputs[nodeId];
if (output.videos && output.videos.length > 0) {
videoData = output.videos[0];
break;
}
}
if (!videoData) {
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: 'Video generation completed but no video output found'
});
}
console.log('[ComfyUI Text-to-Video] Video generation completed successfully');
console.log('[ComfyUI Text-to-Video] Video filename:', videoData.filename);
const videoResponse = await this.helpers.request({
method: 'GET',
url: `${apiUrl}/view?filename=${videoData.filename}`,
headers,
});
return [[{
json: {
prompt_id: promptId,
filename: videoData.filename,
status: 'success'
},
binary: {
video: {
data: Buffer.from(videoResponse).toString('base64'),
mimeType: 'video/mp4',
fileName: videoData.filename,
},
},
}]];
}
else if (status.status_str === 'error') {
const errorMessage = ((_a = status.error) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error occurred during video generation';
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: `Video generation failed: ${errorMessage}`
});
}
}
}
catch (error) {
if (error.message.includes('Video generation failed')) {
throw error;
}
console.log('[ComfyUI Text-to-Video] Polling error (will retry):', error.message);
}
}
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: `Video generation timed out after ${timeout} minutes`
});
}
catch (error) {
if (error instanceof n8n_workflow_1.NodeApiError) {
throw error;
}
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
message: `ComfyUI Text-to-Video error: ${error.message}`
});
}
}
}
exports.ComfyuiTextToVideo = ComfyuiTextToVideo;
//# sourceMappingURL=ComfyuiTextToVideo.node.js.map