@shibam/sticker-maker 1.2.5 → 1.2.7

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/index.js CHANGED
@@ -116,6 +116,10 @@ export default class Sticker {
116
116
  return this.buffer;
117
117
  }
118
118
 
119
+ async toBuffer() {
120
+ return await this.build();
121
+ }
122
+
119
123
  async metadata() {
120
124
  if (!this.buffer) {
121
125
  await this.build();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shibam/sticker-maker",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -14,6 +14,8 @@
14
14
  "cwebp": "^3.1.0",
15
15
  "file-type": "^20.0.0",
16
16
  "jimp": "^1.6.0",
17
- "node-webpmux": "^3.2.0"
17
+ "node-webpmux": "^3.2.0",
18
+ "sharp": "0.30.0",
19
+ "webp-converter": "^2.3.3"
18
20
  }
19
21
  }
package/utils/convert.js CHANGED
@@ -4,14 +4,14 @@ import { promises as fs } from "fs";
4
4
  import { tmpdir } from "os";
5
5
  import { join } from "path";
6
6
  import { fileTypeFromBuffer } from "file-type";
7
- import { Jimp } from "jimp";
7
+ import sharp from "sharp";
8
8
 
9
9
  const exec = promisify(execCallback);
10
10
 
11
11
  export default class MediaConverter {
12
12
  constructor(options = {}) {
13
13
  this.fps = options.fps || 12;
14
- this.quality = options.quality || 80;
14
+ this.quality = options.quality || 10;
15
15
  this.width = options.width || 512;
16
16
  this.mime = null;
17
17
  }
@@ -24,14 +24,14 @@ export default class MediaConverter {
24
24
 
25
25
  if (this.mime.startsWith("video/")) {
26
26
  const gif = await this.videoToGif(buffer);
27
- return await this.gifToWebp(gif);
27
+ return await this.ToWebp(gif);
28
28
  } else if (this.mime === "image/gif") {
29
- return await this.gifToWebp(buffer);
29
+ return await this.ToWebp(buffer);
30
30
  } else if (this.mime.startsWith("image/")) {
31
- return await this.imageToWebp(buffer);
31
+ return await this.ToWebp(buffer);
32
32
  }
33
33
 
34
- throw new Error(`Unsupported file type: ${mime}`);
34
+ throw new Error(`Unsupported file type: ${this.mime}`);
35
35
  }
36
36
 
37
37
  async videoToGif(buffer) {
@@ -46,74 +46,33 @@ export default class MediaConverter {
46
46
 
47
47
  const gifBuffer = await fs.readFile(tempOutput);
48
48
 
49
- await Promise.all([
50
- fs.unlink(tempInput).catch(() => {}),
51
- fs.unlink(tempOutput).catch(() => {}),
52
- ]);
49
+ await Promise.all([fs.unlink(tempInput).catch(() => {}), fs.unlink(tempOutput).catch(() => {})]);
53
50
 
54
51
  return gifBuffer;
55
52
  } catch (error) {
56
- await Promise.all([
57
- fs.unlink(tempInput).catch(() => {}),
58
- fs.unlink(tempOutput).catch(() => {}),
59
- ]);
53
+ await Promise.all([fs.unlink(tempInput).catch(() => {}), fs.unlink(tempOutput).catch(() => {})]);
60
54
  throw new Error(`Failed to convert video to gif: ${error.message}`);
61
55
  }
62
56
  }
63
57
 
64
- async gifToWebp(buffer) {
65
- const tempInput = join(tmpdir(), `input_${Date.now()}.gif`);
66
- const tempOutput = join(tmpdir(), `output_${Date.now()}.webp`);
58
+ async ToWebp(buffer) {
67
59
 
68
- try {
69
- await fs.writeFile(tempInput, buffer);
70
-
71
- const ffmpegCmd = `ffmpeg -i "${tempInput}" -vf "scale=${this.width}:-1" -c:v libwebp -quality ${this.quality} -loop 0 -lossless ${this.mime.startsWith("image/")?'1':'0'} -preset picture -an -vsync 0 "${tempOutput}"`;
72
- await exec(ffmpegCmd);
73
-
74
- const webpBuffer = await fs.readFile(tempOutput);
60
+ const mimeType = this.mime;
61
+ const isAnimated = mimeType?.includes("video") || mimeType?.includes("gif");
75
62
 
76
- await Promise.all([
77
- fs.unlink(tempInput).catch(() => {}),
78
- fs.unlink(tempOutput).catch(() => {}),
79
- ]);
80
-
81
- return webpBuffer;
82
- } catch (error) {
83
- await Promise.all([
84
- fs.unlink(tempInput).catch(() => {}),
85
- fs.unlink(tempOutput).catch(() => {}),
86
- ]);
87
- throw new Error(`Failed to convert gif to webp: ${error.message}`);
88
- }
89
- }
63
+ // Initialize sharp with animation support for GIFs or video frames
64
+ const res = sharp(buffer, { animated: isAnimated });
90
65
 
91
- async imageToWebp(buffer) {
92
- const tempInput = join(tmpdir(), `input_${Date.now()}.png`);
93
- const tempOutput = join(tmpdir(), `output_${Date.now()}.webp`);
66
+ // Resize image to fit within the specified width while preserving aspect ratio
67
+ res.resize(this.width, this.width, {
68
+ fit: sharp.fit.contain,
69
+ background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background
70
+ });
94
71
 
95
- try {
96
- const image = await Jimp.read(buffer);
97
- image.resize(this.width, Jimp.AUTO);
98
- await image.writeAsync(tempInput);
99
-
100
- const ffmpegCmd = `ffmpeg -i "${tempInput}" -quality ${this.quality} "${tempOutput}"`;
101
- await exec(ffmpegCmd);
102
-
103
- const webpBuffer = await fs.readFile(tempOutput);
104
-
105
- await Promise.all([
106
- fs.unlink(tempInput).catch(() => {}),
107
- fs.unlink(tempOutput).catch(() => {}),
108
- ]);
109
-
110
- return webpBuffer;
111
- } catch (error) {
112
- await Promise.all([
113
- fs.unlink(tempInput).catch(() => {}),
114
- fs.unlink(tempOutput).catch(() => {}),
115
- ]);
116
- throw new Error(`Failed to convert image to webp: ${error.message}`);
117
- }
72
+ // Convert to WebP format with the specified quality
73
+ return await res
74
+ .toFormat("webp")
75
+ .webp({ quality: this.quality, lossless: isAnimated }) // Lossless for GIFs or animations
76
+ .toBuffer();
118
77
  }
119
78
  }