n8n-nodes-mediafx
Version:
N8N custom nodes for video editing and media processing
109 lines (108 loc) • 4.52 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeAddText = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const path = __importStar(require("path"));
const ffmpeg = require("fluent-ffmpeg");
const utils_1 = require("../utils");
const fs = __importStar(require("fs-extra"));
function getPositionFromAlignment(horizontalAlign, verticalAlign, paddingX, paddingY) {
let x;
let y;
// Set X position based on horizontal alignment
switch (horizontalAlign) {
case 'left':
x = `${paddingX}`;
break;
case 'right':
x = `w-text_w-${paddingX}`;
break;
case 'center':
default:
x = '(w-text_w)/2';
break;
}
// Set Y position based on vertical alignment
switch (verticalAlign) {
case 'top':
y = `${paddingY}`;
break;
case 'bottom':
y = `h-th-${paddingY}`;
break;
case 'middle':
default:
y = '(h-text_h)/2';
break;
}
return { x, y };
}
async function executeAddText(video, text, options, itemIndex) {
var _a, _b, _c, _d;
const allFonts = (0, utils_1.getAvailableFonts)();
const fontKey = options.fontKey || 'noto-sans-kr';
const font = allFonts[fontKey];
if (!font || !font.path) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Selected font key '${fontKey}' is not valid or its file path is missing.`, { itemIndex });
}
const fontPath = font.path;
// Set default values for text options
const fontSize = options.size || 48;
const fontColor = options.color || 'white';
const startTime = options.startTime || 0;
const endTime = options.endTime || 5;
// Handle position based on position type
let positionX;
let positionY;
const positionType = options.positionType || 'alignment';
if (positionType === 'alignment') {
const horizontalAlign = options.horizontalAlign || 'center';
const verticalAlign = options.verticalAlign || 'bottom';
const paddingX = (_b = (_a = options.paddingX) !== null && _a !== void 0 ? _a : options.padding) !== null && _b !== void 0 ? _b : 20;
const paddingY = (_d = (_c = options.paddingY) !== null && _c !== void 0 ? _c : options.padding) !== null && _d !== void 0 ? _d : 20;
const position = getPositionFromAlignment(horizontalAlign, verticalAlign, paddingX, paddingY);
positionX = position.x;
positionY = position.y;
}
else {
// Custom position
positionX = options.x || '(w-text_w)/2';
positionY = options.y || 'h-th-10';
}
const outputPath = (0, utils_1.getTempFile)(path.extname(video));
const drawtext = `drawtext=fontfile=${fontPath}:text='${text.replace(/'/g, `''`)}':fontsize=${fontSize}:fontcolor=${fontColor}:x=${positionX}:y=${positionY}:enable='between(t,${startTime},${endTime})'`;
const command = ffmpeg(video).videoFilters(drawtext).audioCodec('copy').save(outputPath);
try {
await (0, utils_1.runFfmpeg)(command);
return outputPath;
}
catch (error) {
// Clean up output file if creation failed
await fs.remove(outputPath).catch(() => { });
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error adding text to video. FFmpeg error: ${error.message}`, { itemIndex });
}
}
exports.executeAddText = executeAddText;