@lee-jisoo/n8n-nodes-mediafx 1.6.23 → 1.6.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,21 @@ This is a custom n8n node for comprehensive, local media processing using FFmpeg
10
10
 
11
11
  ## 🆕 What's New in This Fork
12
12
 
13
+ ### v1.6.25
14
+ **New Features**
15
+
16
+ - **📝 Multi-line Text Alignment**: Added text alignment option for Add Text to Image
17
+ - Left, Center, Right alignment for multi-line text
18
+ - Useful when text contains line breaks (`\n`)
19
+
20
+ ### v1.6.24
21
+ **Bug Fixes**
22
+
23
+ - **🐛 Add Text to Image Fix**: Fixed "Unable to find a suitable output format" error
24
+ - Issue occurred when input image was downloaded from URL without file extension
25
+ - Now automatically detects actual image format using ffprobe
26
+ - Properly outputs correct format (JPEG, PNG, etc.) regardless of input file extension
27
+
13
28
  ### v1.6.21
14
29
  **New Features**
15
30
 
@@ -418,6 +418,7 @@ class MediaFX {
418
418
  fontKey: this.getNodeParameter('imageTextFontKey', i, 'noto-sans-kr'),
419
419
  size: this.getNodeParameter('imageTextSize', i, 48),
420
420
  color: this.getNodeParameter('imageTextColor', i, 'white'),
421
+ textAlign: this.getNodeParameter('imageTextAlign', i, 'left'),
421
422
  outlineWidth: this.getNodeParameter('imageTextOutlineWidth', i, 0),
422
423
  outlineColor: this.getNodeParameter('imageTextOutlineColor', i, 'black'),
423
424
  enableBackground: this.getNodeParameter('imageTextEnableBackground', i, false),
@@ -29,6 +29,29 @@ const path = __importStar(require("path"));
29
29
  const ffmpeg = require("fluent-ffmpeg");
30
30
  const utils_1 = require("../utils");
31
31
  const fs = __importStar(require("fs-extra"));
32
+ // Map FFmpeg format names to file extensions
33
+ const FORMAT_TO_EXTENSION = {
34
+ 'jpeg_pipe': '.jpg',
35
+ 'png_pipe': '.png',
36
+ 'gif_pipe': '.gif',
37
+ 'webp_pipe': '.webp',
38
+ 'bmp_pipe': '.bmp',
39
+ 'tiff_pipe': '.tiff',
40
+ 'image2': '.jpg', // Default for generic image format
41
+ };
42
+ // Get the actual image format using ffprobe
43
+ function detectImageFormat(filePath) {
44
+ return new Promise((resolve, reject) => {
45
+ ffmpeg.ffprobe(filePath, (err, metadata) => {
46
+ if (err) {
47
+ return reject(new Error(`Failed to probe image: ${err.message}`));
48
+ }
49
+ const formatName = metadata.format.format_name || '';
50
+ const extension = FORMAT_TO_EXTENSION[formatName] || '.jpg';
51
+ resolve(extension);
52
+ });
53
+ });
54
+ }
32
55
  function getPositionFromAlignment(horizontalAlign, verticalAlign, paddingX, paddingY) {
33
56
  let x;
34
57
  let y;
@@ -73,6 +96,7 @@ async function executeAddTextToImage(imagePath, text, options, itemIndex) {
73
96
  // Set default values for text options
74
97
  const fontSize = options.size || 48;
75
98
  const fontColor = options.color || 'white';
99
+ const textAlign = options.textAlign || 'left';
76
100
  // Outline options
77
101
  const outlineWidth = options.outlineWidth || 0;
78
102
  const outlineColor = options.outlineColor || 'black';
@@ -99,13 +123,27 @@ async function executeAddTextToImage(imagePath, text, options, itemIndex) {
99
123
  positionX = options.x || '(w-text_w)/2';
100
124
  positionY = options.y || '(h-text_h)/2';
101
125
  }
102
- // Use the same extension as input image
103
- const inputExt = path.extname(imagePath);
104
- const outputPath = (0, utils_1.getTempFile)(inputExt);
126
+ // Determine output extension - detect actual format if input has .tmp extension
127
+ let outputExt = path.extname(imagePath).toLowerCase();
128
+ const knownImageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.tiff'];
129
+ if (!knownImageExtensions.includes(outputExt)) {
130
+ // Input has unknown extension (e.g., .tmp from URL download), detect actual format
131
+ try {
132
+ outputExt = await detectImageFormat(imagePath);
133
+ }
134
+ catch {
135
+ // Fallback to .jpg if detection fails
136
+ outputExt = '.jpg';
137
+ }
138
+ }
139
+ const outputPath = (0, utils_1.getTempFile)(outputExt);
105
140
  // Escape single quotes in text
106
141
  const escapedText = text.replace(/'/g, `''`);
142
+ // Map text alignment to FFmpeg format (L=left, C=center, R=right)
143
+ const textAlignMap = { left: 'L', center: 'C', right: 'R' };
144
+ const ffmpegTextAlign = textAlignMap[textAlign] || 'L';
107
145
  // Build drawtext filter
108
- let drawtext = `drawtext=fontfile=${fontPath}:text='${escapedText}':fontsize=${fontSize}:fontcolor=${fontColor}:x=${positionX}:y=${positionY}`;
146
+ let drawtext = `drawtext=fontfile=${fontPath}:text='${escapedText}':fontsize=${fontSize}:fontcolor=${fontColor}:x=${positionX}:y=${positionY}:text_align=${ffmpegTextAlign}`;
109
147
  // Add outline (border) if width > 0
110
148
  if (outlineWidth > 0) {
111
149
  drawtext += `:borderw=${outlineWidth}:bordercolor=${outlineColor}`;
@@ -122,6 +122,24 @@ exports.imageProperties = [
122
122
  },
123
123
  description: 'Text color (e.g., white, #FF0000, rgb(255,0,0))',
124
124
  },
125
+ {
126
+ displayName: 'Text Alignment (Multi-line)',
127
+ name: 'imageTextAlign',
128
+ type: 'options',
129
+ options: [
130
+ { name: 'Left', value: 'left' },
131
+ { name: 'Center', value: 'center' },
132
+ { name: 'Right', value: 'right' },
133
+ ],
134
+ default: 'left',
135
+ displayOptions: {
136
+ show: {
137
+ resource: ['image'],
138
+ operation: ['addTextToImage'],
139
+ },
140
+ },
141
+ description: 'Text alignment for multi-line text (when text contains line breaks)',
142
+ },
125
143
  {
126
144
  displayName: 'Outline Width',
127
145
  name: 'imageTextOutlineWidth',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lee-jisoo/n8n-nodes-mediafx",
3
- "version": "1.6.23",
3
+ "version": "1.6.25",
4
4
  "description": "N8N custom nodes for video editing and media processing (Enhanced fork with Speed control and Subtitle fixes)",
5
5
  "license": "MIT",
6
6
  "author": {