frostpv 1.0.21 → 1.0.24

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.
Files changed (2) hide show
  1. package/index.js +57 -12
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -4,25 +4,27 @@ const path = require("path");
4
4
  const os = require("os");
5
5
  const FormData = require("form-data");
6
6
  const crypto = require("crypto");
7
- const { igdl, ttdl, fbdown, mediafire, capcut, gdrive, pinterest, twitter } = require("btch-downloader");
8
- const { TwitterDL } = require("twitter-downloader");
9
- const instagramCustom = require('./instagramcustom');
10
- const tiktokCustom = require('./tiktokcustom');
11
- const btch = require("btch-downloader");
12
- const btchOld = require("btch-downloader-old");
13
-
14
-
15
- const Tiktok = require("@tobyg74/tiktok-api-dl");
16
- const ab = require("ab-downloader");
17
- const ffmpegPath = require('ffmpeg-ffprobe-static').ffmpegPath;
18
7
  const { v4: uuidv4 } = require('uuid');
19
-
20
8
  const pathToFfmpeg = require("ffmpeg-ffprobe-static");
21
9
  const ffmpeg = require("fluent-ffmpeg");
22
10
  ffmpeg.setFfmpegPath(pathToFfmpeg.ffmpegPath);
23
11
 
12
+ /**
13
+ * Aciona a coleta de lixo se o Node for iniciado com --expose-gc
14
+ */
15
+ function triggerGC() {
16
+ if (global.gc) {
17
+ try {
18
+ global.gc();
19
+ } catch (e) {
20
+ // Ignora silenciosamente se falhar
21
+ }
22
+ }
23
+ }
24
+
24
25
  const OUTPUT_DIR = process.cwd();
25
26
  try { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); } catch (_) { }
27
+
26
28
  const TEMP_DIR = path.join(os.tmpdir(), "downloader-dl-bot");
27
29
  try { fs.mkdirSync(TEMP_DIR, { recursive: true }); } catch (_) { }
28
30
  const OUTPUT_RETENTION_MIN = Number(process.env.OUTPUT_RETENTION_MIN || 5);
