amiudmodz 5.0.8 → 5.0.9
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/lib/Utils/messages-media.js +63 -10
- package/lib/Utils/messages.js +7 -1
- package/package.json +1 -1
|
@@ -343,9 +343,31 @@ const toBuffer = async (stream) => {
|
|
|
343
343
|
return Buffer.concat(chunks);
|
|
344
344
|
};
|
|
345
345
|
exports.toBuffer = toBuffer;
|
|
346
|
+
/**
|
|
347
|
+
* Spills a Buffer or Readable stream to a temp file on disk so it is not
|
|
348
|
+
* held entirely in RAM. Returns the temp-file path so the caller can clean
|
|
349
|
+
* it up when done.
|
|
350
|
+
*/
|
|
351
|
+
const spillToDisk = async (source) => {
|
|
352
|
+
const tmpPath = (0, path_1.join)(getTmpFilesDirectory(), `spill-${(0, generics_1.generateMessageID)()}`);
|
|
353
|
+
const writeStream = (0, fs_1.createWriteStream)(tmpPath);
|
|
354
|
+
await new Promise((resolve, reject) => {
|
|
355
|
+
writeStream.on('error', reject);
|
|
356
|
+
writeStream.on('finish', resolve);
|
|
357
|
+
if (Buffer.isBuffer(source)) {
|
|
358
|
+
writeStream.end(source);
|
|
359
|
+
} else {
|
|
360
|
+
source.pipe(writeStream);
|
|
361
|
+
source.on('error', reject);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
return tmpPath;
|
|
365
|
+
};
|
|
346
366
|
const getStream = async (item, opts) => {
|
|
347
367
|
if (Buffer.isBuffer(item)) {
|
|
348
|
-
|
|
368
|
+
// Write the Buffer to a temp file so it can be GC'd from RAM
|
|
369
|
+
const tmpPath = await spillToDisk(item);
|
|
370
|
+
return { stream: (0, fs_1.createReadStream)(tmpPath), type: 'file', spilledPath: tmpPath };
|
|
349
371
|
}
|
|
350
372
|
if ('stream' in item) {
|
|
351
373
|
return { stream: item.stream, type: 'readable' };
|
|
@@ -479,15 +501,25 @@ const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequi
|
|
|
479
501
|
};
|
|
480
502
|
exports.prepareStream = prepareStream;
|
|
481
503
|
const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, isPtt, forceOpus } = {}) => {
|
|
482
|
-
const { stream, type } = await (0, exports.getStream)(media, opts);
|
|
504
|
+
const { stream, type, spilledPath } = await (0, exports.getStream)(media, opts);
|
|
483
505
|
let finalStream = stream;
|
|
484
506
|
let opusConverted = false;
|
|
507
|
+
// Track temp files created for spill-to-disk of audio opus conversion
|
|
508
|
+
let opusSpillPath;
|
|
485
509
|
if (mediaType === 'audio' && (isPtt === true || forceOpus === true)) {
|
|
486
510
|
try {
|
|
487
|
-
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
511
|
+
// Write audio to temp file, convert via ffmpeg, write result to another temp file
|
|
512
|
+
const audioTmpPath = await spillToDisk(stream);
|
|
513
|
+
try {
|
|
514
|
+
const opusBuffer = await exports.convertToOpusBuffer(
|
|
515
|
+
await fs_1.promises.readFile(audioTmpPath), logger
|
|
516
|
+
);
|
|
517
|
+
opusSpillPath = await spillToDisk(opusBuffer);
|
|
518
|
+
finalStream = (0, fs_1.createReadStream)(opusSpillPath);
|
|
519
|
+
opusConverted = true;
|
|
520
|
+
} finally {
|
|
521
|
+
await fs_1.promises.unlink(audioTmpPath).catch(() => {});
|
|
522
|
+
}
|
|
491
523
|
}
|
|
492
524
|
catch (error) {
|
|
493
525
|
const { stream: newStream } = await (0, exports.getStream)(media, opts);
|
|
@@ -497,15 +529,16 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
497
529
|
const mediaKey = Crypto.randomBytes(32);
|
|
498
530
|
const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType);
|
|
499
531
|
|
|
500
|
-
|
|
501
532
|
const encPath = (0, path_1.join)(getTmpFilesDirectory(), `enc-${mediaType}-${(0, generics_1.generateMessageID)()}`);
|
|
502
533
|
const encTempWriteStream = (0, fs_1.createWriteStream)(encPath);
|
|
503
534
|
|
|
504
535
|
let bodyPath;
|
|
505
536
|
let writeStream;
|
|
506
537
|
let didSaveToTmpPath = false;
|
|
538
|
+
// For 'file' type (includes our spill-to-disk buffers), use the path directly
|
|
507
539
|
if (type === 'file') {
|
|
508
|
-
|
|
540
|
+
// If spilled from a Buffer, spilledPath IS the original; use it as bodyPath
|
|
541
|
+
bodyPath = spilledPath || (media && media.url ? media.url : undefined);
|
|
509
542
|
}
|
|
510
543
|
else if (saveOriginalFileIfRequired) {
|
|
511
544
|
bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageID)());
|
|
@@ -556,15 +589,32 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
556
589
|
const fileSha256 = sha256Plain.digest();
|
|
557
590
|
const fileEncSha256 = sha256Enc.digest();
|
|
558
591
|
|
|
559
|
-
|
|
560
|
-
|
|
592
|
+
await new Promise((resolve, reject) => {
|
|
593
|
+
encTempWriteStream.end(resolve);
|
|
594
|
+
encTempWriteStream.once('error', reject);
|
|
595
|
+
});
|
|
596
|
+
if (writeStream) {
|
|
597
|
+
await new Promise((resolve, reject) => {
|
|
598
|
+
writeStream.end(resolve);
|
|
599
|
+
writeStream.once('error', reject);
|
|
600
|
+
});
|
|
601
|
+
}
|
|
561
602
|
finalStream.destroy();
|
|
603
|
+
// Clean up the opus spill temp file if used
|
|
604
|
+
if (opusSpillPath) {
|
|
605
|
+
await fs_1.promises.unlink(opusSpillPath).catch(() => {});
|
|
606
|
+
}
|
|
607
|
+
// Clean up the buffer-spill temp file — it's no longer needed once encrypted
|
|
608
|
+
// (the enc temp file is what gets uploaded; bodyPath/spilledPath is only
|
|
609
|
+
// needed for thumbnail/duration computation which happens in parallel)
|
|
610
|
+
// Caller (messages.js) handles cleanup of streamPath & bodyPath.
|
|
562
611
|
|
|
563
612
|
return {
|
|
564
613
|
mediaKey,
|
|
565
614
|
encWriteStream: (0, fs_1.createReadStream)(encPath),
|
|
566
615
|
bodyPath,
|
|
567
616
|
streamPath: encPath,
|
|
617
|
+
spilledPath, // expose so caller can clean up the buffer spill file
|
|
568
618
|
mac,
|
|
569
619
|
fileEncSha256,
|
|
570
620
|
fileSha256,
|
|
@@ -581,6 +631,9 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
581
631
|
sha256Plain.destroy();
|
|
582
632
|
sha256Enc.destroy();
|
|
583
633
|
finalStream.destroy();
|
|
634
|
+
if (opusSpillPath) {
|
|
635
|
+
await fs_1.promises.unlink(opusSpillPath).catch(() => {});
|
|
636
|
+
}
|
|
584
637
|
try {
|
|
585
638
|
await fs_1.promises.unlink(encPath);
|
|
586
639
|
} catch { }
|
package/lib/Utils/messages.js
CHANGED
|
@@ -149,7 +149,7 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
149
149
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
150
150
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
151
151
|
|
|
152
|
-
const { mediaKey, encWriteStream, bodyPath, streamPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
152
|
+
const { mediaKey, encWriteStream, bodyPath, streamPath, spilledPath, fileEncSha256, fileSha256, fileLength, didSaveToTmpPath, opusConverted } = await (options.newsletter ? messages_media_1.prepareStream : messages_media_1.encryptedStream)(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
153
153
|
logger,
|
|
154
154
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
155
155
|
opts: options.options,
|
|
@@ -210,6 +210,12 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
210
210
|
if (streamPath) {
|
|
211
211
|
await fs_1.promises.unlink(streamPath).catch(() => { });
|
|
212
212
|
}
|
|
213
|
+
// Clean up the buffer-spill temp file (if input was a Buffer, it was
|
|
214
|
+
// written to /tmp to avoid holding it in RAM; delete it now that we
|
|
215
|
+
// are done with thumbnail/duration computation)
|
|
216
|
+
if (spilledPath && spilledPath !== bodyPath) {
|
|
217
|
+
await fs_1.promises.unlink(spilledPath).catch(() => { });
|
|
218
|
+
}
|
|
213
219
|
logger === null || logger === void 0 ? void 0 : logger.debug('removed tmp files');
|
|
214
220
|
});
|
|
215
221
|
|