@lumy-pack/scene-sieve 0.0.2 → 0.0.4

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/cli.mjs CHANGED
@@ -21,7 +21,8 @@ var logger = {
21
21
  console.log(`${pc.blue("info")} ${message}`);
22
22
  },
23
23
  success(message) {
24
- console.log(`${pc.green("done")} ${message}`);
24
+ console.log(`
25
+ ${pc.green("done")} ${message}`);
25
26
  },
26
27
  warn(message) {
27
28
  console.warn(`${pc.yellow("warn")} ${message}`);
@@ -68,7 +69,7 @@ var DBSCAN_MIN_PTS = 4;
68
69
  var IOU_THRESHOLD = 0.9;
69
70
  var DECAY_LAMBDA = 0.95;
70
71
  var ANIMATION_FRAME_THRESHOLD = 5;
71
- var MATCH_DISTANCE_THRESHOLD = 0.75;
72
+ var MATCH_DISTANCE_THRESHOLD = 0.25;
72
73
  var PIXELDIFF_GAUSSIAN_KERNEL = 3;
73
74
  var PIXELDIFF_BINARY_THRESHOLD = 30;
74
75
  var PIXELDIFF_CONTOUR_MIN_AREA = 100;
@@ -181,7 +182,7 @@ async function ensureOpenCV() {
181
182
  async function preprocessFrame(framePath, scale) {
182
183
  const { data, info } = await sharp(framePath).resize({ width: scale, withoutEnlargement: true }).grayscale().blur(1).raw().toBuffer({ resolveWithObject: true });
183
184
  return {
184
- data: new Uint8Array(data.buffer),
185
+ data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
185
186
  width: info.width,
186
187
  height: info.height
187
188
  };
@@ -262,16 +263,11 @@ var IoUTracker = class {
262
263
  }
263
264
  };
264
265
  async function computeAKAZEDiff(cvLib, frame1, frame2) {
265
- const mat1 = cvLib.matFromImageData({
266
- data: frame1.data,
267
- width: frame1.width,
268
- height: frame1.height
269
- });
270
- const mat2 = cvLib.matFromImageData({
271
- data: frame2.data,
272
- width: frame2.width,
273
- height: frame2.height
274
- });
266
+ const cv = cvLib;
267
+ const mat1 = new cv.Mat(frame1.height, frame1.width, cv.CV_8UC1);
268
+ mat1.data.set(frame1.data);
269
+ const mat2 = new cv.Mat(frame2.height, frame2.width, cv.CV_8UC1);
270
+ mat2.data.set(frame2.data);
275
271
  const kp1 = new cvLib.KeyPointVector();
276
272
  const kp2 = new cvLib.KeyPointVector();
277
273
  const desc1 = new cvLib.Mat();
@@ -512,6 +508,7 @@ import ffmpegPath from "ffmpeg-static";
512
508
 
513
509
  // src/utils/paths.ts
514
510
  import { mkdir, stat } from "fs/promises";
511
+ import { homedir } from "os";
515
512
  import { basename, extname, resolve } from "path";
516
513
  async function ensureDir(dirPath) {
517
514
  await mkdir(dirPath, { recursive: true });
@@ -524,6 +521,16 @@ async function fileExists(filePath) {
524
521
  return false;
525
522
  }
526
523
  }
524
+ function expandTilde(p) {
525
+ if (p === "~") return homedir();
526
+ if (p.startsWith("~/") || p.startsWith("~\\")) {
527
+ return resolve(homedir(), p.slice(2));
528
+ }
529
+ return p;
530
+ }
531
+ function resolveAbsolute(p) {
532
+ return resolve(expandTilde(p));
533
+ }
527
534
  function deriveOutputPath(inputPath) {
528
535
  const dir = resolve(inputPath, "..");
529
536
  const name = basename(inputPath, extname(inputPath));
@@ -658,6 +665,7 @@ async function finalizeOutput(ctx, selectedFrames) {
658
665
  outputFiles.push(join3(outputPath, destName));
659
666
  }
660
667
  await ensureDir(join3(outputPath, ".."));
668
+ await rm(outputPath, { recursive: true, force: true });
661
669
  await rename(stagingDir, outputPath);
662
670
  return outputFiles;
663
671
  }
@@ -698,7 +706,7 @@ async function readFramesAsBuffers(frameNodes, quality) {
698
706
  // src/core/input-resolver.ts
699
707
  function resolveOptions(options) {
700
708
  const mode = options.mode;
701
- const inputPath = mode === "file" ? options.inputPath : void 0;
709
+ const inputPath = mode === "file" ? resolveAbsolute(options.inputPath) : void 0;
702
710
  const outputPath = options.outputPath ?? (inputPath ? deriveOutputPath(inputPath) : join4(process.cwd(), "scene-sieve-output"));
703
711
  const threshold = options.threshold ?? DEFAULT_THRESHOLD;
704
712
  if (threshold <= 0 || threshold > 1) {
@@ -722,7 +730,10 @@ function resolveOptions(options) {
722
730
  }
723
731
  async function resolveInput(options, workspacePath) {
724
732
  if (options.mode === "file") {
725
- return { frames: [], resolvedInputPath: options.inputPath };
733
+ return {
734
+ frames: [],
735
+ resolvedInputPath: resolveAbsolute(options.inputPath)
736
+ };
726
737
  }
727
738
  if (options.mode === "buffer") {
728
739
  const resolvedInputPath = await writeInputBuffer(
@@ -18,7 +18,7 @@ export declare const DBSCAN_MIN_PTS = 4;
18
18
  export declare const IOU_THRESHOLD = 0.9;
19
19
  export declare const DECAY_LAMBDA = 0.95;
20
20
  export declare const ANIMATION_FRAME_THRESHOLD = 5;
21
- export declare const MATCH_DISTANCE_THRESHOLD = 0.75;
21
+ export declare const MATCH_DISTANCE_THRESHOLD = 0.25;
22
22
  export declare const PIXELDIFF_GAUSSIAN_KERNEL = 3;
23
23
  export declare const PIXELDIFF_BINARY_THRESHOLD = 30;
24
24
  export declare const PIXELDIFF_CONTOUR_MIN_AREA = 100;
package/dist/index.cjs CHANGED
@@ -55,7 +55,8 @@ var logger = {
55
55
  console.log(`${import_picocolors.default.blue("info")} ${message}`);
56
56
  },
57
57
  success(message) {
58
- console.log(`${import_picocolors.default.green("done")} ${message}`);
58
+ console.log(`
59
+ ${import_picocolors.default.green("done")} ${message}`);
59
60
  },
60
61
  warn(message) {
61
62
  console.warn(`${import_picocolors.default.yellow("warn")} ${message}`);
@@ -102,7 +103,7 @@ var DBSCAN_MIN_PTS = 4;
102
103
  var IOU_THRESHOLD = 0.9;
103
104
  var DECAY_LAMBDA = 0.95;
104
105
  var ANIMATION_FRAME_THRESHOLD = 5;
105
- var MATCH_DISTANCE_THRESHOLD = 0.75;
106
+ var MATCH_DISTANCE_THRESHOLD = 0.25;
106
107
  var PIXELDIFF_GAUSSIAN_KERNEL = 3;
107
108
  var PIXELDIFF_BINARY_THRESHOLD = 30;
108
109
  var PIXELDIFF_CONTOUR_MIN_AREA = 100;
@@ -215,7 +216,7 @@ async function ensureOpenCV() {
215
216
  async function preprocessFrame(framePath, scale) {
216
217
  const { data, info } = await (0, import_sharp.default)(framePath).resize({ width: scale, withoutEnlargement: true }).grayscale().blur(1).raw().toBuffer({ resolveWithObject: true });
217
218
  return {
218
- data: new Uint8Array(data.buffer),
219
+ data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
219
220
  width: info.width,
220
221
  height: info.height
221
222
  };
@@ -296,16 +297,11 @@ var IoUTracker = class {
296
297
  }
297
298
  };
298
299
  async function computeAKAZEDiff(cvLib, frame1, frame2) {
299
- const mat1 = cvLib.matFromImageData({
300
- data: frame1.data,
301
- width: frame1.width,
302
- height: frame1.height
303
- });
304
- const mat2 = cvLib.matFromImageData({
305
- data: frame2.data,
306
- width: frame2.width,
307
- height: frame2.height
308
- });
300
+ const cv = cvLib;
301
+ const mat1 = new cv.Mat(frame1.height, frame1.width, cv.CV_8UC1);
302
+ mat1.data.set(frame1.data);
303
+ const mat2 = new cv.Mat(frame2.height, frame2.width, cv.CV_8UC1);
304
+ mat2.data.set(frame2.data);
309
305
  const kp1 = new cvLib.KeyPointVector();
310
306
  const kp2 = new cvLib.KeyPointVector();
311
307
  const desc1 = new cvLib.Mat();
@@ -546,6 +542,7 @@ var import_ffmpeg_static = __toESM(require("ffmpeg-static"), 1);
546
542
 
547
543
  // src/utils/paths.ts
548
544
  var import_promises = require("fs/promises");
545
+ var import_node_os2 = require("os");
549
546
  var import_node_path2 = require("path");
550
547
  async function ensureDir(dirPath) {
551
548
  await (0, import_promises.mkdir)(dirPath, { recursive: true });
@@ -558,6 +555,16 @@ async function fileExists(filePath) {
558
555
  return false;
559
556
  }
560
557
  }
558
+ function expandTilde(p) {
559
+ if (p === "~") return (0, import_node_os2.homedir)();
560
+ if (p.startsWith("~/") || p.startsWith("~\\")) {
561
+ return (0, import_node_path2.resolve)((0, import_node_os2.homedir)(), p.slice(2));
562
+ }
563
+ return p;
564
+ }
565
+ function resolveAbsolute(p) {
566
+ return (0, import_node_path2.resolve)(expandTilde(p));
567
+ }
561
568
  function deriveOutputPath(inputPath) {
562
569
  const dir = (0, import_node_path2.resolve)(inputPath, "..");
563
570
  const name = (0, import_node_path2.basename)(inputPath, (0, import_node_path2.extname)(inputPath));
@@ -692,6 +699,7 @@ async function finalizeOutput(ctx, selectedFrames) {
692
699
  outputFiles.push((0, import_node_path4.join)(outputPath, destName));
693
700
  }
694
701
  await ensureDir((0, import_node_path4.join)(outputPath, ".."));
702
+ await (0, import_promises3.rm)(outputPath, { recursive: true, force: true });
695
703
  await (0, import_promises3.rename)(stagingDir, outputPath);
696
704
  return outputFiles;
697
705
  }
@@ -732,7 +740,7 @@ async function readFramesAsBuffers(frameNodes, quality) {
732
740
  // src/core/input-resolver.ts
733
741
  function resolveOptions(options) {
734
742
  const mode = options.mode;
735
- const inputPath = mode === "file" ? options.inputPath : void 0;
743
+ const inputPath = mode === "file" ? resolveAbsolute(options.inputPath) : void 0;
736
744
  const outputPath = options.outputPath ?? (inputPath ? deriveOutputPath(inputPath) : (0, import_node_path5.join)(process.cwd(), "scene-sieve-output"));
737
745
  const threshold = options.threshold ?? DEFAULT_THRESHOLD;
738
746
  if (threshold <= 0 || threshold > 1) {
@@ -756,7 +764,10 @@ function resolveOptions(options) {
756
764
  }
757
765
  async function resolveInput(options, workspacePath) {
758
766
  if (options.mode === "file") {
759
- return { frames: [], resolvedInputPath: options.inputPath };
767
+ return {
768
+ frames: [],
769
+ resolvedInputPath: resolveAbsolute(options.inputPath)
770
+ };
760
771
  }
761
772
  if (options.mode === "buffer") {
762
773
  const resolvedInputPath = await writeInputBuffer(
package/dist/index.mjs CHANGED
@@ -15,7 +15,8 @@ var logger = {
15
15
  console.log(`${pc.blue("info")} ${message}`);
16
16
  },
17
17
  success(message) {
18
- console.log(`${pc.green("done")} ${message}`);
18
+ console.log(`
19
+ ${pc.green("done")} ${message}`);
19
20
  },
20
21
  warn(message) {
21
22
  console.warn(`${pc.yellow("warn")} ${message}`);
@@ -62,7 +63,7 @@ var DBSCAN_MIN_PTS = 4;
62
63
  var IOU_THRESHOLD = 0.9;
63
64
  var DECAY_LAMBDA = 0.95;
64
65
  var ANIMATION_FRAME_THRESHOLD = 5;
65
- var MATCH_DISTANCE_THRESHOLD = 0.75;
66
+ var MATCH_DISTANCE_THRESHOLD = 0.25;
66
67
  var PIXELDIFF_GAUSSIAN_KERNEL = 3;
67
68
  var PIXELDIFF_BINARY_THRESHOLD = 30;
68
69
  var PIXELDIFF_CONTOUR_MIN_AREA = 100;
@@ -175,7 +176,7 @@ async function ensureOpenCV() {
175
176
  async function preprocessFrame(framePath, scale) {
176
177
  const { data, info } = await sharp(framePath).resize({ width: scale, withoutEnlargement: true }).grayscale().blur(1).raw().toBuffer({ resolveWithObject: true });
177
178
  return {
178
- data: new Uint8Array(data.buffer),
179
+ data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
179
180
  width: info.width,
180
181
  height: info.height
181
182
  };
@@ -256,16 +257,11 @@ var IoUTracker = class {
256
257
  }
257
258
  };
258
259
  async function computeAKAZEDiff(cvLib, frame1, frame2) {
259
- const mat1 = cvLib.matFromImageData({
260
- data: frame1.data,
261
- width: frame1.width,
262
- height: frame1.height
263
- });
264
- const mat2 = cvLib.matFromImageData({
265
- data: frame2.data,
266
- width: frame2.width,
267
- height: frame2.height
268
- });
260
+ const cv = cvLib;
261
+ const mat1 = new cv.Mat(frame1.height, frame1.width, cv.CV_8UC1);
262
+ mat1.data.set(frame1.data);
263
+ const mat2 = new cv.Mat(frame2.height, frame2.width, cv.CV_8UC1);
264
+ mat2.data.set(frame2.data);
269
265
  const kp1 = new cvLib.KeyPointVector();
270
266
  const kp2 = new cvLib.KeyPointVector();
271
267
  const desc1 = new cvLib.Mat();
@@ -506,6 +502,7 @@ import ffmpegPath from "ffmpeg-static";
506
502
 
507
503
  // src/utils/paths.ts
508
504
  import { mkdir, stat } from "fs/promises";
505
+ import { homedir } from "os";
509
506
  import { basename, extname, resolve } from "path";
510
507
  async function ensureDir(dirPath) {
511
508
  await mkdir(dirPath, { recursive: true });
@@ -518,6 +515,16 @@ async function fileExists(filePath) {
518
515
  return false;
519
516
  }
520
517
  }
518
+ function expandTilde(p) {
519
+ if (p === "~") return homedir();
520
+ if (p.startsWith("~/") || p.startsWith("~\\")) {
521
+ return resolve(homedir(), p.slice(2));
522
+ }
523
+ return p;
524
+ }
525
+ function resolveAbsolute(p) {
526
+ return resolve(expandTilde(p));
527
+ }
521
528
  function deriveOutputPath(inputPath) {
522
529
  const dir = resolve(inputPath, "..");
523
530
  const name = basename(inputPath, extname(inputPath));
@@ -652,6 +659,7 @@ async function finalizeOutput(ctx, selectedFrames) {
652
659
  outputFiles.push(join3(outputPath, destName));
653
660
  }
654
661
  await ensureDir(join3(outputPath, ".."));
662
+ await rm(outputPath, { recursive: true, force: true });
655
663
  await rename(stagingDir, outputPath);
656
664
  return outputFiles;
657
665
  }
@@ -692,7 +700,7 @@ async function readFramesAsBuffers(frameNodes, quality) {
692
700
  // src/core/input-resolver.ts
693
701
  function resolveOptions(options) {
694
702
  const mode = options.mode;
695
- const inputPath = mode === "file" ? options.inputPath : void 0;
703
+ const inputPath = mode === "file" ? resolveAbsolute(options.inputPath) : void 0;
696
704
  const outputPath = options.outputPath ?? (inputPath ? deriveOutputPath(inputPath) : join4(process.cwd(), "scene-sieve-output"));
697
705
  const threshold = options.threshold ?? DEFAULT_THRESHOLD;
698
706
  if (threshold <= 0 || threshold > 1) {
@@ -716,7 +724,10 @@ function resolveOptions(options) {
716
724
  }
717
725
  async function resolveInput(options, workspacePath) {
718
726
  if (options.mode === "file") {
719
- return { frames: [], resolvedInputPath: options.inputPath };
727
+ return {
728
+ frames: [],
729
+ resolvedInputPath: resolveAbsolute(options.inputPath)
730
+ };
720
731
  }
721
732
  if (options.mode === "buffer") {
722
733
  const resolvedInputPath = await writeInputBuffer(
@@ -1,5 +1,15 @@
1
1
  export declare function ensureDir(dirPath: string): Promise<void>;
2
2
  export declare function fileExists(filePath: string): Promise<boolean>;
3
+ /**
4
+ * Expand leading ~ to homedir. Node's path.resolve() does not expand ~,
5
+ * so paths like ~/Desktop/foo depend on process.cwd() and can produce
6
+ * different results when run from different directories.
7
+ */
8
+ export declare function expandTilde(p: string): string;
9
+ /**
10
+ * Resolve path to absolute. Expands ~ to homedir first so that the result
11
+ * does not depend on process.cwd().
12
+ */
3
13
  export declare function resolveAbsolute(p: string): string;
4
14
  /**
5
15
  * Derive default output directory name from input file path.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumy-pack/scene-sieve",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "CLI tool for extracting key frames from video and GIF files",
5
5
  "keywords": [
6
6
  "cli",