@@ -288,6 +290,17 @@ function getPlatformType(url) {
288
290
  async function tryFallbackDownload(url, maxRetries = 3) {
289
291
  const platform = getPlatformType(url);
290
292
 
293
+ // Importações dinâmicas para economizar RAM
294
+ const btch = require("btch-downloader");
295
+ const { igdl, ttdl, fbdown, mediafire, pinterest } = btch;
296
+ const { TwitterDL } = require("twitter-downloader");
297
+ const btchOld = require("btch-downloader-old");
298
+ const Tiktok = require("@tobyg74/tiktok-api-dl");
299
+ const ab = require("ab-downloader");
300
+ const instagramCustom = require('./instagramcustom');
301
+ const tiktokCustom = require('./tiktokcustom');
302
+
303
+
291
304
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
292
305
  try {
293
306
  let videoUrl = null;
@@ -852,8 +865,13 @@ async function downloadSmartVideo(url, config) {
852
865
  let videoUrl = null;
853
866
  let platform = getPlatformType(url);
854
867
 
868
+ // Importações dinâmicas por plataforma para economizar RAM
869
+ let downloader = null;
870
+
871
+
855
872
  switch (platform) {
856
873
  case "instagram": {
874
+ const { igdl } = require("btch-downloader");
857
875
  let data = null;
858
876
  let attempts = 0;
859
877
  const maxAttempts = 3;
@@ -874,6 +892,7 @@ async function downloadSmartVideo(url, config) {
874
892
  await new Promise(resolve => setTimeout(resolve, 1000 * attempts));
875
893
  }
876
894
  }
895
+
877
896
  if (!videoUrl) {
878
897
  throw new Error("Video unavailable or invalid link for Instagram.");
879
898
  }
@@ -882,6 +901,8 @@ async function downloadSmartVideo(url, config) {
882
901
  case "tiktok": {
883
902
  let data = null;
884
903
  let fallbackError = null;
904
+ const { ttdl } = require("btch-downloader");
905
+ const Tiktok = require("@tobyg74/tiktok-api-dl");
885
906
  try {
886
907
  data = await ttdl(url);
887
908
  if (!data || !data.video || !data.video[0]) {
@@ -925,7 +946,10 @@ async function downloadSmartVideo(url, config) {
925
946
  }
926
947
  break;
927
948
  }
949
+
950
+
928
951
  case "facebook": {
952
+ const { fbdown } = require("btch-downloader");
929
953
  try {
930
954
  const data = await fbdown(url);
931
955
  if (!data || (!data.Normal_video && !data.HD)) {
@@ -949,7 +973,9 @@ async function downloadSmartVideo(url, config) {
949
973
  }
950
974
  break;
951
975
  }
976
+
952
977
  case "mediafire": {
978
+ const { mediafire } = require("btch-downloader");
953
979
  try {
954
980
  const data = await mediafire(url);
955
981
  if (!data || !data.url) {
@@ -961,7 +987,9 @@ async function downloadSmartVideo(url, config) {
961
987
  }
962
988
  break;
963
989
  }
990
+
964
991
  case "pinterest": {
992
+ const { pinterest } = require("btch-downloader");
965
993
  try {
966
994
  const data = await pinterest(url);
967
995
  let directUrl = null;
@@ -1004,7 +1032,9 @@ async function downloadSmartVideo(url, config) {
1004
1032
  }
1005
1033
  break;
1006
1034
  }
1035
+
1007
1036
  case "twitter": {
1037
+ const { twitter } = require("btch-downloader");
1008
1038
  try {
1009
1039
  const data = await twitter(url);
1010
1040
  if (data && data.url) {
@@ -1049,6 +1079,7 @@ async function downloadSmartVideo(url, config) {
1049
1079
  }
1050
1080
  break;
1051
1081
  }
1082
+
1052
1083
  default:
1053
1084
  throw new Error("Platform not supported or invalid link.");
1054
1085
  }
@@ -1078,7 +1109,9 @@ async function downloadSmartVideo(url, config) {
1078
1109
  videoWriter.on("finish", async () => {
1079
1110
  try {
1080
1111
  const finalFilePath = await processDownloadedFile(fileName, config, platform);
1112
+ triggerGC(); // Limpar memória após processamento pesado
1081
1113
  resolve(finalFilePath);
1114
+
1082
1115
  } catch (error) {
1083
1116
  reject(new Error(`Error processing downloaded video: ${error.message}`));
1084
1117
  }
@@ -1092,6 +1125,7 @@ async function downloadSmartVideo(url, config) {
1092
1125
  }
1093
1126
  }
1094
1127
 
1128
+
1095
1129
  // Function for direct video download
1096
1130
  async function downloadDirectVideo(url, config) {
1097
1131
  try {
@@ -1183,6 +1217,7 @@ async function rotateVideo(fileName, rotation) {
1183
1217
  return new Promise((resolve, reject) => {
1184
1218
  ffmpeg(fileName)
1185
1219
  .videoFilters(angle)
1220
+ .audioCodec('copy')
1186
1221
  .output(outputPath)
1187
1222
  .on('end', async () => {
1188
1223
  await safeUnlinkWithRetry(fileName);
@@ -1231,7 +1266,9 @@ async function cleanupTempFiles() {
1231
1266
  for (const file of tempFiles) {
1232
1267
  await safeUnlinkWithRetry(path.join(TEMP_DIR, file));
1233
1268
  }
1269
+ triggerGC();
1234
1270
  } catch (error) {
1271
+
1235
1272
  if (error && error.code !== 'ENOENT') {
1236
1273
  console.error(`Error during temp file cleanup: ${error.message}`);
1237
1274
  }
@@ -1256,9 +1293,11 @@ async function cleanupOutputFiles() {
1256
1293
  }
1257
1294
  } catch (_) { }
1258
1295
  }
1296
+ triggerGC();
1259
1297
  } catch (_) { }
1260
1298
  }
1261
1299
 
1300
+
1262
1301
  // Schedule periodic cleanup (every 10 minutes)
1263
1302
  setInterval(() => {
1264
1303
  cleanupTempFiles();
@@ -1291,6 +1330,7 @@ async function autoCrop(fileName) {
1291
1330
  }
1292
1331
  ffmpeg(inputPath)
1293
1332
  .outputOptions('-vf', cropValues)
1333
+ .audioCodec('copy')
1294
1334
  .output(outputPath)
1295
1335
  .on('end', async () => {
1296
1336
  await safeUnlinkWithRetry(inputPath);
@@ -1326,6 +1366,7 @@ async function checkAndCompressVideo(filePath, limitSizeMB, platform = null) {
1326
1366
  '-crf', '28',
1327
1367
  '-preset', 'slow'
1328
1368
  )
1369
+ .audioCodec('aac')
1329
1370
  .output(outputPath)
1330
1371
  .on('end', async () => {
1331
1372
  await safeUnlinkWithRetry(filePath);
@@ -1500,7 +1541,9 @@ const AudioDownloader = async (url, options = {}) => {
1500
1541
  await safeUnlinkWithRetry(downloadedFilePath);
1501
1542
 
1502
1543
  const result = await uploadToGoFileIfNeeded(audioFilePath);
1544
+ triggerGC();
1503
1545
  return result;
1546
+
1504
1547
  } else {
1505
1548
  throw new Error("Failed to obtain downloaded file path.");
1506
1549
  }
@@ -1522,8 +1565,10 @@ async function extractAudioMp3(videoPath) {
1522
1565
  .format('mp3')
1523
1566
  .save(audioPath)
1524
1567
  .on('end', () => {
1568
+ triggerGC();
1525
1569
  resolve(audioPath);
1526
1570
  })
1571
+
1527
1572
  .on('error', (err) => {
1528
1573
  reject(new Error(`Error extracting audio: ${err.message}`));
1529
1574
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frostpv",
3
- "version": "1.0.21",
3
+ "version": "1.0.24",
4
4
  "description": "downloads",
5
5
  "main": "index.js",
6
6
  "scripts": {