UNPKG

n8n-nodes-jiemeng

Version:

n8n node for Jiemeng AI video generation using Volcengine Doubao Seedance model. Generate videos from images and text prompts.

220 lines 9.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Jiemeng = void 0; const n8n_workflow_1 = require("n8n-workflow"); class Jiemeng { constructor() { this.description = { displayName: 'Jiemeng', name: 'jiemeng', icon: 'file:jiemeng.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Use Jiemeng API to generate videos from images and prompts', defaults: { name: 'Jiemeng', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'jiemengApi', required: true, }, ], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Video Generation', value: 'videoGeneration', }, ], default: 'videoGeneration', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['videoGeneration'], }, }, options: [ { name: 'Image to Video', value: 'imageToVideo', action: 'Generate a video from an image and a prompt', }, ], default: 'imageToVideo', }, { displayName: 'Image URL', name: 'imageUrl', type: 'string', default: '', required: true, displayOptions: { show: { resource: ['videoGeneration'], operation: ['imageToVideo'], }, }, description: 'The URL of the image to use as the base for the video', }, { displayName: 'Prompt', name: 'prompt', type: 'string', default: '', required: true, displayOptions: { show: { resource: ['videoGeneration'], operation: ['imageToVideo'], }, }, description: 'The prompt to guide the video generation', }, ], }; } static getErrorSuggestions(errorCode) { switch (errorCode) { case 'ModelNotOpen': return [ '前往火山方舟控制台开通模型服务', '访问: https://console.volcengine.com/ark/region:ark+cn-beijing/openManagement', '在「视觉大模型」下找到 Seedance 相关模型并开通服务', '确保账户有足够的额度' ]; case 'InvalidEndpoint.NotFound': return [ '检查 API 端点 URL 是否正确', '确认使用的是正确的火山引擎 API 地址' ]; case 'Unauthorized': return [ '检查 API Key 是否正确', '确认 API Key 有相应的权限', '检查 API Key 是否已过期' ]; default: return ['请检查网络连接和API配置']; } } async execute() { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const imageUrl = this.getNodeParameter('imageUrl', i, ''); const prompt = this.getNodeParameter('prompt', i, ''); const credentials = await this.getCredentials('jiemengApi'); const createTaskBody = { model: 'doubao-seedance-1-0-lite-i2v-250428', content: [ { type: 'text', text: prompt, }, { type: 'image_url', image_url: { url: imageUrl, }, } ], }; const createTaskResponse = await this.helpers.request({ method: 'POST', url: 'https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks', headers: { 'Authorization': `Bearer ${credentials.apiKey}`, 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: createTaskBody, json: true, }); const taskId = createTaskResponse.id; if (!taskId) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to create generation task. No task ID returned.'); } let taskResult; let taskDone = false; const maxRetries = 60; let retries = 0; while (!taskDone && retries < maxRetries) { taskResult = await this.helpers.request({ method: 'GET', url: `https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks/${taskId}`, headers: { 'Authorization': `Bearer ${credentials.apiKey}`, 'Accept': 'application/json', }, json: true, }); if (taskResult.status === 'done' || taskResult.status === 'succeeded') { taskDone = true; } else if (taskResult.status === 'failed' || taskResult.status === 'canceled') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Task failed with status: ${taskResult.status}`, { itemIndex: i }); } else { retries++; await new Promise(resolve => setTimeout(resolve, 5000)); } } if (!taskDone) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Task timed out after 5 minutes.', { itemIndex: i }); } const outputData = { success: true, taskId: taskResult.id, status: taskResult.status, videoUrl: ((_a = taskResult.content) === null || _a === void 0 ? void 0 : _a.video_url) || null, model: taskResult.model, usage: taskResult.usage, createdAt: taskResult.created_at, updatedAt: taskResult.updated_at, originalResponse: taskResult, }; returnData.push({ json: outputData, pairedItem: { item: i }, }); } catch (error) { if (this.continueOnFail()) { const errorData = { success: false, error: error.message, errorCode: ((_d = (_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.code) || 'UNKNOWN_ERROR', errorType: ((_g = (_f = (_e = error.response) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.error) === null || _g === void 0 ? void 0 : _g.type) || 'UNKNOWN_TYPE', statusCode: ((_h = error.response) === null || _h === void 0 ? void 0 : _h.status) || null, suggestions: Jiemeng.getErrorSuggestions(((_l = (_k = (_j = error.response) === null || _j === void 0 ? void 0 : _j.data) === null || _k === void 0 ? void 0 : _k.error) === null || _l === void 0 ? void 0 : _l.code) || 'UNKNOWN_ERROR'), }; returnData.push({ json: errorData, pairedItem: { item: i }, }); continue; } throw error; } } return this.prepareOutputData(returnData); } } exports.Jiemeng = Jiemeng; //# sourceMappingURL=Jiemeng.node.js.map