@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,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Bridge - Interface between JavaScript and WebAssembly
|
|
3
|
+
*
|
|
4
|
+
* This module handles:
|
|
5
|
+
* - Loading the WASM module
|
|
6
|
+
* - Memory allocation and management
|
|
7
|
+
* - Calling WASM functions
|
|
8
|
+
* - Data marshalling between JS and WASM
|
|
9
|
+
*/
|
|
10
|
+
import { RawFrame } from '../types';
|
|
11
|
+
export declare class WasmBridge {
|
|
12
|
+
private module;
|
|
13
|
+
private initialized;
|
|
14
|
+
private prevFramePtr;
|
|
15
|
+
private curFramePtr;
|
|
16
|
+
private prevPaddedPtr;
|
|
17
|
+
private curPaddedPtr;
|
|
18
|
+
private allocatedFrameSize;
|
|
19
|
+
private allocatedPaddedSize;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the WASM module
|
|
22
|
+
*/
|
|
23
|
+
init(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Ensure the WASM module is initialized
|
|
26
|
+
*/
|
|
27
|
+
private ensureInitialized;
|
|
28
|
+
/**
|
|
29
|
+
* Pre-allocate WASM buffers for frame processing
|
|
30
|
+
* This eliminates per-frame allocation overhead and reduces memory copies
|
|
31
|
+
*
|
|
32
|
+
* @param width Frame width
|
|
33
|
+
* @param height Frame height
|
|
34
|
+
*/
|
|
35
|
+
allocateBuffers(width: number, height: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* Detect scene change between two frames
|
|
38
|
+
*
|
|
39
|
+
* Uses pre-allocated WASM buffers to eliminate per-frame allocation
|
|
40
|
+
* and reduce memory copies from 3 to 1 per frame.
|
|
41
|
+
*
|
|
42
|
+
* @param prevFrame Previous frame
|
|
43
|
+
* @param curFrame Current frame
|
|
44
|
+
* @param intraCount Number of consecutive non-scene-change frames
|
|
45
|
+
* @param fcode Motion search range parameter (default: 4 = 256 pixels)
|
|
46
|
+
* @returns true if scene change detected, false otherwise
|
|
47
|
+
*/
|
|
48
|
+
detectSceneChange(prevFrame: RawFrame, curFrame: RawFrame, intraCount: number, fcode?: number): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Calculate required buffer size for a padded frame
|
|
51
|
+
*
|
|
52
|
+
* @param width Original frame width
|
|
53
|
+
* @param height Original frame height
|
|
54
|
+
* @returns Required buffer size in bytes
|
|
55
|
+
*/
|
|
56
|
+
calculatePaddedSize(width: number, height: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* Get macroblock parameters for a given frame size
|
|
59
|
+
*
|
|
60
|
+
* @param width Frame width
|
|
61
|
+
* @param height Frame height
|
|
62
|
+
* @returns Macroblock parameters
|
|
63
|
+
*/
|
|
64
|
+
getMBParam(width: number, height: number): {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
mb_width: number;
|
|
68
|
+
mb_height: number;
|
|
69
|
+
edged_width: number;
|
|
70
|
+
edged_height: number;
|
|
71
|
+
edge_size: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Check if the WASM module is initialized
|
|
75
|
+
*/
|
|
76
|
+
isInitialized(): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Clean up resources
|
|
79
|
+
*/
|
|
80
|
+
destroy(): void;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=wasm-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm-bridge.d.ts","sourceRoot":"","sources":["../../src/detection/wasm-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAc,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIhD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,WAAW,CAAkB;IAGrC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,mBAAmB,CAAa;IAExC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;OAMG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA2BpD;;;;;;;;;;;OAWG;IACH,iBAAiB,CACf,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAU,GAChB,OAAO;IAkCV;;;;;;OAMG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAK1D;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;IAgBxC;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,OAAO,IAAI,IAAI;CAmBhB"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Bridge - Interface between JavaScript and WebAssembly
|
|
3
|
+
*
|
|
4
|
+
* This module handles:
|
|
5
|
+
* - Loading the WASM module
|
|
6
|
+
* - Memory allocation and management
|
|
7
|
+
* - Calling WASM functions
|
|
8
|
+
* - Data marshalling between JS and WASM
|
|
9
|
+
*/
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
export class WasmBridge {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.module = null;
|
|
15
|
+
this.initialized = false;
|
|
16
|
+
// Pre-allocated WASM buffers for frame processing
|
|
17
|
+
this.prevFramePtr = 0; // Raw previous frame
|
|
18
|
+
this.curFramePtr = 0; // Raw current frame
|
|
19
|
+
this.prevPaddedPtr = 0; // Padded previous frame
|
|
20
|
+
this.curPaddedPtr = 0; // Padded current frame
|
|
21
|
+
this.allocatedFrameSize = 0; // Size of raw frame buffers
|
|
22
|
+
this.allocatedPaddedSize = 0; // Size of padded frame buffers
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the WASM module
|
|
26
|
+
*/
|
|
27
|
+
async init() {
|
|
28
|
+
if (this.initialized) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// Load the WASM module
|
|
33
|
+
const wasmPath = path.join(__dirname, '../dist/detection.wasm.js');
|
|
34
|
+
if (!fs.existsSync(wasmPath)) {
|
|
35
|
+
throw new Error(`WASM module not found at ${wasmPath}. ` +
|
|
36
|
+
`Please run 'npm run build:wasm' to compile the WASM module.`);
|
|
37
|
+
}
|
|
38
|
+
// Dynamic import the WASM module
|
|
39
|
+
const createWasmModule = require(wasmPath);
|
|
40
|
+
this.module = await createWasmModule();
|
|
41
|
+
this.initialized = true;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`Failed to initialize WASM module: ${error}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Ensure the WASM module is initialized
|
|
49
|
+
*/
|
|
50
|
+
ensureInitialized() {
|
|
51
|
+
if (!this.initialized || !this.module) {
|
|
52
|
+
throw new Error('WASM module not initialized. Call init() first.');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Pre-allocate WASM buffers for frame processing
|
|
57
|
+
* This eliminates per-frame allocation overhead and reduces memory copies
|
|
58
|
+
*
|
|
59
|
+
* @param width Frame width
|
|
60
|
+
* @param height Frame height
|
|
61
|
+
*/
|
|
62
|
+
allocateBuffers(width, height) {
|
|
63
|
+
this.ensureInitialized();
|
|
64
|
+
const frameSize = width * height;
|
|
65
|
+
const paddedSize = this.module._calculate_padded_size(width, height);
|
|
66
|
+
// Allocate or re-allocate raw frame buffers if size changed
|
|
67
|
+
if (frameSize !== this.allocatedFrameSize) {
|
|
68
|
+
if (this.prevFramePtr)
|
|
69
|
+
this.module._free(this.prevFramePtr);
|
|
70
|
+
if (this.curFramePtr)
|
|
71
|
+
this.module._free(this.curFramePtr);
|
|
72
|
+
this.prevFramePtr = this.module._malloc(frameSize);
|
|
73
|
+
this.curFramePtr = this.module._malloc(frameSize);
|
|
74
|
+
this.allocatedFrameSize = frameSize;
|
|
75
|
+
}
|
|
76
|
+
// Allocate or re-allocate padded frame buffers if size changed
|
|
77
|
+
if (paddedSize !== this.allocatedPaddedSize) {
|
|
78
|
+
if (this.prevPaddedPtr)
|
|
79
|
+
this.module._free(this.prevPaddedPtr);
|
|
80
|
+
if (this.curPaddedPtr)
|
|
81
|
+
this.module._free(this.curPaddedPtr);
|
|
82
|
+
this.prevPaddedPtr = this.module._malloc(paddedSize);
|
|
83
|
+
this.curPaddedPtr = this.module._malloc(paddedSize);
|
|
84
|
+
this.allocatedPaddedSize = paddedSize;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Detect scene change between two frames
|
|
89
|
+
*
|
|
90
|
+
* Uses pre-allocated WASM buffers to eliminate per-frame allocation
|
|
91
|
+
* and reduce memory copies from 3 to 1 per frame.
|
|
92
|
+
*
|
|
93
|
+
* @param prevFrame Previous frame
|
|
94
|
+
* @param curFrame Current frame
|
|
95
|
+
* @param intraCount Number of consecutive non-scene-change frames
|
|
96
|
+
* @param fcode Motion search range parameter (default: 4 = 256 pixels)
|
|
97
|
+
* @returns true if scene change detected, false otherwise
|
|
98
|
+
*/
|
|
99
|
+
detectSceneChange(prevFrame, curFrame, intraCount, fcode = 4) {
|
|
100
|
+
this.ensureInitialized();
|
|
101
|
+
// Validate inputs
|
|
102
|
+
if (prevFrame.width !== curFrame.width || prevFrame.height !== curFrame.height) {
|
|
103
|
+
throw new Error('Frame dimensions must match');
|
|
104
|
+
}
|
|
105
|
+
// Ensure buffers are allocated (should be done once at start)
|
|
106
|
+
if (!this.prevFramePtr || this.allocatedFrameSize !== prevFrame.data.length) {
|
|
107
|
+
this.allocateBuffers(prevFrame.width, prevFrame.height);
|
|
108
|
+
}
|
|
109
|
+
// Single copy: Raw frames -> WASM memory (eliminates 2 extra copies)
|
|
110
|
+
this.module.HEAPU8.set(prevFrame.data, this.prevFramePtr);
|
|
111
|
+
this.module.HEAPU8.set(curFrame.data, this.curFramePtr);
|
|
112
|
+
// Pad frames in-place in WASM (no copy back to JS)
|
|
113
|
+
this.module._pad_frame(this.prevFramePtr, this.prevPaddedPtr, prevFrame.width, prevFrame.height);
|
|
114
|
+
this.module._pad_frame(this.curFramePtr, this.curPaddedPtr, curFrame.width, curFrame.height);
|
|
115
|
+
// Run motion estimation on pre-padded buffers
|
|
116
|
+
const result = this.module._MEanalysis_js(this.prevPaddedPtr, this.curPaddedPtr, prevFrame.width, prevFrame.height, intraCount, fcode);
|
|
117
|
+
return result === 1;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Calculate required buffer size for a padded frame
|
|
121
|
+
*
|
|
122
|
+
* @param width Original frame width
|
|
123
|
+
* @param height Original frame height
|
|
124
|
+
* @returns Required buffer size in bytes
|
|
125
|
+
*/
|
|
126
|
+
calculatePaddedSize(width, height) {
|
|
127
|
+
this.ensureInitialized();
|
|
128
|
+
return this.module._calculate_padded_size(width, height);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get macroblock parameters for a given frame size
|
|
132
|
+
*
|
|
133
|
+
* @param width Frame width
|
|
134
|
+
* @param height Frame height
|
|
135
|
+
* @returns Macroblock parameters
|
|
136
|
+
*/
|
|
137
|
+
getMBParam(width, height) {
|
|
138
|
+
const mb_width = Math.ceil(width / 16);
|
|
139
|
+
const mb_height = Math.ceil(height / 16);
|
|
140
|
+
const edge_size = 64;
|
|
141
|
+
return {
|
|
142
|
+
width,
|
|
143
|
+
height,
|
|
144
|
+
mb_width,
|
|
145
|
+
mb_height,
|
|
146
|
+
edged_width: 16 * mb_width + 2 * edge_size,
|
|
147
|
+
edged_height: 16 * mb_height + 2 * edge_size,
|
|
148
|
+
edge_size
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if the WASM module is initialized
|
|
153
|
+
*/
|
|
154
|
+
isInitialized() {
|
|
155
|
+
return this.initialized;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Clean up resources
|
|
159
|
+
*/
|
|
160
|
+
destroy() {
|
|
161
|
+
// Free pre-allocated WASM buffers
|
|
162
|
+
if (this.module) {
|
|
163
|
+
if (this.prevFramePtr)
|
|
164
|
+
this.module._free(this.prevFramePtr);
|
|
165
|
+
if (this.curFramePtr)
|
|
166
|
+
this.module._free(this.curFramePtr);
|
|
167
|
+
if (this.prevPaddedPtr)
|
|
168
|
+
this.module._free(this.prevPaddedPtr);
|
|
169
|
+
if (this.curPaddedPtr)
|
|
170
|
+
this.module._free(this.curPaddedPtr);
|
|
171
|
+
}
|
|
172
|
+
this.prevFramePtr = 0;
|
|
173
|
+
this.curFramePtr = 0;
|
|
174
|
+
this.prevPaddedPtr = 0;
|
|
175
|
+
this.curPaddedPtr = 0;
|
|
176
|
+
this.allocatedFrameSize = 0;
|
|
177
|
+
this.allocatedPaddedSize = 0;
|
|
178
|
+
this.module = null;
|
|
179
|
+
this.initialized = false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=wasm-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm-bridge.js","sourceRoot":"","sources":["../../src/detection/wasm-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var createWasmModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("detection.wasm.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":return HEAP8[ptr];case"i8":return HEAP8[ptr];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP64[ptr>>3];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];case"*":return HEAPU32[ptr>>2];default:abort(`invalid type for getValue: ${type}`)}}var noExitRuntime=true;function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":HEAP8[ptr]=value;break;case"i8":HEAP8[ptr]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":HEAP64[ptr>>3]=BigInt(value);break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;case"*":HEAPU32[ptr>>2]=value;break;default:abort(`invalid type for setValue: ${type}`)}}var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.codePointAt(i);if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["setValue"]=setValue;Module["getValue"]=getValue;var _MEanalysis_js,_free,_calculate_padded_size,_pad_frame,_malloc,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_MEanalysis_js=Module["_MEanalysis_js"]=wasmExports["d"];_free=Module["_free"]=wasmExports["e"];_calculate_padded_size=Module["_calculate_padded_size"]=wasmExports["f"];_pad_frame=Module["_pad_frame"]=wasmExports["g"];_malloc=Module["_malloc"]=wasmExports["h"];__emscripten_stack_restore=wasmExports["i"];__emscripten_stack_alloc=wasmExports["j"];_emscripten_stack_get_current=wasmExports["k"];memory=wasmMemory=wasmExports["b"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={a:_emscripten_resize_heap};function run(){preRun();function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
|
|
2
|
+
;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createWasmModule;module.exports.default=createWasmModule}else if(typeof define==="function"&&define["amd"])define([],()=>createWasmModule);
|
|
Binary file
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* keyframes - Scene change detection for Node.js
|
|
3
|
+
*
|
|
4
|
+
* A JavaScript/TypeScript port of vapoursynth-wwxd using Xvid's motion estimation algorithm.
|
|
5
|
+
* Powered by WebAssembly for high performance.
|
|
6
|
+
*/
|
|
7
|
+
export { SceneDetector } from './detection/detector';
|
|
8
|
+
export { FFmpegDecoder } from './decoder/ffmpeg-decoder';
|
|
9
|
+
export { WasmBridge } from './detection/wasm-bridge';
|
|
10
|
+
export { FrameBuffer } from './decoder/frame-buffer';
|
|
11
|
+
export { BufferPool } from './utils/buffer-pool';
|
|
12
|
+
export type { DetectionOptions, DetectionResult, SceneInfo, VideoMetadata, DetectionStats, Progress, RawFrame, SensitivityLevel, SearchRange, CustomThresholds, TemporalSmoothing, ProgressiveProcessing, FrameExtractionOptions } from './types';
|
|
13
|
+
export { formatTimecode, calculateFcode, calculateThresholds, validateFrame, validateFrameDimensions, calculateMBParam, calculateFrameMemory, estimateProcessingTime } from './utils/frame-processor';
|
|
14
|
+
import { DetectionOptions, DetectionResult } from './types';
|
|
15
|
+
/**
|
|
16
|
+
* Detect scene changes in a video file (simple API)
|
|
17
|
+
*
|
|
18
|
+
* @param videoPath Path to video file
|
|
19
|
+
* @param options Detection options
|
|
20
|
+
* @returns Detection results with scene changes and metadata
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { detectSceneChanges } from 'keyframes';
|
|
25
|
+
*
|
|
26
|
+
* const results = await detectSceneChanges('input.mp4');
|
|
27
|
+
* console.log(`Found ${results.scenes.length} scenes`);
|
|
28
|
+
*
|
|
29
|
+
* results.scenes.forEach(scene => {
|
|
30
|
+
* console.log(`Scene at ${scene.timecode}`);
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectSceneChanges(videoPath: string, options?: DetectionOptions): Promise<DetectionResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Version information
|
|
37
|
+
*/
|
|
38
|
+
export declare const version = "1.0.0";
|
|
39
|
+
/**
|
|
40
|
+
* Library information
|
|
41
|
+
*/
|
|
42
|
+
export declare const info: {
|
|
43
|
+
name: string;
|
|
44
|
+
version: string;
|
|
45
|
+
description: string;
|
|
46
|
+
license: string;
|
|
47
|
+
repository: string;
|
|
48
|
+
author: string;
|
|
49
|
+
credits: {
|
|
50
|
+
original: string;
|
|
51
|
+
algorithm: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;CAWhB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* keyframes - Scene change detection for Node.js
|
|
3
|
+
*
|
|
4
|
+
* A JavaScript/TypeScript port of vapoursynth-wwxd using Xvid's motion estimation algorithm.
|
|
5
|
+
* Powered by WebAssembly for high performance.
|
|
6
|
+
*/
|
|
7
|
+
export { SceneDetector } from './detection/detector';
|
|
8
|
+
export { FFmpegDecoder } from './decoder/ffmpeg-decoder';
|
|
9
|
+
export { WasmBridge } from './detection/wasm-bridge';
|
|
10
|
+
export { FrameBuffer } from './decoder/frame-buffer';
|
|
11
|
+
export { BufferPool } from './utils/buffer-pool';
|
|
12
|
+
// Export utilities
|
|
13
|
+
export { formatTimecode, calculateFcode, calculateThresholds, validateFrame, validateFrameDimensions, calculateMBParam, calculateFrameMemory, estimateProcessingTime } from './utils/frame-processor';
|
|
14
|
+
import { SceneDetector } from './detection/detector';
|
|
15
|
+
/**
|
|
16
|
+
* Detect scene changes in a video file (simple API)
|
|
17
|
+
*
|
|
18
|
+
* @param videoPath Path to video file
|
|
19
|
+
* @param options Detection options
|
|
20
|
+
* @returns Detection results with scene changes and metadata
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { detectSceneChanges } from 'keyframes';
|
|
25
|
+
*
|
|
26
|
+
* const results = await detectSceneChanges('input.mp4');
|
|
27
|
+
* console.log(`Found ${results.scenes.length} scenes`);
|
|
28
|
+
*
|
|
29
|
+
* results.scenes.forEach(scene => {
|
|
30
|
+
* console.log(`Scene at ${scene.timecode}`);
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export async function detectSceneChanges(videoPath, options) {
|
|
35
|
+
const detector = new SceneDetector(options);
|
|
36
|
+
try {
|
|
37
|
+
const results = await detector.detect(videoPath);
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
detector.destroy();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Version information
|
|
46
|
+
*/
|
|
47
|
+
export const version = '1.0.0';
|
|
48
|
+
/**
|
|
49
|
+
* Library information
|
|
50
|
+
*/
|
|
51
|
+
export const info = {
|
|
52
|
+
name: 'keyframes',
|
|
53
|
+
version: '1.0.0',
|
|
54
|
+
description: 'Scene change detection for Node.js using Xvid\'s motion estimation algorithm',
|
|
55
|
+
license: 'GPL-2.0',
|
|
56
|
+
repository: 'https://github.com/yourusername/keyframes',
|
|
57
|
+
author: '',
|
|
58
|
+
credits: {
|
|
59
|
+
original: 'vapoursynth-wwxd by dubhater (https://github.com/dubhater/vapoursynth-wwxd)',
|
|
60
|
+
algorithm: 'Xvid motion estimation (https://www.xvid.com)'
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAmBjD,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,OAA0B;IAE1B,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,OAAO,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,8EAA8E;IAC3F,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,2CAA2C;IACvD,MAAM,EAAE,EAAE;IACV,OAAO,EAAE;QACP,QAAQ,EAAE,6EAA6E;QACvF,SAAS,EAAE,+CAA+C;KAC3D;CACF,CAAC"}
|