@doedja/scenecut 1.0.1 → 1.0.2
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 +158 -107
- package/bin/cli.js +91 -25
- package/dist/decoder/ffmpeg-decoder.d.ts +15 -3
- package/dist/decoder/ffmpeg-decoder.d.ts.map +1 -1
- package/dist/decoder/ffmpeg-decoder.js +135 -14
- package/dist/decoder/ffmpeg-decoder.js.map +1 -1
- package/dist/detection/detector.d.ts.map +1 -1
- package/dist/detection/detector.js +134 -17
- package/dist/detection/detector.js.map +1 -1
- package/dist/detection/temporal-smoother.d.ts +32 -0
- package/dist/detection/temporal-smoother.d.ts.map +1 -0
- package/dist/detection/temporal-smoother.js +88 -0
- package/dist/detection/temporal-smoother.js.map +1 -0
- package/dist/detection/wasm-bridge.d.ts +26 -23
- package/dist/detection/wasm-bridge.d.ts.map +1 -1
- package/dist/detection/wasm-bridge.js +107 -62
- package/dist/detection/wasm-bridge.js.map +1 -1
- package/dist/detection.wasm.js +1 -1
- package/dist/detection.wasm.wasm +0 -0
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/dist/keyframes.cjs.js +488 -94
- package/dist/keyframes.cjs.js.map +1 -1
- package/dist/keyframes.esm.js +487 -95
- package/dist/keyframes.esm.js.map +1 -1
- package/dist/types/index.d.ts +36 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Uses fluent-ffmpeg to extract grayscale frames for scene detection
|
|
5
5
|
*/
|
|
6
|
-
import { RawFrame, VideoMetadata } from '../types';
|
|
6
|
+
import { RawFrame, VideoMetadata, FrameImageOptions } from '../types';
|
|
7
7
|
import { FrameBuffer } from './frame-buffer';
|
|
8
8
|
export interface DecoderOptions {
|
|
9
9
|
/** Pixel format for extraction (default: 'gray') */
|
|
@@ -20,7 +20,7 @@ export declare class FFmpegDecoder {
|
|
|
20
20
|
private frameBuffer;
|
|
21
21
|
constructor(videoPath: string, options?: DecoderOptions);
|
|
22
22
|
/**
|
|
23
|
-
* Get video metadata
|
|
23
|
+
* Get video metadata (with richer codec/format info)
|
|
24
24
|
*/
|
|
25
25
|
getMetadata(): Promise<VideoMetadata>;
|
|
26
26
|
/**
|
|
@@ -30,14 +30,26 @@ export declare class FFmpegDecoder {
|
|
|
30
30
|
/**
|
|
31
31
|
* Extract frames as grayscale data
|
|
32
32
|
*
|
|
33
|
+
* Uses pre-allocated alternating buffers to eliminate double allocation.
|
|
34
|
+
* Auto-sizes ring buffer based on video resolution.
|
|
35
|
+
*
|
|
33
36
|
* @param onFrame Callback for each frame
|
|
34
37
|
* @param onProgress Optional progress callback
|
|
38
|
+
* @param signal Optional AbortSignal for cancellation
|
|
35
39
|
*/
|
|
36
|
-
extractFrames(onFrame: (frame: RawFrame) => Promise<void> | void, onProgress?: (current: number, total: number) => void): Promise<void>;
|
|
40
|
+
extractFrames(onFrame: (frame: RawFrame) => Promise<void> | void, onProgress?: (current: number, total: number) => void, signal?: AbortSignal): Promise<void>;
|
|
37
41
|
/**
|
|
38
42
|
* Extract a single frame at specific frame number
|
|
39
43
|
*/
|
|
40
44
|
extractFrame(frameNumber: number): Promise<RawFrame>;
|
|
45
|
+
/**
|
|
46
|
+
* Extract multiple frame images in a single FFmpeg invocation
|
|
47
|
+
* Uses FFmpeg's select filter to avoid N+1 process spawning
|
|
48
|
+
*
|
|
49
|
+
* @param frameNumbers Array of frame numbers to extract
|
|
50
|
+
* @param options Image extraction options
|
|
51
|
+
*/
|
|
52
|
+
extractFrameImages(frameNumbers: number[], options: FrameImageOptions): Promise<string[]>;
|
|
41
53
|
/**
|
|
42
54
|
* Get the frame buffer
|
|
43
55
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ffmpeg-decoder.d.ts","sourceRoot":"","sources":["../../src/decoder/ffmpeg-decoder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ffmpeg-decoder.d.ts","sourceRoot":"","sources":["../../src/decoder/ffmpeg-decoder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAiJ7C,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,WAAW,CAAc;gBAErB,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAU3D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAwC3C;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;;;;;;OASG;IACG,aAAa,CACjB,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAClD,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EACrD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC;IAmGhB;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgD1D;;;;;;OAMG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,EAAE,CAAC;IA4DpB;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -7,6 +7,8 @@ import * as ffmpeg from 'fluent-ffmpeg';
|
|
|
7
7
|
import * as ffmpegInstaller from '@ffmpeg-installer/ffmpeg';
|
|
8
8
|
import * as ffprobeInstaller from '@ffprobe-installer/ffprobe';
|
|
9
9
|
import { FrameBuffer } from './frame-buffer';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as fs from 'fs';
|
|
10
12
|
// Set FFmpeg and FFprobe paths from installers
|
|
11
13
|
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
|
|
12
14
|
ffmpeg.setFfprobePath(ffprobeInstaller.path);
|
|
@@ -50,31 +52,66 @@ class RingBuffer {
|
|
|
50
52
|
this.availableBytes += chunkSize;
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
|
-
* Read data from the ring buffer
|
|
55
|
+
* Read data from the ring buffer (allocates new buffer)
|
|
54
56
|
*/
|
|
55
57
|
read(size) {
|
|
56
58
|
if (size > this.availableBytes) {
|
|
57
59
|
throw new Error('RingBuffer underflow: not enough data available');
|
|
58
60
|
}
|
|
59
61
|
const result = Buffer.allocUnsafe(size);
|
|
62
|
+
this.readIntoBuffer(result, 0, size);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Read data directly into a pre-allocated Uint8Array (zero-allocation)
|
|
67
|
+
*/
|
|
68
|
+
readInto(target, offset, size) {
|
|
69
|
+
if (size > this.availableBytes) {
|
|
70
|
+
throw new Error('RingBuffer underflow: not enough data available');
|
|
71
|
+
}
|
|
60
72
|
const endSpace = this.capacity - this.readPos;
|
|
61
73
|
if (size <= endSpace) {
|
|
62
74
|
// No wrap-around needed
|
|
63
|
-
|
|
75
|
+
for (let i = 0; i < size; i++) {
|
|
76
|
+
target[offset + i] = this.buffer[this.readPos + i];
|
|
77
|
+
}
|
|
64
78
|
this.readPos += size;
|
|
65
79
|
}
|
|
66
80
|
else {
|
|
67
81
|
// Wrap-around: split read
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
for (let i = 0; i < endSpace; i++) {
|
|
83
|
+
target[offset + i] = this.buffer[this.readPos + i];
|
|
84
|
+
}
|
|
85
|
+
const remaining = size - endSpace;
|
|
86
|
+
for (let i = 0; i < remaining; i++) {
|
|
87
|
+
target[offset + endSpace + i] = this.buffer[i];
|
|
88
|
+
}
|
|
89
|
+
this.readPos = remaining;
|
|
71
90
|
}
|
|
72
91
|
// Wrap read position if at end
|
|
73
92
|
if (this.readPos >= this.capacity) {
|
|
74
93
|
this.readPos = 0;
|
|
75
94
|
}
|
|
76
95
|
this.availableBytes -= size;
|
|
77
|
-
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Internal: read into a Node.js Buffer
|
|
99
|
+
*/
|
|
100
|
+
readIntoBuffer(result, offset, size) {
|
|
101
|
+
const endSpace = this.capacity - this.readPos;
|
|
102
|
+
if (size <= endSpace) {
|
|
103
|
+
this.buffer.copy(result, offset, this.readPos, this.readPos + size);
|
|
104
|
+
this.readPos += size;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.buffer.copy(result, offset, this.readPos, this.capacity);
|
|
108
|
+
this.buffer.copy(result, offset + endSpace, 0, size - endSpace);
|
|
109
|
+
this.readPos = size - endSpace;
|
|
110
|
+
}
|
|
111
|
+
if (this.readPos >= this.capacity) {
|
|
112
|
+
this.readPos = 0;
|
|
113
|
+
}
|
|
114
|
+
this.availableBytes -= size;
|
|
78
115
|
}
|
|
79
116
|
/**
|
|
80
117
|
* Get number of bytes available to read
|
|
@@ -103,7 +140,7 @@ export class FFmpegDecoder {
|
|
|
103
140
|
this.frameBuffer = new FrameBuffer(this.options.maxBufferFrames);
|
|
104
141
|
}
|
|
105
142
|
/**
|
|
106
|
-
* Get video metadata
|
|
143
|
+
* Get video metadata (with richer codec/format info)
|
|
107
144
|
*/
|
|
108
145
|
async getMetadata() {
|
|
109
146
|
if (this.metadata) {
|
|
@@ -130,7 +167,10 @@ export class FFmpegDecoder {
|
|
|
130
167
|
resolution: {
|
|
131
168
|
width: videoStream.width || 0,
|
|
132
169
|
height: videoStream.height || 0
|
|
133
|
-
}
|
|
170
|
+
},
|
|
171
|
+
codec: videoStream.codec_name || undefined,
|
|
172
|
+
pixelFormat: videoStream.pix_fmt || undefined,
|
|
173
|
+
bitrate: metadata.format.bit_rate ? parseInt(String(metadata.format.bit_rate)) : undefined
|
|
134
174
|
};
|
|
135
175
|
resolve(this.metadata);
|
|
136
176
|
});
|
|
@@ -149,16 +189,26 @@ export class FFmpegDecoder {
|
|
|
149
189
|
/**
|
|
150
190
|
* Extract frames as grayscale data
|
|
151
191
|
*
|
|
192
|
+
* Uses pre-allocated alternating buffers to eliminate double allocation.
|
|
193
|
+
* Auto-sizes ring buffer based on video resolution.
|
|
194
|
+
*
|
|
152
195
|
* @param onFrame Callback for each frame
|
|
153
196
|
* @param onProgress Optional progress callback
|
|
197
|
+
* @param signal Optional AbortSignal for cancellation
|
|
154
198
|
*/
|
|
155
|
-
async extractFrames(onFrame, onProgress) {
|
|
199
|
+
async extractFrames(onFrame, onProgress, signal) {
|
|
156
200
|
const metadata = await this.getMetadata();
|
|
157
201
|
const { width, height } = metadata.resolution;
|
|
158
202
|
return new Promise((resolve, reject) => {
|
|
159
203
|
let frameNumber = 0;
|
|
160
|
-
const ringBuffer = new RingBuffer(); // 8MB ring buffer
|
|
161
204
|
const frameSize = width * height; // Grayscale: 1 byte per pixel
|
|
205
|
+
// Auto-size ring buffer based on resolution (min 4MB, fits 3 frames)
|
|
206
|
+
const ringBufferSize = Math.max(4 * 1024 * 1024, frameSize * 3);
|
|
207
|
+
const ringBuffer = new RingBuffer(ringBufferSize);
|
|
208
|
+
// Pre-allocate two alternating frame buffers (eliminates double allocation)
|
|
209
|
+
const frameBufferA = new Uint8Array(frameSize);
|
|
210
|
+
const frameBufferB = new Uint8Array(frameSize);
|
|
211
|
+
let useBufferA = true;
|
|
162
212
|
const command = ffmpeg.default(this.videoPath)
|
|
163
213
|
.outputOptions([
|
|
164
214
|
'-f', 'image2pipe',
|
|
@@ -172,20 +222,38 @@ export class FFmpegDecoder {
|
|
|
172
222
|
resolve();
|
|
173
223
|
});
|
|
174
224
|
const stream = command.pipe();
|
|
225
|
+
// Listen for abort signal
|
|
226
|
+
if (signal) {
|
|
227
|
+
const onAbort = () => {
|
|
228
|
+
stream.destroy();
|
|
229
|
+
reject(new Error('Detection aborted'));
|
|
230
|
+
};
|
|
231
|
+
if (signal.aborted) {
|
|
232
|
+
stream.destroy();
|
|
233
|
+
reject(new Error('Detection aborted'));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
237
|
+
}
|
|
175
238
|
stream.on('data', async (chunk) => {
|
|
176
|
-
// Write chunk to ring buffer
|
|
239
|
+
// Write chunk to ring buffer
|
|
177
240
|
ringBuffer.write(chunk);
|
|
178
241
|
// Process complete frames
|
|
179
242
|
while (ringBuffer.available() >= frameSize) {
|
|
180
|
-
const frameData = ringBuffer.read(frameSize);
|
|
181
243
|
// Skip frames if requested
|
|
182
244
|
if (this.options.skipFrames > 0 && frameNumber % (this.options.skipFrames + 1) !== 0) {
|
|
245
|
+
// Still need to consume the data from the ring buffer
|
|
246
|
+
ringBuffer.read(frameSize);
|
|
183
247
|
frameNumber++;
|
|
184
248
|
continue;
|
|
185
249
|
}
|
|
186
|
-
//
|
|
250
|
+
// Read directly into pre-allocated buffer (zero-allocation)
|
|
251
|
+
const targetBuffer = useBufferA ? frameBufferA : frameBufferB;
|
|
252
|
+
ringBuffer.readInto(targetBuffer, 0, frameSize);
|
|
253
|
+
useBufferA = !useBufferA;
|
|
254
|
+
// Create RawFrame (reuses the pre-allocated buffer - no copy)
|
|
187
255
|
const frame = {
|
|
188
|
-
data:
|
|
256
|
+
data: targetBuffer,
|
|
189
257
|
width,
|
|
190
258
|
height,
|
|
191
259
|
stride: width,
|
|
@@ -255,6 +323,59 @@ export class FFmpegDecoder {
|
|
|
255
323
|
});
|
|
256
324
|
});
|
|
257
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Extract multiple frame images in a single FFmpeg invocation
|
|
328
|
+
* Uses FFmpeg's select filter to avoid N+1 process spawning
|
|
329
|
+
*
|
|
330
|
+
* @param frameNumbers Array of frame numbers to extract
|
|
331
|
+
* @param options Image extraction options
|
|
332
|
+
*/
|
|
333
|
+
async extractFrameImages(frameNumbers, options) {
|
|
334
|
+
const metadata = await this.getMetadata();
|
|
335
|
+
// Ensure output directory exists
|
|
336
|
+
if (!fs.existsSync(options.outputDir)) {
|
|
337
|
+
fs.mkdirSync(options.outputDir, { recursive: true });
|
|
338
|
+
}
|
|
339
|
+
const format = options.format || 'jpg';
|
|
340
|
+
const quality = options.quality || 85;
|
|
341
|
+
const template = options.filenameTemplate || 'scene_{frame}';
|
|
342
|
+
// Build FFmpeg select filter expression
|
|
343
|
+
// select='eq(n,100)+eq(n,200)+eq(n,300)'
|
|
344
|
+
const selectExpr = frameNumbers.map(n => `eq(n\\,${n})`).join('+');
|
|
345
|
+
return new Promise((resolve, reject) => {
|
|
346
|
+
const outputPaths = [];
|
|
347
|
+
// Generate output filenames
|
|
348
|
+
for (const frameNum of frameNumbers) {
|
|
349
|
+
const timestamp = frameNum / metadata.fps;
|
|
350
|
+
const filename = template
|
|
351
|
+
.replace('{frame}', String(frameNum))
|
|
352
|
+
.replace('{timestamp}', timestamp.toFixed(3));
|
|
353
|
+
outputPaths.push(path.join(options.outputDir, `${filename}.${format}`));
|
|
354
|
+
}
|
|
355
|
+
// Use FFmpeg with select filter and output pattern
|
|
356
|
+
const outputPattern = path.join(options.outputDir, `${template.replace('{frame}', '%d').replace('{timestamp}', '%d')}.${format}`);
|
|
357
|
+
const outputOptions = [
|
|
358
|
+
'-vf', `select='${selectExpr}',setpts=N/TB`,
|
|
359
|
+
'-vsync', 'vfr'
|
|
360
|
+
];
|
|
361
|
+
if (format === 'jpg') {
|
|
362
|
+
outputOptions.push('-qscale:v', String(Math.round((100 - quality) / 3.33)));
|
|
363
|
+
}
|
|
364
|
+
if (options.width) {
|
|
365
|
+
outputOptions.push('-vf', `select='${selectExpr}',scale=${options.width}:-1,setpts=N/TB`);
|
|
366
|
+
}
|
|
367
|
+
ffmpeg.default(this.videoPath)
|
|
368
|
+
.outputOptions(outputOptions)
|
|
369
|
+
.output(outputPattern)
|
|
370
|
+
.on('error', (err) => {
|
|
371
|
+
reject(new Error(`FFmpeg frame extraction error: ${err.message}`));
|
|
372
|
+
})
|
|
373
|
+
.on('end', () => {
|
|
374
|
+
resolve(outputPaths);
|
|
375
|
+
})
|
|
376
|
+
.run();
|
|
377
|
+
});
|
|
378
|
+
}
|
|
258
379
|
/**
|
|
259
380
|
* Get the frame buffer
|
|
260
381
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ffmpeg-decoder.js","sourceRoot":"","sources":["../../src/decoder/ffmpeg-decoder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,eAAe,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,+CAA+C;AAC/C,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAC3C,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU;IAOd,YAAY,OAAe,CAAC,GAAG,IAAI,GAAG,IAAI;QALlC,aAAQ,GAAW,CAAC,CAAC;QACrB,YAAO,GAAW,CAAC,CAAC;QACpB,mBAAc,GAAW,CAAC,CAAC;QAIjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAa;QACjB,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;QAE/B,IAAI,SAAS,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QAED,wCAAwC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE/C,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;YAC1B,wBAAwB;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,2BAA2B;YAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;QACvC,CAAC;QAED,gCAAgC;QAChC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,CAAC,cAAc,IAAI,SAAS,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,IAAY;QACf,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;QAE9C,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;YACrB,wBAAwB;YACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;YAC/D,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;YACvD,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC;QACjC,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF;AAWD,MAAM,OAAO,aAAa;IAMxB,YAAY,SAAiB,EAAE,UAA0B,EAAE;QAHnD,aAAQ,GAAyB,IAAI,CAAC;QAI5C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG;YACb,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,MAAM;YAC1C,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,CAAC;YAC7C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;SACpC,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;gBAC/C,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;oBACnE,OAAO;gBACT,CAAC;gBAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC;gBACzE,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;oBAC3C,OAAO;gBACT,CAAC;gBAED,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,YAAY,IAAI,WAAW,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC;gBAC5F,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;gBACnE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;gBAE/C,IAAI,CAAC,QAAQ,GAAG;oBACd,WAAW;oBACX,QAAQ;oBACR,GAAG;oBACH,UAAU,EAAE;wBACV,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;wBAC7B,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,CAAC;qBAChC;iBACF,CAAC;gBAEF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,SAAiB;QAChC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CACjB,OAAkD,EAClD,UAAqD;QAErD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC;QAE9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC,CAAC,kBAAkB;YACvD,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC,8BAA8B;YAEhE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;iBAC3C,aAAa,CAAC;gBACb,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,MAAM;gBAClB,SAAS,EAAE,UAAU;aACtB,CAAC;iBACD,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC;iBACD,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACd,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YAEL,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAc,CAAC;YAE1C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;gBACxC,yDAAyD;gBACzD,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAExB,0BAA0B;gBAC1B,OAAO,UAAU,CAAC,SAAS,EAAE,IAAI,SAAS,EAAE,CAAC;oBAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAE7C,2BAA2B;oBAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;wBACrF,WAAW,EAAE,CAAC;wBACd,SAAS;oBACX,CAAC;oBAED,kBAAkB;oBAClB,MAAM,KAAK,GAAa;wBACtB,IAAI,EAAE,IAAI,UAAU,CAAC,SAAS,CAAC;wBAC/B,KAAK;wBACL,MAAM;wBACN,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,WAAW,GAAG,QAAQ,CAAC,GAAG;wBAC/B,WAAW;qBACZ,CAAC;oBAEF,gBAAgB;oBAChB,IAAI,CAAC;wBACH,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;oBACvB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,OAAO,EAAE,CAAC;wBACjB,MAAM,CAAC,GAAG,CAAC,CAAC;wBACZ,OAAO;oBACT,CAAC;oBAED,oBAAoB;oBACpB,IAAI,UAAU,IAAI,WAAW,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;wBACzC,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;oBAChD,CAAC;oBAED,WAAW,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,WAAmB;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC9C,MAAM,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC;QAE7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;YAEjC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;iBAC3C,SAAS,CAAC,SAAS,CAAC;iBACpB,aAAa,CAAC;gBACb,UAAU,EAAE,GAAG;gBACf,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,MAAM;gBAClB,SAAS,EAAE,UAAU;aACtB,CAAC;iBACD,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YAEL,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAc,CAAC;YAE1C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAClC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAExB,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,SAAS,EAAE,CAAC;oBACxC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAE7C,MAAM,KAAK,GAAa;wBACtB,IAAI,EAAE,IAAI,UAAU,CAAC,SAAS,CAAC;wBAC/B,KAAK;wBACL,MAAM;wBACN,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,SAAS;wBACd,WAAW;qBACZ,CAAC;oBAEF,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"ffmpeg-decoder.js","sourceRoot":"","sources":["../../src/decoder/ffmpeg-decoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/detection/detector.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/detection/detector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EACL,gBAAgB,EAChB,eAAe,EAKhB,MAAM,UAAU,CAAC;AAQlB,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAiB;gBAElB,OAAO,GAAE,gBAAqB;IA2B1C;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAmQzD;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -3,21 +3,23 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { FFmpegDecoder } from '../decoder/ffmpeg-decoder';
|
|
5
5
|
import { WasmBridge } from './wasm-bridge';
|
|
6
|
-
import {
|
|
6
|
+
import { TemporalSmoother } from './temporal-smoother';
|
|
7
|
+
import { formatTimecode, calculateFcode, calculateThresholds, validateFrame } from '../utils/frame-processor';
|
|
7
8
|
export class SceneDetector {
|
|
8
9
|
constructor(options = {}) {
|
|
9
10
|
// Set default options
|
|
10
11
|
this.options = {
|
|
11
|
-
sensitivity: options.sensitivity || '
|
|
12
|
+
sensitivity: options.sensitivity || 'low',
|
|
12
13
|
customThresholds: options.customThresholds || { intraThresh: 2000, intraThresh2: 90 },
|
|
13
14
|
searchRange: options.searchRange || 'medium',
|
|
14
|
-
workers: options.workers || 1,
|
|
15
|
+
workers: options.workers || 1,
|
|
15
16
|
progressive: options.progressive || { enabled: false, initialStep: 1, refinementSteps: [] },
|
|
16
17
|
temporalSmoothing: options.temporalSmoothing || { enabled: false, windowSize: 5, minConsecutive: 2 },
|
|
17
18
|
frameExtraction: options.frameExtraction || { pixelFormat: 'gray', maxBufferFrames: 2 },
|
|
18
19
|
onProgress: options.onProgress || (() => { }),
|
|
19
20
|
onScene: options.onScene || (() => { }),
|
|
20
|
-
format: options.format || 'json'
|
|
21
|
+
format: options.format || 'json',
|
|
22
|
+
signal: options.signal || undefined
|
|
21
23
|
};
|
|
22
24
|
this.wasmBridge = new WasmBridge();
|
|
23
25
|
// Initialize detection state
|
|
@@ -44,65 +46,180 @@ export class SceneDetector {
|
|
|
44
46
|
const metadata = await decoder.getMetadata();
|
|
45
47
|
// Calculate fcode from search range
|
|
46
48
|
this.state.fcode = calculateFcode(this.options.searchRange, metadata.resolution.width, metadata.resolution.height);
|
|
47
|
-
//
|
|
49
|
+
// Calculate thresholds from sensitivity
|
|
50
|
+
let thresholds;
|
|
51
|
+
if (this.options.sensitivity === 'custom') {
|
|
52
|
+
thresholds = this.options.customThresholds;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
thresholds = calculateThresholds(this.options.sensitivity);
|
|
56
|
+
}
|
|
57
|
+
// Pre-allocate WASM buffers
|
|
48
58
|
this.wasmBridge.allocateBuffers(metadata.resolution.width, metadata.resolution.height);
|
|
59
|
+
// Initialize temporal smoother if enabled
|
|
60
|
+
let temporalSmoother = null;
|
|
61
|
+
if (this.options.temporalSmoothing.enabled) {
|
|
62
|
+
temporalSmoother = new TemporalSmoother(this.options.temporalSmoothing);
|
|
63
|
+
}
|
|
49
64
|
// Initialize scene list (frame 0 is always a scene change)
|
|
50
65
|
const scenes = [
|
|
51
66
|
{
|
|
52
67
|
frameNumber: 0,
|
|
53
68
|
timestamp: 0,
|
|
54
|
-
timecode: '00:00:00.000'
|
|
69
|
+
timecode: '00:00:00.000',
|
|
70
|
+
confidence: 1.0
|
|
55
71
|
}
|
|
56
72
|
];
|
|
57
73
|
// Processing statistics
|
|
58
74
|
const startTime = Date.now();
|
|
59
75
|
let processedFrames = 0;
|
|
76
|
+
let firstFrameValidated = false;
|
|
77
|
+
// Rolling FPS window for accurate speed metrics (3-second window)
|
|
78
|
+
const fpsWindow = [];
|
|
79
|
+
// Fade/dissolve detection state
|
|
80
|
+
let keyframeData = null;
|
|
81
|
+
const driftThresholdFactor = 0.6; // Re-run detection at 60% of base thresholds
|
|
82
|
+
// Quick-reject sampling interval
|
|
83
|
+
const quickRejectStep = 64;
|
|
84
|
+
const quickRejectThreshold = 5;
|
|
85
|
+
// AbortSignal check
|
|
86
|
+
const signal = this.options.signal;
|
|
60
87
|
// Process frames
|
|
61
88
|
await decoder.extractFrames(async (frame) => {
|
|
62
|
-
|
|
89
|
+
// Check abort signal
|
|
90
|
+
if (signal && signal.aborted) {
|
|
91
|
+
throw new Error('Detection aborted');
|
|
92
|
+
}
|
|
93
|
+
// Validate only the first frame (dimensions never change within a video)
|
|
94
|
+
if (!firstFrameValidated) {
|
|
95
|
+
validateFrame(frame);
|
|
96
|
+
firstFrameValidated = true;
|
|
97
|
+
}
|
|
63
98
|
// Update current frame
|
|
64
99
|
this.state.curFrame = frame;
|
|
65
100
|
// Need at least 2 frames to detect scene change
|
|
66
101
|
if (this.state.prevFrame) {
|
|
67
|
-
|
|
102
|
+
let isSceneChange = false;
|
|
103
|
+
let confidence = 0;
|
|
104
|
+
// Quick-reject: sampled MAD between prev and cur frame
|
|
105
|
+
const prevData = this.state.prevFrame.data;
|
|
106
|
+
const curData = this.state.curFrame.data;
|
|
107
|
+
let sampledDiff = 0;
|
|
108
|
+
let sampleCount = 0;
|
|
109
|
+
for (let i = 0; i < curData.length; i += quickRejectStep) {
|
|
110
|
+
sampledDiff += Math.abs(curData[i] - prevData[i]);
|
|
111
|
+
sampleCount++;
|
|
112
|
+
}
|
|
113
|
+
const avgDiff = sampledDiff / sampleCount;
|
|
114
|
+
if (avgDiff >= quickRejectThreshold) {
|
|
115
|
+
// Frame differs enough, run full WASM detection
|
|
116
|
+
const result = this.wasmBridge.detectSceneChange(this.state.prevFrame, this.state.curFrame, this.state.intraCount, this.state.fcode, thresholds.intraThresh, thresholds.intraThresh2);
|
|
117
|
+
isSceneChange = result.isSceneChange;
|
|
118
|
+
confidence = result.confidence;
|
|
119
|
+
// Fade/dissolve detection: if not detected as scene change,
|
|
120
|
+
// check drift from last keyframe
|
|
121
|
+
if (!isSceneChange && keyframeData) {
|
|
122
|
+
let driftSum = 0;
|
|
123
|
+
let driftCount = 0;
|
|
124
|
+
// Sample every 4th pixel for speed
|
|
125
|
+
for (let i = 0; i < curData.length; i += 4) {
|
|
126
|
+
driftSum += Math.abs(curData[i] - keyframeData[i]);
|
|
127
|
+
driftCount++;
|
|
128
|
+
}
|
|
129
|
+
const driftAvg = driftSum / driftCount;
|
|
130
|
+
// If cumulative drift is high but per-frame SAD didn't trigger,
|
|
131
|
+
// re-run with lowered thresholds
|
|
132
|
+
if (driftAvg > 30) {
|
|
133
|
+
const fadeResult = this.wasmBridge.detectSceneChange(this.state.prevFrame, this.state.curFrame, this.state.intraCount, this.state.fcode, Math.round(thresholds.intraThresh * driftThresholdFactor), Math.round(thresholds.intraThresh2 * driftThresholdFactor));
|
|
134
|
+
if (fadeResult.isSceneChange) {
|
|
135
|
+
isSceneChange = true;
|
|
136
|
+
confidence = fadeResult.confidence;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// else: quick-reject - frames are nearly identical, skip WASM call
|
|
142
|
+
// Apply temporal smoothing if enabled
|
|
143
|
+
if (temporalSmoother) {
|
|
144
|
+
const smoothed = temporalSmoother.process(frame.frameNumber, isSceneChange, confidence);
|
|
145
|
+
isSceneChange = smoothed.isSceneChange;
|
|
146
|
+
confidence = smoothed.confidence;
|
|
147
|
+
}
|
|
68
148
|
if (isSceneChange) {
|
|
69
149
|
const scene = {
|
|
70
150
|
frameNumber: frame.frameNumber,
|
|
71
151
|
timestamp: frame.pts,
|
|
72
|
-
timecode: formatTimecode(frame.pts)
|
|
152
|
+
timecode: formatTimecode(frame.pts),
|
|
153
|
+
confidence
|
|
73
154
|
};
|
|
74
155
|
scenes.push(scene);
|
|
75
156
|
// Call scene callback
|
|
76
157
|
this.options.onScene(scene);
|
|
77
158
|
// Reset intraCount
|
|
78
159
|
this.state.intraCount = 1;
|
|
160
|
+
// Update keyframe for drift detection
|
|
161
|
+
keyframeData = new Uint8Array(curData);
|
|
79
162
|
}
|
|
80
163
|
else {
|
|
81
|
-
// Increment intraCount
|
|
82
164
|
this.state.intraCount++;
|
|
83
165
|
}
|
|
84
166
|
}
|
|
167
|
+
else {
|
|
168
|
+
// First frame is the initial keyframe for drift detection
|
|
169
|
+
keyframeData = new Uint8Array(frame.data);
|
|
170
|
+
}
|
|
85
171
|
// Move current frame to previous
|
|
86
172
|
this.state.prevFrame = this.state.curFrame;
|
|
87
173
|
processedFrames++;
|
|
88
174
|
}, (current, total) => {
|
|
89
|
-
//
|
|
175
|
+
// Enhanced progress with rolling FPS window
|
|
176
|
+
const now = Date.now();
|
|
177
|
+
const elapsed = (now - startTime) / 1000;
|
|
178
|
+
// Add to rolling window
|
|
179
|
+
fpsWindow.push({ time: now, frame: current });
|
|
180
|
+
// Remove samples older than 3 seconds
|
|
181
|
+
while (fpsWindow.length > 1 && (now - fpsWindow[0].time) > 3000) {
|
|
182
|
+
fpsWindow.shift();
|
|
183
|
+
}
|
|
184
|
+
// Calculate instantaneous FPS from rolling window
|
|
185
|
+
let currentFps = 0;
|
|
186
|
+
if (fpsWindow.length >= 2) {
|
|
187
|
+
const oldest = fpsWindow[0];
|
|
188
|
+
const newest = fpsWindow[fpsWindow.length - 1];
|
|
189
|
+
const dt = (newest.time - oldest.time) / 1000;
|
|
190
|
+
if (dt > 0) {
|
|
191
|
+
currentFps = (newest.frame - oldest.frame) / dt;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Calculate ETA from instantaneous FPS
|
|
195
|
+
const remaining = currentFps > 0 ? (total - current) / currentFps : undefined;
|
|
90
196
|
const progress = {
|
|
91
197
|
currentFrame: current,
|
|
92
198
|
totalFrames: total,
|
|
93
|
-
percent: Math.round((current / total) * 100)
|
|
199
|
+
percent: Math.round((current / total) * 100),
|
|
200
|
+
eta: remaining,
|
|
201
|
+
fps: currentFps,
|
|
202
|
+
elapsed,
|
|
203
|
+
scenesDetected: scenes.length
|
|
94
204
|
};
|
|
95
|
-
// Calculate ETA
|
|
96
|
-
const elapsed = (Date.now() - startTime) / 1000;
|
|
97
|
-
const fps = current / elapsed;
|
|
98
|
-
const remaining = (total - current) / fps;
|
|
99
|
-
progress.eta = remaining;
|
|
100
205
|
this.options.onProgress(progress);
|
|
101
206
|
});
|
|
102
207
|
// Calculate statistics
|
|
103
208
|
const endTime = Date.now();
|
|
104
209
|
const processingTime = (endTime - startTime) / 1000;
|
|
105
210
|
const framesPerSecond = processedFrames / processingTime;
|
|
211
|
+
// Post-process: compute scene durations
|
|
212
|
+
for (let i = 0; i < scenes.length; i++) {
|
|
213
|
+
if (i < scenes.length - 1) {
|
|
214
|
+
scenes[i].duration = scenes[i + 1].timestamp - scenes[i].timestamp;
|
|
215
|
+
scenes[i].frameCount = scenes[i + 1].frameNumber - scenes[i].frameNumber;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// Last scene: duration until end of video
|
|
219
|
+
scenes[i].duration = metadata.duration - scenes[i].timestamp;
|
|
220
|
+
scenes[i].frameCount = metadata.totalFrames - scenes[i].frameNumber;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
106
223
|
// Clean up
|
|
107
224
|
decoder.destroy();
|
|
108
225
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/detection/detector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/detection/detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporal Smoother - Sliding window filter to reduce false positives
|
|
3
|
+
*
|
|
4
|
+
* Three rules:
|
|
5
|
+
* 1. Minimum gap: Suppress detections within minConsecutive frames of each other (keep highest confidence)
|
|
6
|
+
* 2. Flash suppression: Isolated single-frame detections with low confidence are suppressed
|
|
7
|
+
* 3. Cluster merging: Consecutive triggered frames (common in dissolves) keep only highest-confidence one
|
|
8
|
+
*/
|
|
9
|
+
import { TemporalSmoothing } from '../types';
|
|
10
|
+
export interface SmoothedResult {
|
|
11
|
+
isSceneChange: boolean;
|
|
12
|
+
confidence: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class TemporalSmoother {
|
|
15
|
+
private windowSize;
|
|
16
|
+
private minConsecutive;
|
|
17
|
+
private recentDetections;
|
|
18
|
+
private lastConfirmedFrame;
|
|
19
|
+
private pendingCluster;
|
|
20
|
+
private nonDetectionCount;
|
|
21
|
+
private flashConfidenceThreshold;
|
|
22
|
+
constructor(config: TemporalSmoothing);
|
|
23
|
+
/**
|
|
24
|
+
* Process a frame's detection result through temporal smoothing
|
|
25
|
+
*/
|
|
26
|
+
process(frameNumber: number, rawIsSceneChange: boolean, rawConfidence: number): SmoothedResult;
|
|
27
|
+
/**
|
|
28
|
+
* Flush the pending cluster, emitting the highest-confidence detection
|
|
29
|
+
*/
|
|
30
|
+
private flushCluster;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=temporal-smoother.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal-smoother.d.ts","sourceRoot":"","sources":["../../src/detection/temporal-smoother.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAO7C,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAS;IAG/B,OAAO,CAAC,gBAAgB,CAAwB;IAGhD,OAAO,CAAC,kBAAkB,CAAa;IAGvC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,wBAAwB,CAAe;gBAEnC,MAAM,EAAE,iBAAiB;IAKrC;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc;IAyC9F;;OAEG;IACH,OAAO,CAAC,YAAY;CA8BrB"}
|