@lumy-pack/scene-sieve 0.0.1
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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +948 -0
- package/dist/constants.d.ts +20 -0
- package/dist/core/analyzer.d.ts +29 -0
- package/dist/core/dbscan.d.ts +10 -0
- package/dist/core/extractor.d.ts +7 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/input-resolver.d.ts +13 -0
- package/dist/core/orchestrator.d.ts +2 -0
- package/dist/core/pruner.d.ts +42 -0
- package/dist/core/workspace.d.ts +19 -0
- package/dist/index.cjs +936 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +895 -0
- package/dist/types/index.d.ts +79 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/min-heap.d.ts +16 -0
- package/dist/utils/paths.d.ts +9 -0
- package/package.json +73 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type ProgressPhase = 'EXTRACTING' | 'ANALYZING' | 'PRUNING' | 'FINALIZING';
|
|
2
|
+
export type SieveInput = {
|
|
3
|
+
mode: 'file';
|
|
4
|
+
inputPath: string;
|
|
5
|
+
} | {
|
|
6
|
+
mode: 'buffer';
|
|
7
|
+
inputBuffer: Buffer;
|
|
8
|
+
} | {
|
|
9
|
+
mode: 'frames';
|
|
10
|
+
inputFrames: Buffer[];
|
|
11
|
+
};
|
|
12
|
+
export interface SieveOptionsBase {
|
|
13
|
+
count?: number;
|
|
14
|
+
threshold?: number;
|
|
15
|
+
outputPath?: string;
|
|
16
|
+
fps?: number;
|
|
17
|
+
scale?: number;
|
|
18
|
+
quality?: number;
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
onProgress?: (phase: ProgressPhase, percent: number) => void;
|
|
21
|
+
}
|
|
22
|
+
export type SieveOptions = SieveOptionsBase & SieveInput;
|
|
23
|
+
export interface ResolvedOptions {
|
|
24
|
+
mode: 'file' | 'buffer' | 'frames';
|
|
25
|
+
inputPath?: string;
|
|
26
|
+
count: number;
|
|
27
|
+
threshold?: number;
|
|
28
|
+
pruneMode: 'count' | 'threshold' | 'threshold-with-cap';
|
|
29
|
+
outputPath: string;
|
|
30
|
+
fps: number;
|
|
31
|
+
scale: number;
|
|
32
|
+
quality: number;
|
|
33
|
+
debug: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface SieveResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
originalFramesCount: number;
|
|
38
|
+
prunedFramesCount: number;
|
|
39
|
+
outputFiles: string[];
|
|
40
|
+
outputBuffers?: Buffer[];
|
|
41
|
+
executionTimeMs: number;
|
|
42
|
+
}
|
|
43
|
+
export interface FrameNode {
|
|
44
|
+
id: number;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
extractPath: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ScoreEdge {
|
|
49
|
+
sourceId: number;
|
|
50
|
+
targetId: number;
|
|
51
|
+
/**
|
|
52
|
+
* Information gain score (G(t)) between adjacent frames.
|
|
53
|
+
* Higher values = greater visual change (state transition) = should be preserved.
|
|
54
|
+
* Lower values = similar frames (little change) = candidates for pruning.
|
|
55
|
+
*
|
|
56
|
+
* Pruner removes frames with the LOWEST scores first (greedy ascending).
|
|
57
|
+
* Maps directly to G(t) from the vision analysis pipeline.
|
|
58
|
+
*/
|
|
59
|
+
score: number;
|
|
60
|
+
}
|
|
61
|
+
export interface BoundingBox {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
}
|
|
67
|
+
export interface DBSCANResult {
|
|
68
|
+
labels: number[];
|
|
69
|
+
boundingBoxes: BoundingBox[];
|
|
70
|
+
}
|
|
71
|
+
export interface ProcessContext {
|
|
72
|
+
options: ResolvedOptions;
|
|
73
|
+
workspacePath: string;
|
|
74
|
+
frames: FrameNode[];
|
|
75
|
+
graph: ScoreEdge[];
|
|
76
|
+
status: 'INIT' | ProgressPhase | 'SUCCESS' | 'FAILED';
|
|
77
|
+
emitProgress: (percent: number) => void;
|
|
78
|
+
error?: Error;
|
|
79
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic binary min-heap.
|
|
3
|
+
*
|
|
4
|
+
* Elements are ordered by a numeric `score` field.
|
|
5
|
+
* push/pop: O(log N), size: O(1).
|
|
6
|
+
*/
|
|
7
|
+
export declare class MinHeap<T extends {
|
|
8
|
+
score: number;
|
|
9
|
+
}> {
|
|
10
|
+
private readonly h;
|
|
11
|
+
get size(): number;
|
|
12
|
+
push(entry: T): void;
|
|
13
|
+
pop(): T | undefined;
|
|
14
|
+
private siftUp;
|
|
15
|
+
private siftDown;
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
2
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
3
|
+
export declare function resolveAbsolute(p: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Derive default output directory name from input file path.
|
|
6
|
+
* e.g., /path/to/video.mp4 -> /path/to/video_scenes
|
|
7
|
+
*/
|
|
8
|
+
export declare function deriveOutputPath(inputPath: string): string;
|
|
9
|
+
export declare function isSupportedFile(filePath: string, extensions: string[]): boolean;
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lumy-pack/scene-sieve",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI tool for extracting key frames from video and GIF files",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"video",
|
|
8
|
+
"frames",
|
|
9
|
+
"scene",
|
|
10
|
+
"ffmpeg",
|
|
11
|
+
"opencv"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/vincent-kk/lumy-pack.git",
|
|
16
|
+
"directory": "packages/scene-sieve"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "Vincent K. Kelvin",
|
|
21
|
+
"email": "lunox273@gmail.com"
|
|
22
|
+
},
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"source": "./src/index.ts",
|
|
29
|
+
"import": "./dist/index.mjs",
|
|
30
|
+
"require": "./dist/index.cjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"main": "dist/index.cjs",
|
|
34
|
+
"module": "dist/index.mjs",
|
|
35
|
+
"types": "dist/index.d.ts",
|
|
36
|
+
"bin": "./dist/cli.mjs",
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"!dist/tsconfig.tsbuildinfo"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup && yarn build:types",
|
|
43
|
+
"build:types": "tsc -p ./tsconfig.declarations.json",
|
|
44
|
+
"dev": "tsx src/cli.ts",
|
|
45
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
46
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
47
|
+
"publish:npm": "yarn npm publish --access public",
|
|
48
|
+
"test": "vitest",
|
|
49
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
50
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
51
|
+
"test:run": "vitest run",
|
|
52
|
+
"version:major": "yarn version major",
|
|
53
|
+
"version:minor": "yarn version minor",
|
|
54
|
+
"version:patch": "yarn version patch"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@ffprobe-installer/ffprobe": "^1.4.1",
|
|
58
|
+
"@techstark/opencv-js": "4.12.0-release.1",
|
|
59
|
+
"cli-progress": "^3.12.0",
|
|
60
|
+
"commander": "^12.1.0",
|
|
61
|
+
"ffmpeg-static": "^5.2.0",
|
|
62
|
+
"fluent-ffmpeg": "^2.1.3",
|
|
63
|
+
"ora": "^8.0.0",
|
|
64
|
+
"picocolors": "^1.1.1",
|
|
65
|
+
"sharp": "^0.33.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/cli-progress": "^3.11.6",
|
|
69
|
+
"@types/fluent-ffmpeg": "^2.1.27",
|
|
70
|
+
"@types/node": "^20.11.0",
|
|
71
|
+
"@vitest/coverage-v8": "^3.2.4"
|
|
72
|
+
}
|
|
73
|
+
}
|