@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.
@@ -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;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAuG7C,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;IAqC3C;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;;OAKG;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,GACpD,OAAO,CAAC,IAAI,CAAC;IAwEhB;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgD1D;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
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
- this.buffer.copy(result, 0, this.readPos, this.readPos + size);
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
- this.buffer.copy(result, 0, this.readPos, this.capacity);
69
- this.buffer.copy(result, endSpace, 0, size - endSpace);
70
- this.readPos = size - endSpace;
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
- return result;
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 (no allocation, no copying)
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
- // Create RawFrame
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: new Uint8Array(frameData),
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":"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"}
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;AAIH,OAAO,EACL,gBAAgB,EAChB,eAAe,EAKhB,MAAM,UAAU,CAAC;AAOlB,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAiB;gBAElB,OAAO,GAAE,gBAAqB;IA0B1C;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsHzD;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB"}
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 { formatTimecode, calculateFcode, validateFrame } from '../utils/frame-processor';
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 || 'medium',
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, // Multi-threading not implemented yet
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
- // Pre-allocate WASM buffers (eliminates per-frame allocation overhead)
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
- validateFrame(frame);
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
- const isSceneChange = this.wasmBridge.detectSceneChange(this.state.prevFrame, this.state.curFrame, this.state.intraCount, this.state.fcode);
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
- // Progress callback
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":"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"}
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"}