@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
|
-
//
|
|
103
|
-
|
|
104
|
-
const
|
|
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