amiudmodz 5.0.9 → 5.1.0

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.
@@ -103,43 +103,52 @@ const extractVideoThumb = async (path, destPath, time, size) => new Promise((res
103
103
  });
104
104
  const extractImageThumb = async (bufferOrFilePath, width = 32) => {
105
105
  var _a, _b;
106
+ let tmpPath;
106
107
  if (bufferOrFilePath instanceof stream_1.Readable) {
107
- bufferOrFilePath = await (0, exports.toBuffer)(bufferOrFilePath);
108
- }
109
- const lib = await getImageProcessingLibrary();
110
- if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
111
- const img = lib.sharp.default(bufferOrFilePath);
112
- const dimensions = await img.metadata();
113
- const buffer = await img
114
- .resize(width)
115
- .jpeg({ quality: 50 })
116
- .toBuffer();
117
- return {
118
- buffer,
119
- original: {
120
- width: dimensions.width,
121
- height: dimensions.height,
122
- },
123
- };
108
+ // Spill stream to disk instead of buffering to RAM
109
+ tmpPath = await spillToDisk(bufferOrFilePath);
110
+ bufferOrFilePath = tmpPath;
124
111
  }
125
- else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
126
- const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
127
- const jimp = await read(bufferOrFilePath);
128
- const dimensions = {
129
- width: jimp.getWidth(),
130
- height: jimp.getHeight()
131
- };
132
- const buffer = await jimp
133
- .quality(50)
134
- .resize(width, AUTO, RESIZE_BILINEAR)
135
- .getBufferAsync(MIME_JPEG);
136
- return {
137
- buffer,
138
- original: dimensions
139
- };
140
- }
141
- else {
142
- throw new boom_1.Boom('No image processing library available');
112
+ try {
113
+ const lib = await getImageProcessingLibrary();
114
+ if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
115
+ const img = lib.sharp.default(bufferOrFilePath);
116
+ const dimensions = await img.metadata();
117
+ const buffer = await img
118
+ .resize(width)
119
+ .jpeg({ quality: 50 })
120
+ .toBuffer();
121
+ return {
122
+ buffer,
123
+ original: {
124
+ width: dimensions.width,
125
+ height: dimensions.height,
126
+ },
127
+ };
128
+ }
129
+ else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
130
+ const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
131
+ const jimp = await read(bufferOrFilePath);
132
+ const dimensions = {
133
+ width: jimp.getWidth(),
134
+ height: jimp.getHeight()
135
+ };
136
+ const buffer = await jimp
137
+ .quality(50)
138
+ .resize(width, AUTO, RESIZE_BILINEAR)
139
+ .getBufferAsync(MIME_JPEG);
140
+ return {
141
+ buffer,
142
+ original: dimensions
143
+ };
144
+ }
145
+ else {
146
+ throw new boom_1.Boom('No image processing library available');
147
+ }
148
+ } finally {
149
+ if (tmpPath) {
150
+ await fs_1.promises.unlink(tmpPath).catch(() => {});
151
+ }
143
152
  }
144
153
  };
145
154
  exports.extractImageThumb = extractImageThumb;
@@ -151,6 +160,7 @@ exports.encodeBase64EncodedStringForUpload = encodeBase64EncodedStringForUpload;
151
160
  const generateProfilePicture = async (mediaUpload) => {
152
161
  var _a, _b;
153
162
  let bufferOrFilePath;
163
+ let tmpPath;
154
164
  if (Buffer.isBuffer(mediaUpload)) {
155
165
  bufferOrFilePath = mediaUpload;
156
166
  }
@@ -158,34 +168,41 @@ const generateProfilePicture = async (mediaUpload) => {
158
168
  bufferOrFilePath = mediaUpload.url.toString();
159
169
  }
160
170
  else {
161
- bufferOrFilePath = await (0, exports.toBuffer)(mediaUpload.stream);
162
- }
163
- const lib = await getImageProcessingLibrary();
164
- let img;
165
- if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
166
- img = lib.sharp.default(bufferOrFilePath)
167
- .resize(640, 640)
168
- .jpeg({
169
- quality: 50,
170
- })
171
- .toBuffer();
172
- }
173
- else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
174
- const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp;
175
- const jimp = await read(bufferOrFilePath);
176
- const min = Math.min(jimp.getWidth(), jimp.getHeight());
177
- const cropped = jimp.crop(0, 0, min, min);
178
- img = cropped
179
- .quality(50)
180
- .resize(640, 640, RESIZE_BILINEAR)
181
- .getBufferAsync(MIME_JPEG);
171
+ tmpPath = await spillToDisk(mediaUpload.stream);
172
+ bufferOrFilePath = tmpPath;
182
173
  }
183
- else {
184
- throw new boom_1.Boom('No image processing library available');
174
+ try {
175
+ const lib = await getImageProcessingLibrary();
176
+ let img;
177
+ if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
178
+ img = lib.sharp.default(bufferOrFilePath)
179
+ .resize(640, 640)
180
+ .jpeg({
181
+ quality: 50,
182
+ })
183
+ .toBuffer();
184
+ }
185
+ else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
186
+ const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp;
187
+ const jimp = await read(bufferOrFilePath);
188
+ const min = Math.min(jimp.getWidth(), jimp.getHeight());
189
+ const cropped = jimp.crop(0, 0, min, min);
190
+ img = cropped
191
+ .quality(50)
192
+ .resize(640, 640, RESIZE_BILINEAR)
193
+ .getBufferAsync(MIME_JPEG);
194
+ }
195
+ else {
196
+ throw new boom_1.Boom('No image processing library available');
197
+ }
198
+ return {
199
+ img: await img,
200
+ };
201
+ } finally {
202
+ if (tmpPath) {
203
+ await fs_1.promises.unlink(tmpPath).catch(() => {});
204
+ }
185
205
  }
