koztv-blog-tools 1.3.1 → 1.3.3
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/dist/node.d.mts +2 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +62 -1
- package/dist/node.mjs +62 -1
- package/package.json +1 -1
package/dist/node.d.mts
CHANGED
|
@@ -27,6 +27,8 @@ interface TelegramExportOptions {
|
|
|
27
27
|
downloadMedia?: boolean;
|
|
28
28
|
/** Skip posts that already have markdown files */
|
|
29
29
|
skipExisting?: boolean;
|
|
30
|
+
/** Compress large videos and skip files over 95MB (requires ffmpeg) */
|
|
31
|
+
compressMedia?: boolean;
|
|
30
32
|
/** Number of concurrent media downloads */
|
|
31
33
|
mediaWorkers?: number;
|
|
32
34
|
/** Callback for progress updates */
|
package/dist/node.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ interface TelegramExportOptions {
|
|
|
27
27
|
downloadMedia?: boolean;
|
|
28
28
|
/** Skip posts that already have markdown files */
|
|
29
29
|
skipExisting?: boolean;
|
|
30
|
+
/** Compress large videos and skip files over 95MB (requires ffmpeg) */
|
|
31
|
+
compressMedia?: boolean;
|
|
30
32
|
/** Number of concurrent media downloads */
|
|
31
33
|
mediaWorkers?: number;
|
|
32
34
|
/** Callback for progress updates */
|
package/dist/node.js
CHANGED
|
@@ -375,6 +375,30 @@ var import_sessions = require("telegram/sessions/index.js");
|
|
|
375
375
|
var fs = __toESM(require("fs"));
|
|
376
376
|
var path = __toESM(require("path"));
|
|
377
377
|
var readline = __toESM(require("readline"));
|
|
378
|
+
var import_child_process = require("child_process");
|
|
379
|
+
var MAX_FILE_SIZE = 95 * 1024 * 1024;
|
|
380
|
+
var COMPRESS_THRESHOLD = 50 * 1024 * 1024;
|
|
381
|
+
function hasFFmpeg() {
|
|
382
|
+
try {
|
|
383
|
+
(0, import_child_process.execSync)("ffmpeg -version", { stdio: "ignore" });
|
|
384
|
+
return true;
|
|
385
|
+
} catch {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function compressVideo(inputPath, outputPath) {
|
|
390
|
+
try {
|
|
391
|
+
(0, import_child_process.execSync)(
|
|
392
|
+
`ffmpeg -i "${inputPath}" -vf "scale='min(1280,iw)':'-2'" -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 128k -y "${outputPath}"`,
|
|
393
|
+
{ stdio: "ignore", timeout: 3e5 }
|
|
394
|
+
// 5 min timeout
|
|
395
|
+
);
|
|
396
|
+
const stats = fs.statSync(outputPath);
|
|
397
|
+
return stats.size <= MAX_FILE_SIZE;
|
|
398
|
+
} catch {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
378
402
|
function entitiesToMarkdown(text, entities) {
|
|
379
403
|
if (!entities || entities.length === 0) return text;
|
|
380
404
|
const mergedEntities = [];
|
|
@@ -515,6 +539,7 @@ async function exportTelegramChannel(options) {
|
|
|
515
539
|
until,
|
|
516
540
|
downloadMedia = true,
|
|
517
541
|
skipExisting = false,
|
|
542
|
+
compressMedia = false,
|
|
518
543
|
mediaWorkers = 3,
|
|
519
544
|
onProgress,
|
|
520
545
|
onPhoneNumber = () => defaultReadline("Phone number: "),
|
|
@@ -655,7 +680,43 @@ async function exportTelegramChannel(options) {
|
|
|
655
680
|
const mediaFileName = `media${ext}`;
|
|
656
681
|
const mediaPath = path.join(postMediaDir, mediaFileName);
|
|
657
682
|
fs.writeFileSync(mediaPath, buffer);
|
|
658
|
-
|
|
683
|
+
if (compressMedia) {
|
|
684
|
+
const stats = fs.statSync(mediaPath);
|
|
685
|
+
const isVideo = [".mp4", ".mov", ".avi", ".webm", ".m4v"].includes(ext.toLowerCase());
|
|
686
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
687
|
+
if (isVideo && hasFFmpeg()) {
|
|
688
|
+
const compressedPath = path.join(postMediaDir, `media_compressed${ext}`);
|
|
689
|
+
if (compressVideo(mediaPath, compressedPath)) {
|
|
690
|
+
fs.unlinkSync(mediaPath);
|
|
691
|
+
fs.renameSync(compressedPath, mediaPath);
|
|
692
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
693
|
+
} else {
|
|
694
|
+
fs.unlinkSync(mediaPath);
|
|
695
|
+
if (fs.existsSync(compressedPath)) fs.unlinkSync(compressedPath);
|
|
696
|
+
console.warn(`Skipping large media for message ${msgId} (>${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
697
|
+
}
|
|
698
|
+
} else {
|
|
699
|
+
fs.unlinkSync(mediaPath);
|
|
700
|
+
console.warn(`Skipping large media for message ${msgId} (>${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
701
|
+
}
|
|
702
|
+
} else if (stats.size > COMPRESS_THRESHOLD && isVideo && hasFFmpeg()) {
|
|
703
|
+
const compressedPath = path.join(postMediaDir, `media_compressed${ext}`);
|
|
704
|
+
if (compressVideo(mediaPath, compressedPath)) {
|
|
705
|
+
const compressedStats = fs.statSync(compressedPath);
|
|
706
|
+
if (compressedStats.size < stats.size) {
|
|
707
|
+
fs.unlinkSync(mediaPath);
|
|
708
|
+
fs.renameSync(compressedPath, mediaPath);
|
|
709
|
+
} else {
|
|
710
|
+
fs.unlinkSync(compressedPath);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
714
|
+
} else {
|
|
715
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
716
|
+
}
|
|
717
|
+
} else {
|
|
718
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
719
|
+
}
|
|
659
720
|
}
|
|
660
721
|
} catch (e) {
|
|
661
722
|
console.error(`Error downloading media for message ${msgId}:`, e);
|
package/dist/node.mjs
CHANGED
|
@@ -25,6 +25,30 @@ import { StringSession } from "telegram/sessions/index.js";
|
|
|
25
25
|
import * as fs from "fs";
|
|
26
26
|
import * as path from "path";
|
|
27
27
|
import * as readline from "readline";
|
|
28
|
+
import { execSync } from "child_process";
|
|
29
|
+
var MAX_FILE_SIZE = 95 * 1024 * 1024;
|
|
30
|
+
var COMPRESS_THRESHOLD = 50 * 1024 * 1024;
|
|
31
|
+
function hasFFmpeg() {
|
|
32
|
+
try {
|
|
33
|
+
execSync("ffmpeg -version", { stdio: "ignore" });
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function compressVideo(inputPath, outputPath) {
|
|
40
|
+
try {
|
|
41
|
+
execSync(
|
|
42
|
+
`ffmpeg -i "${inputPath}" -vf "scale='min(1280,iw)':'-2'" -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 128k -y "${outputPath}"`,
|
|
43
|
+
{ stdio: "ignore", timeout: 3e5 }
|
|
44
|
+
// 5 min timeout
|
|
45
|
+
);
|
|
46
|
+
const stats = fs.statSync(outputPath);
|
|
47
|
+
return stats.size <= MAX_FILE_SIZE;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
28
52
|
function entitiesToMarkdown(text, entities) {
|
|
29
53
|
if (!entities || entities.length === 0) return text;
|
|
30
54
|
const mergedEntities = [];
|
|
@@ -165,6 +189,7 @@ async function exportTelegramChannel(options) {
|
|
|
165
189
|
until,
|
|
166
190
|
downloadMedia = true,
|
|
167
191
|
skipExisting = false,
|
|
192
|
+
compressMedia = false,
|
|
168
193
|
mediaWorkers = 3,
|
|
169
194
|
onProgress,
|
|
170
195
|
onPhoneNumber = () => defaultReadline("Phone number: "),
|
|
@@ -305,7 +330,43 @@ async function exportTelegramChannel(options) {
|
|
|
305
330
|
const mediaFileName = `media${ext}`;
|
|
306
331
|
const mediaPath = path.join(postMediaDir, mediaFileName);
|
|
307
332
|
fs.writeFileSync(mediaPath, buffer);
|
|
308
|
-
|
|
333
|
+
if (compressMedia) {
|
|
334
|
+
const stats = fs.statSync(mediaPath);
|
|
335
|
+
const isVideo = [".mp4", ".mov", ".avi", ".webm", ".m4v"].includes(ext.toLowerCase());
|
|
336
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
337
|
+
if (isVideo && hasFFmpeg()) {
|
|
338
|
+
const compressedPath = path.join(postMediaDir, `media_compressed${ext}`);
|
|
339
|
+
if (compressVideo(mediaPath, compressedPath)) {
|
|
340
|
+
fs.unlinkSync(mediaPath);
|
|
341
|
+
fs.renameSync(compressedPath, mediaPath);
|
|
342
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
343
|
+
} else {
|
|
344
|
+
fs.unlinkSync(mediaPath);
|
|
345
|
+
if (fs.existsSync(compressedPath)) fs.unlinkSync(compressedPath);
|
|
346
|
+
console.warn(`Skipping large media for message ${msgId} (>${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
fs.unlinkSync(mediaPath);
|
|
350
|
+
console.warn(`Skipping large media for message ${msgId} (>${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
351
|
+
}
|
|
352
|
+
} else if (stats.size > COMPRESS_THRESHOLD && isVideo && hasFFmpeg()) {
|
|
353
|
+
const compressedPath = path.join(postMediaDir, `media_compressed${ext}`);
|
|
354
|
+
if (compressVideo(mediaPath, compressedPath)) {
|
|
355
|
+
const compressedStats = fs.statSync(compressedPath);
|
|
356
|
+
if (compressedStats.size < stats.size) {
|
|
357
|
+
fs.unlinkSync(mediaPath);
|
|
358
|
+
fs.renameSync(compressedPath, mediaPath);
|
|
359
|
+
} else {
|
|
360
|
+
fs.unlinkSync(compressedPath);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
364
|
+
} else {
|
|
365
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
mediaFiles.push(`media/${paddedId}/${mediaFileName}`);
|
|
369
|
+
}
|
|
309
370
|
}
|
|
310
371
|
} catch (e) {
|
|
311
372
|
console.error(`Error downloading media for message ${msgId}:`, e);
|