MCPcopy Create free account
hub / github.com/GlobalTechInfo/MEGA-MD / _convertBufferToStickerWebp

Function _convertBufferToStickerWebp

plugins/igsc.js:10–67  ·  view source on GitHub ↗
(inputBuffer, isAnimated, cropSquare)

Source from the content-addressed store, hash-verified

8import crypto from 'crypto';
9import { stickercropFromBuffer } from './stickercrop.js';
10async function _convertBufferToStickerWebp(inputBuffer, isAnimated, cropSquare) {
11 const tmpDir = path.join(process.cwd(), 'temp');
12 if (!fs.existsSync(tmpDir))
13 fs.mkdirSync(tmpDir, { recursive: true });
14 const tempInputBase = path.join(tmpDir, `igs_${Date.now()}_${Math.random().toString(36).slice(2)}`);
15 const tempInput = isAnimated ? `${tempInputBase}.mp4` : `${tempInputBase}.jpg`;
16 const tempOutput = path.join(tmpDir, `igs_out_${Date.now()}_${Math.random().toString(36).slice(2)}.webp`);
17 fs.writeFileSync(tempInput, inputBuffer);
18 const scheduleDelete = (p) => {
19 if (!p)
20 return;
21 setTimeout(() => {
22 try {
23 fs.unlinkSync(p);
24 }
25 catch { }
26 }, 5000);
27 };
28 const vfCropSquareImg = "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512";
29 const vfPadSquareImg = "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000";
30 let ffmpegCommand;
31 if (isAnimated) {
32 const isLargeVideo = inputBuffer.length > (5 * 1024 * 1024);
33 if (cropSquare) {
34 ffmpegCommand = isLargeVideo
35 ? `ffmpeg -y -i "${tempInput}" -t 2 -vf "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 30 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput}"`
36 : `ffmpeg -y -i "${tempInput}" -t 3 -vf "crop=min(iw\\,ih):min(iw\\,ih),scale=512:512,fps=12" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 50 -compression_level 6 -b:v 150k -max_muxing_queue_size 1024 "${tempOutput}"`;
37 }
38 else {
39 ffmpegCommand = isLargeVideo
40 ? `ffmpeg -y -i "${tempInput}" -t 2 -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,fps=8" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 35 -compression_level 6 -b:v 100k -max_muxing_queue_size 1024 "${tempOutput}"`
41 : `ffmpeg -y -i "${tempInput}" -t 3 -vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,fps=12" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 45 -compression_level 6 -b:v 150k -max_muxing_queue_size 1024 "${tempOutput}"`;
42 }
43 }
44 else {
45 const vf = `${cropSquare ? vfCropSquareImg : vfPadSquareImg},format=rgba`;
46 ffmpegCommand = `ffmpeg -y -i "${tempInput}" -vf "${vf}" -c:v libwebp -preset default -loop 0 -vsync 0 -pix_fmt yuva420p -quality 40 -compression_level 6 "${tempOutput}"`;
47 }
48 await new Promise((resolve, reject) => {
49 exec(ffmpegCommand, (error) => error ? reject(error) : resolve(undefined));
50 });
51 const webpBuffer = fs.readFileSync(tempOutput);
52 scheduleDelete(tempOutput);
53 scheduleDelete(tempInput);
54 const img = new webp.Image();
55 await img.load(webpBuffer);
56 const json = {
57 'sticker-pack-id': crypto.randomBytes(32).toString('hex'),
58 'sticker-pack-name': config.packname || 'MegaBot',
59 'emojis': ['📸']
60 };
61 const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
62 const jsonBuffer = Buffer.from(JSON.stringify(json), 'utf8');
63 const exif = Buffer.concat([exifAttr, jsonBuffer]);
64 exif.writeUIntLE(jsonBuffer.length, 14, 4);
65 img.exif = exif;
66 return await img.save(null);
67}

Callers

nothing calls this directly

Calls 1

scheduleDeleteFunction · 0.70

Tested by

no test coverage detected