@doedja/scenecut 1.0.0
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/README.md +280 -0
- package/bin/cli.js +293 -0
- package/dist/decoder/ffmpeg-decoder.d.ts +50 -0
- package/dist/decoder/ffmpeg-decoder.d.ts.map +1 -0
- package/dist/decoder/ffmpeg-decoder.js +269 -0
- package/dist/decoder/ffmpeg-decoder.js.map +1 -0
- package/dist/decoder/frame-buffer.d.ts +81 -0
- package/dist/decoder/frame-buffer.d.ts.map +1 -0
- package/dist/decoder/frame-buffer.js +123 -0
- package/dist/decoder/frame-buffer.js.map +1 -0
- package/dist/detection/detector.d.ts +19 -0
- package/dist/detection/detector.d.ts.map +1 -0
- package/dist/detection/detector.js +126 -0
- package/dist/detection/detector.js.map +1 -0
- package/dist/detection/wasm-bridge.d.ts +82 -0
- package/dist/detection/wasm-bridge.d.ts.map +1 -0
- package/dist/detection/wasm-bridge.js +182 -0
- package/dist/detection/wasm-bridge.js.map +1 -0
- package/dist/detection.wasm.js +2 -0
- package/dist/detection.wasm.wasm +0 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/keyframes.cjs.js +985 -0
- package/dist/keyframes.cjs.js.map +1 -0
- package/dist/keyframes.esm.js +946 -0
- package/dist/keyframes.esm.js.map +1 -0
- package/dist/types/index.d.ts +225 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/buffer-pool.d.ts +44 -0
- package/dist/utils/buffer-pool.d.ts.map +1 -0
- package/dist/utils/buffer-pool.js +81 -0
- package/dist/utils/buffer-pool.js.map +1 -0
- package/dist/utils/frame-processor.d.ts +48 -0
- package/dist/utils/frame-processor.d.ts.map +1 -0
- package/dist/utils/frame-processor.js +112 -0
- package/dist/utils/frame-processor.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frame Processor - Utilities for frame preprocessing
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format timestamp as timecode (HH:MM:SS.mmm)
|
|
6
|
+
*/
|
|
7
|
+
export function formatTimecode(seconds) {
|
|
8
|
+
const hours = Math.floor(seconds / 3600);
|
|
9
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
10
|
+
const secs = Math.floor(seconds % 60);
|
|
11
|
+
const ms = Math.floor((seconds % 1) * 1000);
|
|
12
|
+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Calculate macroblock parameters for frame dimensions
|
|
16
|
+
*/
|
|
17
|
+
export function calculateMBParam(width, height) {
|
|
18
|
+
const mb_width = Math.ceil(width / 16);
|
|
19
|
+
const mb_height = Math.ceil(height / 16);
|
|
20
|
+
const edge_size = 64;
|
|
21
|
+
return {
|
|
22
|
+
width,
|
|
23
|
+
height,
|
|
24
|
+
mb_width,
|
|
25
|
+
mb_height,
|
|
26
|
+
edged_width: 16 * mb_width + 2 * edge_size,
|
|
27
|
+
edged_height: 16 * mb_height + 2 * edge_size,
|
|
28
|
+
edge_size
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if frame dimensions are valid
|
|
33
|
+
*/
|
|
34
|
+
export function validateFrameDimensions(width, height) {
|
|
35
|
+
if (width <= 0 || height <= 0) {
|
|
36
|
+
throw new Error(`Invalid frame dimensions: ${width}x${height}`);
|
|
37
|
+
}
|
|
38
|
+
if (width > 8192 || height > 8192) {
|
|
39
|
+
throw new Error(`Frame dimensions too large: ${width}x${height} (max: 8192x8192)`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Calculate fcode from search range option
|
|
44
|
+
*/
|
|
45
|
+
export function calculateFcode(searchRange, width, height) {
|
|
46
|
+
switch (searchRange) {
|
|
47
|
+
case 'small':
|
|
48
|
+
return 2; // 64 pixel range
|
|
49
|
+
case 'medium':
|
|
50
|
+
return 4; // 256 pixel range (default)
|
|
51
|
+
case 'large':
|
|
52
|
+
return 6; // 1024 pixel range
|
|
53
|
+
case 'auto':
|
|
54
|
+
// Auto-adjust based on resolution
|
|
55
|
+
const pixels = width * height;
|
|
56
|
+
if (pixels <= 720 * 480)
|
|
57
|
+
return 3; // SD: 128px
|
|
58
|
+
if (pixels <= 1920 * 1080)
|
|
59
|
+
return 4; // HD: 256px
|
|
60
|
+
return 5; // 4K+: 512px
|
|
61
|
+
default:
|
|
62
|
+
return 4;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Calculate adaptive thresholds based on sensitivity
|
|
67
|
+
*/
|
|
68
|
+
export function calculateThresholds(sensitivity) {
|
|
69
|
+
switch (sensitivity) {
|
|
70
|
+
case 'low':
|
|
71
|
+
return { intraThresh: 3000, intraThresh2: 150 }; // Less sensitive
|
|
72
|
+
case 'medium':
|
|
73
|
+
return { intraThresh: 2000, intraThresh2: 90 }; // Default
|
|
74
|
+
case 'high':
|
|
75
|
+
return { intraThresh: 1000, intraThresh2: 50 }; // More sensitive
|
|
76
|
+
case 'custom':
|
|
77
|
+
// Will be overridden by customThresholds
|
|
78
|
+
return { intraThresh: 2000, intraThresh2: 90 };
|
|
79
|
+
default:
|
|
80
|
+
return { intraThresh: 2000, intraThresh2: 90 };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate frame data
|
|
85
|
+
*/
|
|
86
|
+
export function validateFrame(frame) {
|
|
87
|
+
if (!frame.data || frame.data.length === 0) {
|
|
88
|
+
throw new Error('Frame data is empty');
|
|
89
|
+
}
|
|
90
|
+
const expectedSize = frame.width * frame.height;
|
|
91
|
+
if (frame.data.length < expectedSize) {
|
|
92
|
+
throw new Error(`Frame data size mismatch: expected at least ${expectedSize}, got ${frame.data.length}`);
|
|
93
|
+
}
|
|
94
|
+
validateFrameDimensions(frame.width, frame.height);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Calculate memory usage for frame
|
|
98
|
+
*/
|
|
99
|
+
export function calculateFrameMemory(width, height) {
|
|
100
|
+
const mbParam = calculateMBParam(width, height);
|
|
101
|
+
return mbParam.edged_width * mbParam.edged_height;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Estimate processing time based on frame count and resolution
|
|
105
|
+
*/
|
|
106
|
+
export function estimateProcessingTime(frameCount, width, height, targetFps = 60) {
|
|
107
|
+
// Rough estimate: higher resolution = slower
|
|
108
|
+
const resolutionFactor = (width * height) / (1920 * 1080);
|
|
109
|
+
const adjustedFps = targetFps / resolutionFactor;
|
|
110
|
+
return frameCount / adjustedFps;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=frame-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-processor.js","sourceRoot":"","sources":["../../src/utils/frame-processor.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@doedja/scenecut",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Scene change detection for Node.js using Xvid's motion estimation algorithm",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"scenecut": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/keyframes.esm.js",
|
|
13
|
+
"require": "./dist/keyframes.cjs.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"bin",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build:wasm": "cd src/wasm && bash build.sh",
|
|
25
|
+
"build:ts": "tsc",
|
|
26
|
+
"build:bundle": "rollup -c",
|
|
27
|
+
"build": "npm run build:ts && npm run build:bundle",
|
|
28
|
+
"dev": "tsc --watch",
|
|
29
|
+
"test": "node test-basic.js",
|
|
30
|
+
"test:full": "node test-full.js",
|
|
31
|
+
"lint": "eslint src/**/*.ts",
|
|
32
|
+
"format": "prettier --write \"src/**/*.{ts,js}\"",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"scene-detection",
|
|
37
|
+
"video",
|
|
38
|
+
"keyframe",
|
|
39
|
+
"xvid",
|
|
40
|
+
"ffmpeg",
|
|
41
|
+
"video-processing",
|
|
42
|
+
"motion-estimation",
|
|
43
|
+
"wasm",
|
|
44
|
+
"webassembly"
|
|
45
|
+
],
|
|
46
|
+
"author": "doedja",
|
|
47
|
+
"license": "GPL-2.0",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/doedja/scenecut.git"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/doedja/scenecut/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/doedja/scenecut#readme",
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
58
|
+
"fluent-ffmpeg": "^2.1.2"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
62
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
63
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
64
|
+
"@types/fluent-ffmpeg": "^2.1.24",
|
|
65
|
+
"@types/node": "^20.10.0",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
67
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
68
|
+
"eslint": "^8.56.0",
|
|
69
|
+
"prettier": "^3.1.0",
|
|
70
|
+
"rollup": "^4.9.0",
|
|
71
|
+
"typescript": "^5.3.0",
|
|
72
|
+
"vitest": "^1.0.0"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=18.0.0"
|
|
76
|
+
}
|
|
77
|
+
}
|