186
- return {
187
- img: await img,
188
- };
189
206
  };
190
207
  exports.generateProfilePicture = generateProfilePicture;
191
208
  /** gets the SHA256 of the given media message */
@@ -239,19 +256,14 @@ async function getAudioWaveform(buffer, logger) {
239
256
  const { PassThrough } = require('stream');
240
257
  const ff = require('fluent-ffmpeg');
241
258
 
242
- let audioData;
259
+ const inputStream = new PassThrough();
243
260
  if (Buffer.isBuffer(buffer)) {
244
- audioData = buffer;
261
+ inputStream.end(buffer);
245
262
  } else if (typeof buffer === 'string') {
246
- const rStream = require('fs').createReadStream(buffer);
247
- audioData = await exports.toBuffer(rStream);
263
+ (0, fs_1.createReadStream)(buffer).pipe(inputStream);
248
264
  } else {
249
- audioData = await exports.toBuffer(buffer);
265
+ buffer.pipe(inputStream);
250
266
  }
251
-
252
- return await new Promise((resolve, reject) => {
253
- const inputStream = new PassThrough();
254
- inputStream.end(audioData);
255
267
  const chunks = [];
256
268
  const bars = 64;
257
269
 
@@ -280,7 +292,7 @@ async function getAudioWaveform(buffer, logger) {
280
292
  const normalized = avg.map(v => Math.floor((v / max) * 100));
281
293
  resolve(new Uint8Array(normalized));
282
294
  })
283
- .pipe()
295
+ .pipe(new PassThrough(), { end: true })
284
296
  .on('data', chunk => chunks.push(chunk));
285
297
  });
286
298
  } catch (e) {
@@ -504,17 +516,40 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
504
516
  const { stream, type, spilledPath } = await (0, exports.getStream)(media, opts);
505
517
  let finalStream = stream;
506
518
  let opusConverted = false;
507
- // Track temp files created for spill-to-disk of audio opus conversion
508
519
  let opusSpillPath;
509
520
  if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
510
521
  try {
511
522
  // Write audio to temp file, convert via ffmpeg, write result to another temp file
512
523
  const audioTmpPath = await spillToDisk(stream);
513
524
  try {
514
- const opusBuffer = await exports.convertToOpusBuffer(
515
- await fs_1.promises.readFile(audioTmpPath), logger
516
- );
517
- opusSpillPath = await spillToDisk(opusBuffer);
525
+ const ff = require('fluent-ffmpeg');
526
+ opusSpillPath = (0, path_1.join)(getTmpFilesDirectory(), `opus-${(0, generics_1.generateMessageID)()}`);
527
+ const opusWriteStream = (0, fs_1.createWriteStream)(opusSpillPath);
528
+
529
+ await new Promise((resolve, reject) => {
530
+ ff(audioTmpPath)
531
+ .noVideo()
532
+ .audioCodec('libopus')
533
+ .format('ogg')
534
+ .audioBitrate('48k')
535
+ .audioChannels(1)
536
+ .audioFrequency(48000)
537
+ .outputOptions([
538
+ '-vn',
539
+ '-b:a 64k',
540
+ '-ac 2',
541
+ '-ar 48000',
542
+ '-map_metadata', '-1',
543
+ '-application', 'voip'
544
+ ])
545
+ .on('error', (err) => {
546
+ opusWriteStream.destroy();
547
+ reject(err);
548
+ })
549
+ .on('end', resolve)
550
+ .pipe(opusWriteStream);
551
+ });
552
+
518
553
  finalStream = (0, fs_1.createReadStream)(opusSpillPath);
519
554
  opusConverted = true;
520
555
  } finally {
@@ -799,6 +834,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
799
834
  headers: {
800
835
  ...options.headers || {},
801
836
  'Content-Type': 'application/octet-stream',
837
+ 'Content-Length': bodyLength.toString(),
802
838
  'Origin': Defaults_1.DEFAULT_ORIGIN
803
839
  },
804
840
  httpsAgent: fetchAgent,
@@ -157,6 +157,9 @@ const prepareWAMessageMedia = async (message, options) => {
157
157
  forceOpus: (mediaType === "audio" && uploadData.mimetype && uploadData.mimetype.includes('opus'))
158
158
  });
159
159
 
160
+ // Nullify the media reference to help GC free the memory if it's a large Buffer
161
+ uploadData.media = undefined;
162
+
160
163
  if (mediaType === 'audio' && opusConverted) {
161
164
  uploadData.mimetype = 'audio/ogg; codecs=opus';
162
165
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amiudmodz",
3
- "version": "5.0.9",
3
+ "version": "5.1.0",
4
4
  "description": "WhatsApp Baileys mod Powered by UDMODZ",
5
5
  "keywords": [
6
6
  "whatsapp",