@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyframes.cjs.js","sources":["utils/buffer-pool.js","decoder/frame-buffer.js","decoder/ffmpeg-decoder.js","detection/wasm-bridge.js","utils/frame-processor.js","detection/detector.js","index.js"],"sourcesContent":["/**\n * Buffer Pool - Memory management for frame buffers\n *\n * Reuses TypedArray buffers to reduce memory allocation and GC pressure\n */\nexport class BufferPool {\n /**\n * Create a new buffer pool\n *\n * @param maxPoolSize Maximum number of buffers to keep per size (default: 4)\n */\n constructor(maxPoolSize = 4) {\n this.pool = new Map();\n this.maxPoolSize = maxPoolSize;\n }\n /**\n * Acquire a buffer of the specified size\n *\n * @param size Buffer size in bytes\n * @returns Uint8Array buffer\n */\n acquire(size) {\n const poolForSize = this.pool.get(size);\n if (poolForSize && poolForSize.length > 0) {\n const buffer = poolForSize.pop();\n // Clear the buffer before reuse\n buffer.fill(0);\n return buffer;\n }\n // No buffer available, allocate new one\n return new Uint8Array(size);\n }\n /**\n * Release a buffer back to the pool\n *\n * @param buffer Buffer to release\n */\n release(buffer) {\n const size = buffer.length;\n let poolForSize = this.pool.get(size);\n if (!poolForSize) {\n poolForSize = [];\n this.pool.set(size, poolForSize);\n }\n // Only keep buffer if pool not full\n if (poolForSize.length < this.maxPoolSize) {\n poolForSize.push(buffer);\n }\n // Otherwise, let it be garbage collected\n }\n /**\n * Get pool statistics\n */\n getStats() {\n const stats = [];\n for (const [size, buffers] of this.pool.entries()) {\n stats.push({\n size,\n count: buffers.length\n });\n }\n return stats.sort((a, b) => b.size - a.size);\n }\n /**\n * Clear all pooled buffers\n */\n clear() {\n this.pool.clear();\n }\n /**\n * Get total memory used by pooled buffers\n */\n getTotalMemory() {\n let total = 0;\n for (const [size, buffers] of this.pool.entries()) {\n total += size * buffers.length;\n }\n return total;\n }\n}\n//# sourceMappingURL=buffer-pool.js.map","/**\n * Frame Buffer - Circular buffer for frame management\n *\n * Maintains a circular buffer of frames for efficient scene detection\n * Typically only needs to hold 2 frames (previous and current)\n */\nimport { BufferPool } from '../utils/buffer-pool';\nexport class FrameBuffer {\n /**\n * Create a new frame buffer\n *\n * @param maxFrames Maximum number of frames to buffer (default: 2)\n * @param bufferPool Optional buffer pool for memory reuse\n */\n constructor(maxFrames = 2, bufferPool) {\n this.currentIndex = 0;\n this.maxFrames = maxFrames;\n this.bufferPool = bufferPool || new BufferPool();\n this.frames = new Array(maxFrames).fill(null);\n }\n /**\n * Push a new frame into the buffer\n *\n * @param frame Frame to push\n * @returns The frame that was evicted, if any\n */\n push(frame) {\n const evictedFrame = this.frames[this.currentIndex];\n // Release the evicted frame's buffer back to pool\n if (evictedFrame) {\n this.bufferPool.release(evictedFrame.data);\n }\n // Store the new frame\n this.frames[this.currentIndex] = frame;\n // Move to next position\n this.currentIndex = (this.currentIndex + 1) % this.maxFrames;\n return evictedFrame;\n }\n /**\n * Get frame at specific offset from current position\n *\n * @param offset Offset from current position (0 = most recent, 1 = previous, etc.)\n * @returns Frame or null if not available\n */\n get(offset = 0) {\n if (offset < 0 || offset >= this.maxFrames) {\n return null;\n }\n const index = (this.currentIndex - 1 - offset + this.maxFrames) % this.maxFrames;\n return this.frames[index];\n }\n /**\n * Get the most recent frame\n */\n getCurrent() {\n return this.get(0);\n }\n /**\n * Get the previous frame\n */\n getPrevious() {\n return this.get(1);\n }\n /**\n * Get both current and previous frames\n *\n * @returns [current, previous] or null if either is not available\n */\n getCurrentAndPrevious() {\n const current = this.getCurrent();\n const previous = this.getPrevious();\n if (!current || !previous) {\n return null;\n }\n return [current, previous];\n }\n /**\n * Allocate a buffer for a new frame\n *\n * @param size Buffer size in bytes\n * @returns Uint8Array buffer\n */\n allocateBuffer(size) {\n return this.bufferPool.acquire(size);\n }\n /**\n * Clear all frames from the buffer\n */\n clear() {\n // Release all buffers back to pool\n for (const frame of this.frames) {\n if (frame) {\n this.bufferPool.release(frame.data);\n }\n }\n this.frames = new Array(this.maxFrames).fill(null);\n this.currentIndex = 0;\n }\n /**\n * Get the number of frames currently in the buffer\n */\n size() {\n return this.frames.filter(f => f !== null).length;\n }\n /**\n * Check if buffer is full\n */\n isFull() {\n return this.size() === this.maxFrames;\n }\n /**\n * Get buffer statistics\n */\n getStats() {\n return {\n maxFrames: this.maxFrames,\n currentFrames: this.size(),\n bufferPoolStats: this.bufferPool.getStats(),\n totalPoolMemory: this.bufferPool.getTotalMemory()\n };\n }\n}\n//# sourceMappingURL=frame-buffer.js.map","/**\n * FFmpeg Decoder - Extract frames from video files\n *\n * Uses fluent-ffmpeg to extract grayscale frames for scene detection\n */\nimport * as ffmpeg from 'fluent-ffmpeg';\nimport * as ffmpegInstaller from '@ffmpeg-installer/ffmpeg';\nimport * as ffprobeInstaller from '@ffprobe-installer/ffprobe';\nimport { FrameBuffer } from './frame-buffer';\n// Set FFmpeg and FFprobe paths from installers\nffmpeg.setFfmpegPath(ffmpegInstaller.path);\nffmpeg.setFfprobePath(ffprobeInstaller.path);\n/**\n * Ring Buffer - Fixed-size circular buffer for streaming data\n * Eliminates repeated Buffer.concat() allocations and GC pressure\n */\nclass RingBuffer {\n constructor(size = 8 * 1024 * 1024) {\n this.writePos = 0;\n this.readPos = 0;\n this.availableBytes = 0;\n this.buffer = Buffer.allocUnsafe(size);\n this.capacity = size;\n }\n /**\n * Write data to the ring buffer\n */\n write(chunk) {\n const chunkSize = chunk.length;\n if (chunkSize > this.capacity - this.availableBytes) {\n throw new Error('RingBuffer overflow: chunk too large for available space');\n }\n // Write in two parts if wrapping around\n const endSpace = this.capacity - this.writePos;\n if (chunkSize <= endSpace) {\n // No wrap-around needed\n chunk.copy(this.buffer, this.writePos);\n this.writePos += chunkSize;\n }\n else {\n // Wrap-around: split write\n chunk.copy(this.buffer, this.writePos, 0, endSpace);\n chunk.copy(this.buffer, 0, endSpace, chunkSize);\n this.writePos = chunkSize - endSpace;\n }\n // Wrap write position if at end\n if (this.writePos >= this.capacity) {\n this.writePos = 0;\n }\n this.availableBytes += chunkSize;\n }\n /**\n * Read data from the ring buffer\n */\n read(size) {\n if (size > this.availableBytes) {\n throw new Error('RingBuffer underflow: not enough data available');\n }\n const result = Buffer.allocUnsafe(size);\n const endSpace = this.capacity - this.readPos;\n if (size <= endSpace) {\n // No wrap-around needed\n this.buffer.copy(result, 0, this.readPos, this.readPos + size);\n this.readPos += size;\n }\n else {\n // Wrap-around: split read\n this.buffer.copy(result, 0, this.readPos, this.capacity);\n this.buffer.copy(result, endSpace, 0, size - endSpace);\n this.readPos = size - endSpace;\n }\n // Wrap read position if at end\n if (this.readPos >= this.capacity) {\n this.readPos = 0;\n }\n this.availableBytes -= size;\n return result;\n }\n /**\n * Get number of bytes available to read\n */\n available() {\n return this.availableBytes;\n }\n /**\n * Reset the ring buffer\n */\n reset() {\n this.writePos = 0;\n this.readPos = 0;\n this.availableBytes = 0;\n }\n}\nexport class FFmpegDecoder {\n constructor(videoPath, options = {}) {\n this.metadata = null;\n this.videoPath = videoPath;\n this.options = {\n pixelFormat: options.pixelFormat || 'gray',\n maxBufferFrames: options.maxBufferFrames || 2,\n skipFrames: options.skipFrames || 0\n };\n this.frameBuffer = new FrameBuffer(this.options.maxBufferFrames);\n }\n /**\n * Get video metadata\n */\n async getMetadata() {\n if (this.metadata) {\n return this.metadata;\n }\n return new Promise((resolve, reject) => {\n ffmpeg.ffprobe(this.videoPath, (err, metadata) => {\n if (err) {\n reject(new Error(`Failed to read video metadata: ${err.message}`));\n return;\n }\n const videoStream = metadata.streams.find(s => s.codec_type === 'video');\n if (!videoStream) {\n reject(new Error('No video stream found'));\n return;\n }\n const fps = this.parseFps(videoStream.r_frame_rate || videoStream.avg_frame_rate || '30/1');\n const duration = parseFloat(String(metadata.format.duration || 0));\n const totalFrames = Math.floor(duration * fps);\n this.metadata = {\n totalFrames,\n duration,\n fps,\n resolution: {\n width: videoStream.width || 0,\n height: videoStream.height || 0\n }\n };\n resolve(this.metadata);\n });\n });\n }\n /**\n * Parse frame rate from FFmpeg format (e.g., \"30000/1001\")\n */\n parseFps(fpsString) {\n const parts = fpsString.split('/');\n if (parts.length === 2) {\n return parseInt(parts[0]) / parseInt(parts[1]);\n }\n return parseFloat(fpsString);\n }\n /**\n * Extract frames as grayscale data\n *\n * @param onFrame Callback for each frame\n * @param onProgress Optional progress callback\n */\n async extractFrames(onFrame, onProgress) {\n const metadata = await this.getMetadata();\n const { width, height } = metadata.resolution;\n return new Promise((resolve, reject) => {\n let frameNumber = 0;\n const ringBuffer = new RingBuffer(); // 8MB ring buffer\n const frameSize = width * height; // Grayscale: 1 byte per pixel\n const command = ffmpeg.default(this.videoPath)\n .outputOptions([\n '-f', 'image2pipe',\n '-pix_fmt', 'gray',\n '-vcodec', 'rawvideo'\n ])\n .on('error', (err) => {\n reject(new Error(`FFmpeg error: ${err.message}`));\n })\n .on('end', () => {\n resolve();\n });\n const stream = command.pipe();\n stream.on('data', async (chunk) => {\n // Write chunk to ring buffer (no allocation, no copying)\n ringBuffer.write(chunk);\n // Process complete frames\n while (ringBuffer.available() >= frameSize) {\n const frameData = ringBuffer.read(frameSize);\n // Skip frames if requested\n if (this.options.skipFrames > 0 && frameNumber % (this.options.skipFrames + 1) !== 0) {\n frameNumber++;\n continue;\n }\n // Create RawFrame\n const frame = {\n data: new Uint8Array(frameData),\n width,\n height,\n stride: width,\n pts: frameNumber / metadata.fps,\n frameNumber\n };\n // Call callback\n try {\n await onFrame(frame);\n }\n catch (err) {\n stream.destroy();\n reject(err);\n return;\n }\n // Progress callback\n if (onProgress && frameNumber % 30 === 0) {\n onProgress(frameNumber, metadata.totalFrames);\n }\n frameNumber++;\n }\n });\n stream.on('error', (err) => {\n reject(new Error(`Stream error: ${err.message}`));\n });\n });\n }\n /**\n * Extract a single frame at specific frame number\n */\n async extractFrame(frameNumber) {\n const metadata = await this.getMetadata();\n const { width, height } = metadata.resolution;\n const timestamp = frameNumber / metadata.fps;\n return new Promise((resolve, reject) => {\n const ringBuffer = new RingBuffer();\n const frameSize = width * height;\n const command = ffmpeg.default(this.videoPath)\n .seekInput(timestamp)\n .outputOptions([\n '-vframes', '1',\n '-f', 'image2pipe',\n '-pix_fmt', 'gray',\n '-vcodec', 'rawvideo'\n ])\n .on('error', (err) => {\n reject(new Error(`FFmpeg error: ${err.message}`));\n });\n const stream = command.pipe();\n stream.on('data', (chunk) => {\n ringBuffer.write(chunk);\n if (ringBuffer.available() >= frameSize) {\n const frameData = ringBuffer.read(frameSize);\n const frame = {\n data: new Uint8Array(frameData),\n width,\n height,\n stride: width,\n pts: timestamp,\n frameNumber\n };\n resolve(frame);\n }\n });\n stream.on('error', (err) => {\n reject(new Error(`Stream error: ${err.message}`));\n });\n });\n }\n /**\n * Get the frame buffer\n */\n getFrameBuffer() {\n return this.frameBuffer;\n }\n /**\n * Clean up resources\n */\n destroy() {\n this.frameBuffer.clear();\n }\n}\n//# sourceMappingURL=ffmpeg-decoder.js.map","/**\n * WASM Bridge - Interface between JavaScript and WebAssembly\n *\n * This module handles:\n * - Loading the WASM module\n * - Memory allocation and management\n * - Calling WASM functions\n * - Data marshalling between JS and WASM\n */\nimport * as path from 'path';\nimport * as fs from 'fs';\nexport class WasmBridge {\n constructor() {\n this.module = null;\n this.initialized = false;\n // Pre-allocated WASM buffers for frame processing\n this.prevFramePtr = 0; // Raw previous frame\n this.curFramePtr = 0; // Raw current frame\n this.prevPaddedPtr = 0; // Padded previous frame\n this.curPaddedPtr = 0; // Padded current frame\n this.allocatedFrameSize = 0; // Size of raw frame buffers\n this.allocatedPaddedSize = 0; // Size of padded frame buffers\n }\n /**\n * Initialize the WASM module\n */\n async init() {\n if (this.initialized) {\n return;\n }\n try {\n // Load the WASM module\n const wasmPath = path.join(__dirname, '../dist/detection.wasm.js');\n if (!fs.existsSync(wasmPath)) {\n throw new Error(`WASM module not found at ${wasmPath}. ` +\n `Please run 'npm run build:wasm' to compile the WASM module.`);\n }\n // Dynamic import the WASM module\n const createWasmModule = require(wasmPath);\n this.module = await createWasmModule();\n this.initialized = true;\n }\n catch (error) {\n throw new Error(`Failed to initialize WASM module: ${error}`);\n }\n }\n /**\n * Ensure the WASM module is initialized\n */\n ensureInitialized() {\n if (!this.initialized || !this.module) {\n throw new Error('WASM module not initialized. Call init() first.');\n }\n }\n /**\n * Pre-allocate WASM buffers for frame processing\n * This eliminates per-frame allocation overhead and reduces memory copies\n *\n * @param width Frame width\n * @param height Frame height\n */\n allocateBuffers(width, height) {\n this.ensureInitialized();\n const frameSize = width * height;\n const paddedSize = this.module._calculate_padded_size(width, height);\n // Allocate or re-allocate raw frame buffers if size changed\n if (frameSize !== this.allocatedFrameSize) {\n if (this.prevFramePtr)\n this.module._free(this.prevFramePtr);\n if (this.curFramePtr)\n this.module._free(this.curFramePtr);\n this.prevFramePtr = this.module._malloc(frameSize);\n this.curFramePtr = this.module._malloc(frameSize);\n this.allocatedFrameSize = frameSize;\n }\n // Allocate or re-allocate padded frame buffers if size changed\n if (paddedSize !== this.allocatedPaddedSize) {\n if (this.prevPaddedPtr)\n this.module._free(this.prevPaddedPtr);\n if (this.curPaddedPtr)\n this.module._free(this.curPaddedPtr);\n this.prevPaddedPtr = this.module._malloc(paddedSize);\n this.curPaddedPtr = this.module._malloc(paddedSize);\n this.allocatedPaddedSize = paddedSize;\n }\n }\n /**\n * Detect scene change between two frames\n *\n * Uses pre-allocated WASM buffers to eliminate per-frame allocation\n * and reduce memory copies from 3 to 1 per frame.\n *\n * @param prevFrame Previous frame\n * @param curFrame Current frame\n * @param intraCount Number of consecutive non-scene-change frames\n * @param fcode Motion search range parameter (default: 4 = 256 pixels)\n * @returns true if scene change detected, false otherwise\n */\n detectSceneChange(prevFrame, curFrame, intraCount, fcode = 4) {\n this.ensureInitialized();\n // Validate inputs\n if (prevFrame.width !== curFrame.width || prevFrame.height !== curFrame.height) {\n throw new Error('Frame dimensions must match');\n }\n // Ensure buffers are allocated (should be done once at start)\n if (!this.prevFramePtr || this.allocatedFrameSize !== prevFrame.data.length) {\n this.allocateBuffers(prevFrame.width, prevFrame.height);\n }\n // Single copy: Raw frames -> WASM memory (eliminates 2 extra copies)\n this.module.HEAPU8.set(prevFrame.data, this.prevFramePtr);\n this.module.HEAPU8.set(curFrame.data, this.curFramePtr);\n // Pad frames in-place in WASM (no copy back to JS)\n this.module._pad_frame(this.prevFramePtr, this.prevPaddedPtr, prevFrame.width, prevFrame.height);\n this.module._pad_frame(this.curFramePtr, this.curPaddedPtr, curFrame.width, curFrame.height);\n // Run motion estimation on pre-padded buffers\n const result = this.module._MEanalysis_js(this.prevPaddedPtr, this.curPaddedPtr, prevFrame.width, prevFrame.height, intraCount, fcode);\n return result === 1;\n }\n /**\n * Calculate required buffer size for a padded frame\n *\n * @param width Original frame width\n * @param height Original frame height\n * @returns Required buffer size in bytes\n */\n calculatePaddedSize(width, height) {\n this.ensureInitialized();\n return this.module._calculate_padded_size(width, height);\n }\n /**\n * Get macroblock parameters for a given frame size\n *\n * @param width Frame width\n * @param height Frame height\n * @returns Macroblock parameters\n */\n getMBParam(width, height) {\n const mb_width = Math.ceil(width / 16);\n const mb_height = Math.ceil(height / 16);\n const edge_size = 64;\n return {\n width,\n height,\n mb_width,\n mb_height,\n edged_width: 16 * mb_width + 2 * edge_size,\n edged_height: 16 * mb_height + 2 * edge_size,\n edge_size\n };\n }\n /**\n * Check if the WASM module is initialized\n */\n isInitialized() {\n return this.initialized;\n }\n /**\n * Clean up resources\n */\n destroy() {\n // Free pre-allocated WASM buffers\n if (this.module) {\n if (this.prevFramePtr)\n this.module._free(this.prevFramePtr);\n if (this.curFramePtr)\n this.module._free(this.curFramePtr);\n if (this.prevPaddedPtr)\n this.module._free(this.prevPaddedPtr);\n if (this.curPaddedPtr)\n this.module._free(this.curPaddedPtr);\n }\n this.prevFramePtr = 0;\n this.curFramePtr = 0;\n this.prevPaddedPtr = 0;\n this.curPaddedPtr = 0;\n this.allocatedFrameSize = 0;\n this.allocatedPaddedSize = 0;\n this.module = null;\n this.initialized = false;\n }\n}\n//# sourceMappingURL=wasm-bridge.js.map","/**\n * Frame Processor - Utilities for frame preprocessing\n */\n/**\n * Format timestamp as timecode (HH:MM:SS.mmm)\n */\nexport function formatTimecode(seconds) {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n const ms = Math.floor((seconds % 1) * 1000);\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;\n}\n/**\n * Calculate macroblock parameters for frame dimensions\n */\nexport function calculateMBParam(width, height) {\n const mb_width = Math.ceil(width / 16);\n const mb_height = Math.ceil(height / 16);\n const edge_size = 64;\n return {\n width,\n height,\n mb_width,\n mb_height,\n edged_width: 16 * mb_width + 2 * edge_size,\n edged_height: 16 * mb_height + 2 * edge_size,\n edge_size\n };\n}\n/**\n * Check if frame dimensions are valid\n */\nexport function validateFrameDimensions(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error(`Invalid frame dimensions: ${width}x${height}`);\n }\n if (width > 8192 || height > 8192) {\n throw new Error(`Frame dimensions too large: ${width}x${height} (max: 8192x8192)`);\n }\n}\n/**\n * Calculate fcode from search range option\n */\nexport function calculateFcode(searchRange, width, height) {\n switch (searchRange) {\n case 'small':\n return 2; // 64 pixel range\n case 'medium':\n return 4; // 256 pixel range (default)\n case 'large':\n return 6; // 1024 pixel range\n case 'auto':\n // Auto-adjust based on resolution\n const pixels = width * height;\n if (pixels <= 720 * 480)\n return 3; // SD: 128px\n if (pixels <= 1920 * 1080)\n return 4; // HD: 256px\n return 5; // 4K+: 512px\n default:\n return 4;\n }\n}\n/**\n * Calculate adaptive thresholds based on sensitivity\n */\nexport function calculateThresholds(sensitivity) {\n switch (sensitivity) {\n case 'low':\n return { intraThresh: 3000, intraThresh2: 150 }; // Less sensitive\n case 'medium':\n return { intraThresh: 2000, intraThresh2: 90 }; // Default\n case 'high':\n return { intraThresh: 1000, intraThresh2: 50 }; // More sensitive\n case 'custom':\n // Will be overridden by customThresholds\n return { intraThresh: 2000, intraThresh2: 90 };\n default:\n return { intraThresh: 2000, intraThresh2: 90 };\n }\n}\n/**\n * Validate frame data\n */\nexport function validateFrame(frame) {\n if (!frame.data || frame.data.length === 0) {\n throw new Error('Frame data is empty');\n }\n const expectedSize = frame.width * frame.height;\n if (frame.data.length < expectedSize) {\n throw new Error(`Frame data size mismatch: expected at least ${expectedSize}, got ${frame.data.length}`);\n }\n validateFrameDimensions(frame.width, frame.height);\n}\n/**\n * Calculate memory usage for frame\n */\nexport function calculateFrameMemory(width, height) {\n const mbParam = calculateMBParam(width, height);\n return mbParam.edged_width * mbParam.edged_height;\n}\n/**\n * Estimate processing time based on frame count and resolution\n */\nexport function estimateProcessingTime(frameCount, width, height, targetFps = 60) {\n // Rough estimate: higher resolution = slower\n const resolutionFactor = (width * height) / (1920 * 1080);\n const adjustedFps = targetFps / resolutionFactor;\n return frameCount / adjustedFps;\n}\n//# sourceMappingURL=frame-processor.js.map","/**\n * Scene Detector - Main orchestrator for scene change detection\n */\nimport { FFmpegDecoder } from '../decoder/ffmpeg-decoder';\nimport { WasmBridge } from './wasm-bridge';\nimport { formatTimecode, calculateFcode, validateFrame } from '../utils/frame-processor';\nexport class SceneDetector {\n constructor(options = {}) {\n // Set default options\n this.options = {\n sensitivity: options.sensitivity || 'medium',\n customThresholds: options.customThresholds || { intraThresh: 2000, intraThresh2: 90 },\n searchRange: options.searchRange || 'medium',\n workers: options.workers || 1, // Multi-threading not implemented yet\n progressive: options.progressive || { enabled: false, initialStep: 1, refinementSteps: [] },\n temporalSmoothing: options.temporalSmoothing || { enabled: false, windowSize: 5, minConsecutive: 2 },\n frameExtraction: options.frameExtraction || { pixelFormat: 'gray', maxBufferFrames: 2 },\n onProgress: options.onProgress || (() => { }),\n onScene: options.onScene || (() => { }),\n format: options.format || 'json'\n };\n this.wasmBridge = new WasmBridge();\n // Initialize detection state\n this.state = {\n intraCount: 1,\n fcode: 4,\n prevFrame: null,\n curFrame: null\n };\n }\n /**\n * Detect scene changes in a video file\n */\n async detect(videoPath) {\n // Initialize WASM module\n await this.wasmBridge.init();\n // Create decoder\n const decoder = new FFmpegDecoder(videoPath, {\n pixelFormat: this.options.frameExtraction.pixelFormat,\n maxBufferFrames: this.options.frameExtraction.maxBufferFrames,\n skipFrames: this.options.frameExtraction.skipFrames\n });\n // Get video metadata\n const metadata = await decoder.getMetadata();\n // Calculate fcode from search range\n this.state.fcode = calculateFcode(this.options.searchRange, metadata.resolution.width, metadata.resolution.height);\n // Pre-allocate WASM buffers (eliminates per-frame allocation overhead)\n this.wasmBridge.allocateBuffers(metadata.resolution.width, metadata.resolution.height);\n // Initialize scene list (frame 0 is always a scene change)\n const scenes = [\n {\n frameNumber: 0,\n timestamp: 0,\n timecode: '00:00:00.000'\n }\n ];\n // Processing statistics\n const startTime = Date.now();\n let processedFrames = 0;\n // Process frames\n await decoder.extractFrames(async (frame) => {\n validateFrame(frame);\n // Update current frame\n this.state.curFrame = frame;\n // Need at least 2 frames to detect scene change\n if (this.state.prevFrame) {\n const isSceneChange = this.wasmBridge.detectSceneChange(this.state.prevFrame, this.state.curFrame, this.state.intraCount, this.state.fcode);\n if (isSceneChange) {\n const scene = {\n frameNumber: frame.frameNumber,\n timestamp: frame.pts,\n timecode: formatTimecode(frame.pts)\n };\n scenes.push(scene);\n // Call scene callback\n this.options.onScene(scene);\n // Reset intraCount\n this.state.intraCount = 1;\n }\n else {\n // Increment intraCount\n this.state.intraCount++;\n }\n }\n // Move current frame to previous\n this.state.prevFrame = this.state.curFrame;\n processedFrames++;\n }, (current, total) => {\n // Progress callback\n const progress = {\n currentFrame: current,\n totalFrames: total,\n percent: Math.round((current / total) * 100)\n };\n // Calculate ETA\n const elapsed = (Date.now() - startTime) / 1000;\n const fps = current / elapsed;\n const remaining = (total - current) / fps;\n progress.eta = remaining;\n this.options.onProgress(progress);\n });\n // Calculate statistics\n const endTime = Date.now();\n const processingTime = (endTime - startTime) / 1000;\n const framesPerSecond = processedFrames / processingTime;\n // Clean up\n decoder.destroy();\n return {\n scenes,\n metadata,\n stats: {\n processingTime,\n framesPerSecond\n }\n };\n }\n /**\n * Destroy the detector and clean up resources\n */\n destroy() {\n this.wasmBridge.destroy();\n this.state.prevFrame = null;\n this.state.curFrame = null;\n }\n}\n//# sourceMappingURL=detector.js.map","/**\n * keyframes - Scene change detection for Node.js\n *\n * A JavaScript/TypeScript port of vapoursynth-wwxd using Xvid's motion estimation algorithm.\n * Powered by WebAssembly for high performance.\n */\nexport { SceneDetector } from './detection/detector';\nexport { FFmpegDecoder } from './decoder/ffmpeg-decoder';\nexport { WasmBridge } from './detection/wasm-bridge';\nexport { FrameBuffer } from './decoder/frame-buffer';\nexport { BufferPool } from './utils/buffer-pool';\n// Export utilities\nexport { formatTimecode, calculateFcode, calculateThresholds, validateFrame, validateFrameDimensions, calculateMBParam, calculateFrameMemory, estimateProcessingTime } from './utils/frame-processor';\nimport { SceneDetector } from './detection/detector';\n/**\n * Detect scene changes in a video file (simple API)\n *\n * @param videoPath Path to video file\n * @param options Detection options\n * @returns Detection results with scene changes and metadata\n *\n * @example\n * ```typescript\n * import { detectSceneChanges } from 'keyframes';\n *\n * const results = await detectSceneChanges('input.mp4');\n * console.log(`Found ${results.scenes.length} scenes`);\n *\n * results.scenes.forEach(scene => {\n * console.log(`Scene at ${scene.timecode}`);\n * });\n * ```\n */\nexport async function detectSceneChanges(videoPath, options) {\n const detector = new SceneDetector(options);\n try {\n const results = await detector.detect(videoPath);\n return results;\n }\n finally {\n detector.destroy();\n }\n}\n/**\n * Version information\n */\nexport const version = '1.0.0';\n/**\n * Library information\n */\nexport const info = {\n name: 'keyframes',\n version: '1.0.0',\n description: 'Scene change detection for Node.js using Xvid\\'s motion estimation algorithm',\n license: 'GPL-2.0',\n repository: 'https://github.com/yourusername/keyframes',\n author: '',\n credits: {\n original: 'vapoursynth-wwxd by dubhater (https://github.com/dubhater/vapoursynth-wwxd)',\n algorithm: 'Xvid motion estimation (https://www.xvid.com)'\n }\n};\n//# sourceMappingURL=index.js.map"],"names":["ffmpeg","ffmpegInstaller","ffprobeInstaller","path","fs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keyframes.cjs.js","sources":["utils/buffer-pool.js","decoder/frame-buffer.js","decoder/ffmpeg-decoder.js","detection/wasm-bridge.js","detection/temporal-smoother.js","utils/frame-processor.js","detection/detector.js","index.js"],"sourcesContent":["/**\n * Buffer Pool - Memory management for frame buffers\n *\n * Reuses TypedArray buffers to reduce memory allocation and GC pressure\n */\nexport class BufferPool {\n /**\n * Create a new buffer pool\n *\n * @param maxPoolSize Maximum number of buffers to keep per size (default: 4)\n */\n constructor(maxPoolSize = 4) {\n this.pool = new Map();\n this.maxPoolSize = maxPoolSize;\n }\n /**\n * Acquire a buffer of the specified size\n *\n * @param size Buffer size in bytes\n * @returns Uint8Array buffer\n */\n acquire(size) {\n const poolForSize = this.pool.get(size);\n if (poolForSize && poolForSize.length > 0) {\n const buffer = poolForSize.pop();\n // Clear the buffer before reuse\n buffer.fill(0);\n return buffer;\n }\n // No buffer available, allocate new one\n return new Uint8Array(size);\n }\n /**\n * Release a buffer back to the pool\n *\n * @param buffer Buffer to release\n */\n release(buffer) {\n const size = buffer.length;\n let poolForSize = this.pool.get(size);\n if (!poolForSize) {\n poolForSize = [];\n this.pool.set(size, poolForSize);\n }\n // Only keep buffer if pool not full\n if (poolForSize.length < this.maxPoolSize) {\n poolForSize.push(buffer);\n }\n // Otherwise, let it be garbage collected\n }\n /**\n * Get pool statistics\n */\n getStats() {\n const stats = [];\n for (const [size, buffers] of this.pool.entries()) {\n stats.push({\n size,\n count: buffers.length\n });\n }\n return stats.sort((a, b) => b.size - a.size);\n }\n /**\n * Clear all pooled buffers\n */\n clear() {\n this.pool.clear();\n }\n /**\n * Get total memory used by pooled buffers\n */\n getTotalMemory() {\n let total = 0;\n for (const [size, buffers] of this.pool.entries()) {\n total += size * buffers.length;\n }\n return total;\n }\n}\n//# sourceMappingURL=buffer-pool.js.map","/**\n * Frame Buffer - Circular buffer for frame management\n *\n * Maintains a circular buffer of frames for efficient scene detection\n * Typically only needs to hold 2 frames (previous and current)\n */\nimport { BufferPool } from '../utils/buffer-pool';\nexport class FrameBuffer {\n /**\n * Create a new frame buffer\n *\n * @param maxFrames Maximum number of frames to buffer (default: 2)\n * @param bufferPool Optional buffer pool for memory reuse\n */\n constructor(maxFrames = 2, bufferPool) {\n this.currentIndex = 0;\n this.maxFrames = maxFrames;\n this.bufferPool = bufferPool || new BufferPool();\n this.frames = new Array(maxFrames).fill(null);\n }\n /**\n * Push a new frame into the buffer\n *\n * @param frame Frame to push\n * @returns The frame that was evicted, if any\n */\n push(frame) {\n const evictedFrame = this.frames[this.currentIndex];\n // Release the evicted frame's buffer back to pool\n if (evictedFrame) {\n this.bufferPool.release(evictedFrame.data);\n }\n // Store the new frame\n this.frames[this.currentIndex] = frame;\n // Move to next position\n this.currentIndex = (this.currentIndex + 1) % this.maxFrames;\n return evictedFrame;\n }\n /**\n * Get frame at specific offset from current position\n *\n * @param offset Offset from current position (0 = most recent, 1 = previous, etc.)\n * @returns Frame or null if not available\n */\n get(offset = 0) {\n if (offset < 0 || offset >= this.maxFrames) {\n return null;\n }\n const index = (this.currentIndex - 1 - offset + this.maxFrames) % this.maxFrames;\n return this.frames[index];\n }\n /**\n * Get the most recent frame\n */\n getCurrent() {\n return this.get(0);\n }\n /**\n * Get the previous frame\n */\n getPrevious() {\n return this.get(1);\n }\n /**\n * Get both current and previous frames\n *\n * @returns [current, previous] or null if either is not available\n */\n getCurrentAndPrevious() {\n const current = this.getCurrent();\n const previous = this.getPrevious();\n if (!current || !previous) {\n return null;\n }\n return [current, previous];\n }\n /**\n * Allocate a buffer for a new frame\n *\n * @param size Buffer size in bytes\n * @returns Uint8Array buffer\n */\n allocateBuffer(size) {\n return this.bufferPool.acquire(size);\n }\n /**\n * Clear all frames from the buffer\n */\n clear() {\n // Release all buffers back to pool\n for (const frame of this.frames) {\n if (frame) {\n this.bufferPool.release(frame.data);\n }\n }\n this.frames = new Array(this.maxFrames).fill(null);\n this.currentIndex = 0;\n }\n /**\n * Get the number of frames currently in the buffer\n */\n size() {\n return this.frames.filter(f => f !== null).length;\n }\n /**\n * Check if buffer is full\n */\n isFull() {\n return this.size() === this.maxFrames;\n }\n /**\n * Get buffer statistics\n */\n getStats() {\n return {\n maxFrames: this.maxFrames,\n currentFrames: this.size(),\n bufferPoolStats: this.bufferPool.getStats(),\n totalPoolMemory: this.bufferPool.getTotalMemory()\n };\n }\n}\n//# sourceMappingURL=frame-buffer.js.map","/**\n * FFmpeg Decoder - Extract frames from video files\n *\n * Uses fluent-ffmpeg to extract grayscale frames for scene detection\n */\nimport * as ffmpeg from 'fluent-ffmpeg';\nimport * as ffmpegInstaller from '@ffmpeg-installer/ffmpeg';\nimport * as ffprobeInstaller from '@ffprobe-installer/ffprobe';\nimport { FrameBuffer } from './frame-buffer';\nimport * as path from 'path';\nimport * as fs from 'fs';\n// Set FFmpeg and FFprobe paths from installers\nffmpeg.setFfmpegPath(ffmpegInstaller.path);\nffmpeg.setFfprobePath(ffprobeInstaller.path);\n/**\n * Ring Buffer - Fixed-size circular buffer for streaming data\n * Eliminates repeated Buffer.concat() allocations and GC pressure\n */\nclass RingBuffer {\n constructor(size = 8 * 1024 * 1024) {\n this.writePos = 0;\n this.readPos = 0;\n this.availableBytes = 0;\n this.buffer = Buffer.allocUnsafe(size);\n this.capacity = size;\n }\n /**\n * Write data to the ring buffer\n */\n write(chunk) {\n const chunkSize = chunk.length;\n if (chunkSize > this.capacity - this.availableBytes) {\n throw new Error('RingBuffer overflow: chunk too large for available space');\n }\n // Write in two parts if wrapping around\n const endSpace = this.capacity - this.writePos;\n if (chunkSize <= endSpace) {\n // No wrap-around needed\n chunk.copy(this.buffer, this.writePos);\n this.writePos += chunkSize;\n }\n else {\n // Wrap-around: split write\n chunk.copy(this.buffer, this.writePos, 0, endSpace);\n chunk.copy(this.buffer, 0, endSpace, chunkSize);\n this.writePos = chunkSize - endSpace;\n }\n // Wrap write position if at end\n if (this.writePos >= this.capacity) {\n this.writePos = 0;\n }\n this.availableBytes += chunkSize;\n }\n /**\n * Read data from the ring buffer (allocates new buffer)\n */\n read(size) {\n if (size > this.availableBytes) {\n throw new Error('RingBuffer underflow: not enough data available');\n }\n const result = Buffer.allocUnsafe(size);\n this.readIntoBuffer(result, 0, size);\n return result;\n }\n /**\n * Read data directly into a pre-allocated Uint8Array (zero-allocation)\n */\n readInto(target, offset, size) {\n if (size > this.availableBytes) {\n throw new Error('RingBuffer underflow: not enough data available');\n }\n const endSpace = this.capacity - this.readPos;\n if (size <= endSpace) {\n // No wrap-around needed\n for (let i = 0; i < size; i++) {\n target[offset + i] = this.buffer[this.readPos + i];\n }\n this.readPos += size;\n }\n else {\n // Wrap-around: split read\n for (let i = 0; i < endSpace; i++) {\n target[offset + i] = this.buffer[this.readPos + i];\n }\n const remaining = size - endSpace;\n for (let i = 0; i < remaining; i++) {\n target[offset + endSpace + i] = this.buffer[i];\n }\n this.readPos = remaining;\n }\n // Wrap read position if at end\n if (this.readPos >= this.capacity) {\n this.readPos = 0;\n }\n this.availableBytes -= size;\n }\n /**\n * Internal: read into a Node.js Buffer\n */\n readIntoBuffer(result, offset, size) {\n const endSpace = this.capacity - this.readPos;\n if (size <= endSpace) {\n this.buffer.copy(result, offset, this.readPos, this.readPos + size);\n this.readPos += size;\n }\n else {\n this.buffer.copy(result, offset, this.readPos, this.capacity);\n this.buffer.copy(result, offset + endSpace, 0, size - endSpace);\n this.readPos = size - endSpace;\n }\n if (this.readPos >= this.capacity) {\n this.readPos = 0;\n }\n this.availableBytes -= size;\n }\n /**\n * Get number of bytes available to read\n */\n available() {\n return this.availableBytes;\n }\n /**\n * Reset the ring buffer\n */\n reset() {\n this.writePos = 0;\n this.readPos = 0;\n this.availableBytes = 0;\n }\n}\nexport class FFmpegDecoder {\n constructor(videoPath, options = {}) {\n this.metadata = null;\n this.videoPath = videoPath;\n this.options = {\n pixelFormat: options.pixelFormat || 'gray',\n maxBufferFrames: options.maxBufferFrames || 2,\n skipFrames: options.skipFrames || 0\n };\n this.frameBuffer = new FrameBuffer(this.options.maxBufferFrames);\n }\n /**\n * Get video metadata (with richer codec/format info)\n */\n async getMetadata() {\n if (this.metadata) {\n return this.metadata;\n }\n return new Promise((resolve, reject) => {\n ffmpeg.ffprobe(this.videoPath, (err, metadata) => {\n if (err) {\n reject(new Error(`Failed to read video metadata: ${err.message}`));\n return;\n }\n const videoStream = metadata.streams.find(s => s.codec_type === 'video');\n if (!videoStream) {\n reject(new Error('No video stream found'));\n return;\n }\n const fps = this.parseFps(videoStream.r_frame_rate || videoStream.avg_frame_rate || '30/1');\n const duration = parseFloat(String(metadata.format.duration || 0));\n const totalFrames = Math.floor(duration * fps);\n this.metadata = {\n totalFrames,\n duration,\n fps,\n resolution: {\n width: videoStream.width || 0,\n height: videoStream.height || 0\n },\n codec: videoStream.codec_name || undefined,\n pixelFormat: videoStream.pix_fmt || undefined,\n bitrate: metadata.format.bit_rate ? parseInt(String(metadata.format.bit_rate)) : undefined\n };\n resolve(this.metadata);\n });\n });\n }\n /**\n * Parse frame rate from FFmpeg format (e.g., \"30000/1001\")\n */\n parseFps(fpsString) {\n const parts = fpsString.split('/');\n if (parts.length === 2) {\n return parseInt(parts[0]) / parseInt(parts[1]);\n }\n return parseFloat(fpsString);\n }\n /**\n * Extract frames as grayscale data\n *\n * Uses pre-allocated alternating buffers to eliminate double allocation.\n * Auto-sizes ring buffer based on video resolution.\n *\n * @param onFrame Callback for each frame\n * @param onProgress Optional progress callback\n * @param signal Optional AbortSignal for cancellation\n */\n async extractFrames(onFrame, onProgress, signal) {\n const metadata = await this.getMetadata();\n const { width, height } = metadata.resolution;\n return new Promise((resolve, reject) => {\n let frameNumber = 0;\n const frameSize = width * height; // Grayscale: 1 byte per pixel\n // Auto-size ring buffer based on resolution (min 4MB, fits 3 frames)\n const ringBufferSize = Math.max(4 * 1024 * 1024, frameSize * 3);\n const ringBuffer = new RingBuffer(ringBufferSize);\n // Pre-allocate two alternating frame buffers (eliminates double allocation)\n const frameBufferA = new Uint8Array(frameSize);\n const frameBufferB = new Uint8Array(frameSize);\n let useBufferA = true;\n const command = ffmpeg.default(this.videoPath)\n .outputOptions([\n '-f', 'image2pipe',\n '-pix_fmt', 'gray',\n '-vcodec', 'rawvideo'\n ])\n .on('error', (err) => {\n reject(new Error(`FFmpeg error: ${err.message}`));\n })\n .on('end', () => {\n resolve();\n });\n const stream = command.pipe();\n // Listen for abort signal\n if (signal) {\n const onAbort = () => {\n stream.destroy();\n reject(new Error('Detection aborted'));\n };\n if (signal.aborted) {\n stream.destroy();\n reject(new Error('Detection aborted'));\n return;\n }\n signal.addEventListener('abort', onAbort, { once: true });\n }\n stream.on('data', async (chunk) => {\n // Write chunk to ring buffer\n ringBuffer.write(chunk);\n // Process complete frames\n while (ringBuffer.available() >= frameSize) {\n // Skip frames if requested\n if (this.options.skipFrames > 0 && frameNumber % (this.options.skipFrames + 1) !== 0) {\n // Still need to consume the data from the ring buffer\n ringBuffer.read(frameSize);\n frameNumber++;\n continue;\n }\n // Read directly into pre-allocated buffer (zero-allocation)\n const targetBuffer = useBufferA ? frameBufferA : frameBufferB;\n ringBuffer.readInto(targetBuffer, 0, frameSize);\n useBufferA = !useBufferA;\n // Create RawFrame (reuses the pre-allocated buffer - no copy)\n const frame = {\n data: targetBuffer,\n width,\n height,\n stride: width,\n pts: frameNumber / metadata.fps,\n frameNumber\n };\n // Call callback\n try {\n await onFrame(frame);\n }\n catch (err) {\n stream.destroy();\n reject(err);\n return;\n }\n // Progress callback\n if (onProgress && frameNumber % 30 === 0) {\n onProgress(frameNumber, metadata.totalFrames);\n }\n frameNumber++;\n }\n });\n stream.on('error', (err) => {\n reject(new Error(`Stream error: ${err.message}`));\n });\n });\n }\n /**\n * Extract a single frame at specific frame number\n */\n async extractFrame(frameNumber) {\n const metadata = await this.getMetadata();\n const { width, height } = metadata.resolution;\n const timestamp = frameNumber / metadata.fps;\n return new Promise((resolve, reject) => {\n const ringBuffer = new RingBuffer();\n const frameSize = width * height;\n const command = ffmpeg.default(this.videoPath)\n .seekInput(timestamp)\n .outputOptions([\n '-vframes', '1',\n '-f', 'image2pipe',\n '-pix_fmt', 'gray',\n '-vcodec', 'rawvideo'\n ])\n .on('error', (err) => {\n reject(new Error(`FFmpeg error: ${err.message}`));\n });\n const stream = command.pipe();\n stream.on('data', (chunk) => {\n ringBuffer.write(chunk);\n if (ringBuffer.available() >= frameSize) {\n const frameData = ringBuffer.read(frameSize);\n const frame = {\n data: new Uint8Array(frameData),\n width,\n height,\n stride: width,\n pts: timestamp,\n frameNumber\n };\n resolve(frame);\n }\n });\n stream.on('error', (err) => {\n reject(new Error(`Stream error: ${err.message}`));\n });\n });\n }\n /**\n * Extract multiple frame images in a single FFmpeg invocation\n * Uses FFmpeg's select filter to avoid N+1 process spawning\n *\n * @param frameNumbers Array of frame numbers to extract\n * @param options Image extraction options\n */\n async extractFrameImages(frameNumbers, options) {\n const metadata = await this.getMetadata();\n // Ensure output directory exists\n if (!fs.existsSync(options.outputDir)) {\n fs.mkdirSync(options.outputDir, { recursive: true });\n }\n const format = options.format || 'jpg';\n const quality = options.quality || 85;\n const template = options.filenameTemplate || 'scene_{frame}';\n // Build FFmpeg select filter expression\n // select='eq(n,100)+eq(n,200)+eq(n,300)'\n const selectExpr = frameNumbers.map(n => `eq(n\\\\,${n})`).join('+');\n return new Promise((resolve, reject) => {\n const outputPaths = [];\n // Generate output filenames\n for (const frameNum of frameNumbers) {\n const timestamp = frameNum / metadata.fps;\n const filename = template\n .replace('{frame}', String(frameNum))\n .replace('{timestamp}', timestamp.toFixed(3));\n outputPaths.push(path.join(options.outputDir, `${filename}.${format}`));\n }\n // Use FFmpeg with select filter and output pattern\n const outputPattern = path.join(options.outputDir, `${template.replace('{frame}', '%d').replace('{timestamp}', '%d')}.${format}`);\n const outputOptions = [\n '-vf', `select='${selectExpr}',setpts=N/TB`,\n '-vsync', 'vfr'\n ];\n if (format === 'jpg') {\n outputOptions.push('-qscale:v', String(Math.round((100 - quality) / 3.33)));\n }\n if (options.width) {\n outputOptions.push('-vf', `select='${selectExpr}',scale=${options.width}:-1,setpts=N/TB`);\n }\n ffmpeg.default(this.videoPath)\n .outputOptions(outputOptions)\n .output(outputPattern)\n .on('error', (err) => {\n reject(new Error(`FFmpeg frame extraction error: ${err.message}`));\n })\n .on('end', () => {\n resolve(outputPaths);\n })\n .run();\n });\n }\n /**\n * Get the frame buffer\n */\n getFrameBuffer() {\n return this.frameBuffer;\n }\n /**\n * Clean up resources\n */\n destroy() {\n this.frameBuffer.clear();\n }\n}\n//# sourceMappingURL=ffmpeg-decoder.js.map","/**\n * WASM Bridge - Interface between JavaScript and WebAssembly\n *\n * This module handles:\n * - Loading the WASM module\n * - Memory allocation and management\n * - Calling WASM functions\n * - Data marshalling between JS and WASM\n * - Double-buffering to avoid redundant frame copies\n */\nimport * as path from 'path';\nimport * as fs from 'fs';\nexport class WasmBridge {\n constructor() {\n this.module = null;\n this.initialized = false;\n // Double-buffered WASM pointers for frame processing\n // Slot A and Slot B raw frame buffers\n this.slotARawPtr = 0;\n this.slotBRawPtr = 0;\n // Slot A and Slot B padded frame buffers\n this.slotAPaddedPtr = 0;\n this.slotBPaddedPtr = 0;\n // Which slot currently holds the \"previous\" frame (true = A, false = B)\n this.prevIsSlotA = true;\n // Whether the previous slot has valid padded data\n this.prevSlotPadded = false;\n this.allocatedFrameSize = 0;\n this.allocatedPaddedSize = 0;\n }\n // Frame dimensions (reserved for future use in validation/resizing)\n /**\n * Initialize the WASM module\n */\n async init() {\n if (this.initialized) {\n return;\n }\n try {\n // Load the WASM module\n const wasmPath = path.join(__dirname, '../dist/detection.wasm.js');\n if (!fs.existsSync(wasmPath)) {\n throw new Error(`WASM module not found at ${wasmPath}. ` +\n `Please run 'npm run build:wasm' to compile the WASM module.`);\n }\n // Dynamic import the WASM module\n const createWasmModule = require(wasmPath);\n this.module = await createWasmModule();\n this.initialized = true;\n }\n catch (error) {\n throw new Error(`Failed to initialize WASM module: ${error}`);\n }\n }\n /**\n * Ensure the WASM module is initialized\n */\n ensureInitialized() {\n if (!this.initialized || !this.module) {\n throw new Error('WASM module not initialized. Call init() first.');\n }\n }\n /**\n * Pre-allocate WASM buffers for frame processing.\n * Allocates double-buffered raw + padded slots and pre-allocates the MB array.\n */\n allocateBuffers(width, height) {\n this.ensureInitialized();\n const frameSize = width * height;\n const paddedSize = this.module._calculate_padded_size(width, height);\n // Allocate or re-allocate raw frame buffers if size changed\n if (frameSize !== this.allocatedFrameSize) {\n if (this.slotARawPtr)\n this.module._free(this.slotARawPtr);\n if (this.slotBRawPtr)\n this.module._free(this.slotBRawPtr);\n this.slotARawPtr = this.module._malloc(frameSize);\n this.slotBRawPtr = this.module._malloc(frameSize);\n this.allocatedFrameSize = frameSize;\n }\n // Allocate or re-allocate padded frame buffers if size changed\n if (paddedSize !== this.allocatedPaddedSize) {\n if (this.slotAPaddedPtr)\n this.module._free(this.slotAPaddedPtr);\n if (this.slotBPaddedPtr)\n this.module._free(this.slotBPaddedPtr);\n this.slotAPaddedPtr = this.module._malloc(paddedSize);\n this.slotBPaddedPtr = this.module._malloc(paddedSize);\n this.allocatedPaddedSize = paddedSize;\n }\n // Reset double-buffer state\n this.prevIsSlotA = true;\n this.prevSlotPadded = false;\n // Pre-allocate macroblock array in WASM\n const mbResult = this.module._allocate_mb_array(width, height);\n if (mbResult === 0) {\n throw new Error('Failed to pre-allocate macroblock array in WASM');\n }\n }\n /**\n * Detect scene change between two frames using double-buffering.\n *\n * On first call, both frames are copied and padded.\n * On subsequent calls, only the new current frame is copied and padded;\n * the previous frame is already in WASM memory from the last call.\n *\n * @param prevFrame Previous frame\n * @param curFrame Current frame\n * @param intraCount Number of consecutive non-scene-change frames\n * @param fcode Motion search range parameter\n * @param intraThresh Primary intra threshold\n * @param intraThresh2 Secondary intra threshold (sSAD comparison)\n * @returns Scene change result with confidence score\n */\n detectSceneChange(prevFrame, curFrame, intraCount, fcode = 4, intraThresh = 2000, intraThresh2 = 90) {\n this.ensureInitialized();\n // Validate inputs\n if (prevFrame.width !== curFrame.width || prevFrame.height !== curFrame.height) {\n throw new Error('Frame dimensions must match');\n }\n // Ensure buffers are allocated\n if (!this.slotARawPtr || this.allocatedFrameSize !== prevFrame.data.length) {\n this.allocateBuffers(prevFrame.width, prevFrame.height);\n }\n // Determine which slot is \"prev\" and which is \"cur\"\n const prevRawPtr = this.prevIsSlotA ? this.slotARawPtr : this.slotBRawPtr;\n const prevPaddedPtr = this.prevIsSlotA ? this.slotAPaddedPtr : this.slotBPaddedPtr;\n const curRawPtr = this.prevIsSlotA ? this.slotBRawPtr : this.slotARawPtr;\n const curPaddedPtr = this.prevIsSlotA ? this.slotBPaddedPtr : this.slotAPaddedPtr;\n // Copy and pad previous frame only if not already valid in WASM\n if (!this.prevSlotPadded) {\n this.module.HEAPU8.set(prevFrame.data, prevRawPtr);\n this.module._pad_frame(prevRawPtr, prevPaddedPtr, prevFrame.width, prevFrame.height);\n }\n // Always copy and pad the new current frame\n this.module.HEAPU8.set(curFrame.data, curRawPtr);\n this.module._pad_frame(curRawPtr, curPaddedPtr, curFrame.width, curFrame.height);\n // Run motion estimation with parameterized thresholds\n const rawScore = this.module._MEanalysis_js(prevPaddedPtr, curPaddedPtr, prevFrame.width, prevFrame.height, intraCount, fcode, intraThresh, intraThresh2);\n // Check for WASM error\n if (rawScore === -1) {\n throw new Error('WASM memory allocation failed during scene detection. ' +\n `Frame size: ${prevFrame.width}x${prevFrame.height}. ` +\n 'The video resolution may be too high for available WASM memory.');\n }\n // Swap roles: current slot becomes previous for next call\n this.prevIsSlotA = !this.prevIsSlotA;\n this.prevSlotPadded = true;\n // Determine scene change and confidence\n const isSceneChange = rawScore >= intraThresh2;\n // Normalize confidence: 0 when at threshold, 1 at 2x threshold\n // For non-scene-changes, confidence represents \"how close\" (0 = very far from threshold)\n let confidence;\n if (isSceneChange) {\n confidence = Math.min(1.0, rawScore / (intraThresh2 * 2));\n }\n else {\n confidence = intraThresh2 > 0 ? Math.min(1.0, rawScore / intraThresh2) : 0;\n }\n return { isSceneChange, confidence };\n }\n /**\n * Reset double-buffer state (e.g., after a seek or when starting fresh)\n */\n resetBufferState() {\n this.prevIsSlotA = true;\n this.prevSlotPadded = false;\n }\n /**\n * Calculate required buffer size for a padded frame\n */\n calculatePaddedSize(width, height) {\n this.ensureInitialized();\n return this.module._calculate_padded_size(width, height);\n }\n /**\n * Get macroblock parameters for a given frame size\n */\n getMBParam(width, height) {\n const mb_width = Math.ceil(width / 16);\n const mb_height = Math.ceil(height / 16);\n const edge_size = 64;\n return {\n width,\n height,\n mb_width,\n mb_height,\n edged_width: 16 * mb_width + 2 * edge_size,\n edged_height: 16 * mb_height + 2 * edge_size,\n edge_size\n };\n }\n /**\n * Check if the WASM module is initialized\n */\n isInitialized() {\n return this.initialized;\n }\n /**\n * Clean up resources\n */\n destroy() {\n if (this.module) {\n // Free pre-allocated macroblock array\n this.module._free_mb_array();\n // Free double-buffered WASM frame buffers\n if (this.slotARawPtr)\n this.module._free(this.slotARawPtr);\n if (this.slotBRawPtr)\n this.module._free(this.slotBRawPtr);\n if (this.slotAPaddedPtr)\n this.module._free(this.slotAPaddedPtr);\n if (this.slotBPaddedPtr)\n this.module._free(this.slotBPaddedPtr);\n }\n this.slotARawPtr = 0;\n this.slotBRawPtr = 0;\n this.slotAPaddedPtr = 0;\n this.slotBPaddedPtr = 0;\n this.allocatedFrameSize = 0;\n this.allocatedPaddedSize = 0;\n this.prevSlotPadded = false;\n this.module = null;\n this.initialized = false;\n }\n}\n//# sourceMappingURL=wasm-bridge.js.map","/**\n * Temporal Smoother - Sliding window filter to reduce false positives\n *\n * Three rules:\n * 1. Minimum gap: Suppress detections within minConsecutive frames of each other (keep highest confidence)\n * 2. Flash suppression: Isolated single-frame detections with low confidence are suppressed\n * 3. Cluster merging: Consecutive triggered frames (common in dissolves) keep only highest-confidence one\n */\nexport class TemporalSmoother {\n constructor(config) {\n // Sliding window of recent detections\n this.recentDetections = [];\n // Last confirmed scene change frame\n this.lastConfirmedFrame = 0;\n // Buffer for cluster detection\n this.pendingCluster = [];\n this.nonDetectionCount = 0;\n // Flash suppression: minimum confidence for isolated detections\n this.flashConfidenceThreshold = 0.4;\n this.windowSize = config.windowSize;\n this.minConsecutive = config.minConsecutive;\n }\n /**\n * Process a frame's detection result through temporal smoothing\n */\n process(frameNumber, rawIsSceneChange, rawConfidence) {\n // If no detection, track gap and possibly flush pending cluster\n if (!rawIsSceneChange) {\n this.nonDetectionCount++;\n // If we had a pending cluster and enough non-detections have passed,\n // emit the best detection from the cluster\n if (this.pendingCluster.length > 0 && this.nonDetectionCount >= 2) {\n const best = this.flushCluster();\n if (best) {\n return best;\n }\n }\n return { isSceneChange: false, confidence: 0 };\n }\n // We have a detection\n this.nonDetectionCount = 0;\n // Rule 1: Minimum gap enforcement\n if (frameNumber - this.lastConfirmedFrame < this.minConsecutive) {\n // Too close to last confirmed scene change\n // If this has higher confidence, replace pending, but don't emit yet\n if (this.pendingCluster.length > 0) {\n const best = this.pendingCluster.reduce((a, b) => a.confidence > b.confidence ? a : b);\n if (rawConfidence > best.confidence) {\n // Replace entire cluster with this better detection\n this.pendingCluster = [{ frameNumber, confidence: rawConfidence }];\n }\n }\n return { isSceneChange: false, confidence: 0 };\n }\n // Rule 3: Cluster merging - add to pending cluster\n this.pendingCluster.push({ frameNumber, confidence: rawConfidence });\n // Don't emit immediately; wait to see if more consecutive detections follow\n return { isSceneChange: false, confidence: 0 };\n }\n /**\n * Flush the pending cluster, emitting the highest-confidence detection\n */\n flushCluster() {\n if (this.pendingCluster.length === 0) {\n return null;\n }\n // Find the detection with highest confidence\n const best = this.pendingCluster.reduce((a, b) => a.confidence > b.confidence ? a : b);\n // Rule 2: Flash suppression - isolated single-frame detections with low confidence\n if (this.pendingCluster.length === 1 && best.confidence < this.flashConfidenceThreshold) {\n this.pendingCluster = [];\n return null;\n }\n // Confirm this detection\n this.lastConfirmedFrame = best.frameNumber;\n this.recentDetections.push(best);\n // Keep sliding window bounded\n while (this.recentDetections.length > this.windowSize) {\n this.recentDetections.shift();\n }\n this.pendingCluster = [];\n return {\n isSceneChange: true,\n confidence: best.confidence\n };\n }\n}\n//# sourceMappingURL=temporal-smoother.js.map","/**\n * Frame Processor - Utilities for frame preprocessing\n */\n/**\n * Format timestamp as timecode (HH:MM:SS.mmm)\n */\nexport function formatTimecode(seconds) {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n const ms = Math.floor((seconds % 1) * 1000);\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;\n}\n/**\n * Calculate macroblock parameters for frame dimensions\n */\nexport function calculateMBParam(width, height) {\n const mb_width = Math.ceil(width / 16);\n const mb_height = Math.ceil(height / 16);\n const edge_size = 64;\n return {\n width,\n height,\n mb_width,\n mb_height,\n edged_width: 16 * mb_width + 2 * edge_size,\n edged_height: 16 * mb_height + 2 * edge_size,\n edge_size\n };\n}\n/**\n * Check if frame dimensions are valid\n */\nexport function validateFrameDimensions(width, height) {\n if (width <= 0 || height <= 0) {\n throw new Error(`Invalid frame dimensions: ${width}x${height}`);\n }\n if (width > 8192 || height > 8192) {\n throw new Error(`Frame dimensions too large: ${width}x${height} (max: 8192x8192)`);\n }\n}\n/**\n * Calculate fcode from search range option\n */\nexport function calculateFcode(searchRange, width, height) {\n switch (searchRange) {\n case 'small':\n return 2; // 64 pixel range\n case 'medium':\n return 4; // 256 pixel range (default)\n case 'large':\n return 6; // 1024 pixel range\n case 'auto':\n // Auto-adjust based on resolution\n const pixels = width * height;\n if (pixels <= 720 * 480)\n return 3; // SD: 128px\n if (pixels <= 1920 * 1080)\n return 4; // HD: 256px\n return 5; // 4K+: 512px\n default:\n return 4;\n }\n}\n/**\n * Calculate adaptive thresholds based on sensitivity\n */\nexport function calculateThresholds(sensitivity) {\n switch (sensitivity) {\n case 'low':\n return { intraThresh: 3000, intraThresh2: 150 }; // Less sensitive\n case 'medium':\n return { intraThresh: 2000, intraThresh2: 90 }; // Default\n case 'high':\n return { intraThresh: 1000, intraThresh2: 50 }; // More sensitive\n case 'custom':\n // Will be overridden by customThresholds\n return { intraThresh: 2000, intraThresh2: 90 };\n default:\n return { intraThresh: 2000, intraThresh2: 90 };\n }\n}\n/**\n * Validate frame data\n */\nexport function validateFrame(frame) {\n if (!frame.data || frame.data.length === 0) {\n throw new Error('Frame data is empty');\n }\n const expectedSize = frame.width * frame.height;\n if (frame.data.length < expectedSize) {\n throw new Error(`Frame data size mismatch: expected at least ${expectedSize}, got ${frame.data.length}`);\n }\n validateFrameDimensions(frame.width, frame.height);\n}\n/**\n * Calculate memory usage for frame\n */\nexport function calculateFrameMemory(width, height) {\n const mbParam = calculateMBParam(width, height);\n return mbParam.edged_width * mbParam.edged_height;\n}\n/**\n * Estimate processing time based on frame count and resolution\n */\nexport function estimateProcessingTime(frameCount, width, height, targetFps = 60) {\n // Rough estimate: higher resolution = slower\n const resolutionFactor = (width * height) / (1920 * 1080);\n const adjustedFps = targetFps / resolutionFactor;\n return frameCount / adjustedFps;\n}\n//# sourceMappingURL=frame-processor.js.map","/**\n * Scene Detector - Main orchestrator for scene change detection\n */\nimport { FFmpegDecoder } from '../decoder/ffmpeg-decoder';\nimport { WasmBridge } from './wasm-bridge';\nimport { TemporalSmoother } from './temporal-smoother';\nimport { formatTimecode, calculateFcode, calculateThresholds, validateFrame } from '../utils/frame-processor';\nexport class SceneDetector {\n constructor(options = {}) {\n // Set default options\n this.options = {\n sensitivity: options.sensitivity || 'low',\n customThresholds: options.customThresholds || { intraThresh: 2000, intraThresh2: 90 },\n searchRange: options.searchRange || 'medium',\n workers: options.workers || 1,\n progressive: options.progressive || { enabled: false, initialStep: 1, refinementSteps: [] },\n temporalSmoothing: options.temporalSmoothing || { enabled: false, windowSize: 5, minConsecutive: 2 },\n frameExtraction: options.frameExtraction || { pixelFormat: 'gray', maxBufferFrames: 2 },\n onProgress: options.onProgress || (() => { }),\n onScene: options.onScene || (() => { }),\n format: options.format || 'json',\n signal: options.signal || undefined\n };\n this.wasmBridge = new WasmBridge();\n // Initialize detection state\n this.state = {\n intraCount: 1,\n fcode: 4,\n prevFrame: null,\n curFrame: null\n };\n }\n /**\n * Detect scene changes in a video file\n */\n async detect(videoPath) {\n // Initialize WASM module\n await this.wasmBridge.init();\n // Create decoder\n const decoder = new FFmpegDecoder(videoPath, {\n pixelFormat: this.options.frameExtraction.pixelFormat,\n maxBufferFrames: this.options.frameExtraction.maxBufferFrames,\n skipFrames: this.options.frameExtraction.skipFrames\n });\n // Get video metadata\n const metadata = await decoder.getMetadata();\n // Calculate fcode from search range\n this.state.fcode = calculateFcode(this.options.searchRange, metadata.resolution.width, metadata.resolution.height);\n // Calculate thresholds from sensitivity\n let thresholds;\n if (this.options.sensitivity === 'custom') {\n thresholds = this.options.customThresholds;\n }\n else {\n thresholds = calculateThresholds(this.options.sensitivity);\n }\n // Pre-allocate WASM buffers\n this.wasmBridge.allocateBuffers(metadata.resolution.width, metadata.resolution.height);\n // Initialize temporal smoother if enabled\n let temporalSmoother = null;\n if (this.options.temporalSmoothing.enabled) {\n temporalSmoother = new TemporalSmoother(this.options.temporalSmoothing);\n }\n // Initialize scene list (frame 0 is always a scene change)\n const scenes = [\n {\n frameNumber: 0,\n timestamp: 0,\n timecode: '00:00:00.000',\n confidence: 1.0\n }\n ];\n // Processing statistics\n const startTime = Date.now();\n let processedFrames = 0;\n let firstFrameValidated = false;\n // Rolling FPS window for accurate speed metrics (3-second window)\n const fpsWindow = [];\n // Fade/dissolve detection state\n let keyframeData = null;\n const driftThresholdFactor = 0.6; // Re-run detection at 60% of base thresholds\n // Quick-reject sampling interval\n const quickRejectStep = 64;\n const quickRejectThreshold = 5;\n // AbortSignal check\n const signal = this.options.signal;\n // Process frames\n await decoder.extractFrames(async (frame) => {\n // Check abort signal\n if (signal && signal.aborted) {\n throw new Error('Detection aborted');\n }\n // Validate only the first frame (dimensions never change within a video)\n if (!firstFrameValidated) {\n validateFrame(frame);\n firstFrameValidated = true;\n }\n // Update current frame\n this.state.curFrame = frame;\n // Need at least 2 frames to detect scene change\n if (this.state.prevFrame) {\n let isSceneChange = false;\n let confidence = 0;\n // Quick-reject: sampled MAD between prev and cur frame\n const prevData = this.state.prevFrame.data;\n const curData = this.state.curFrame.data;\n let sampledDiff = 0;\n let sampleCount = 0;\n for (let i = 0; i < curData.length; i += quickRejectStep) {\n sampledDiff += Math.abs(curData[i] - prevData[i]);\n sampleCount++;\n }\n const avgDiff = sampledDiff / sampleCount;\n if (avgDiff >= quickRejectThreshold) {\n // Frame differs enough, run full WASM detection\n const result = this.wasmBridge.detectSceneChange(this.state.prevFrame, this.state.curFrame, this.state.intraCount, this.state.fcode, thresholds.intraThresh, thresholds.intraThresh2);\n isSceneChange = result.isSceneChange;\n confidence = result.confidence;\n // Fade/dissolve detection: if not detected as scene change,\n // check drift from last keyframe\n if (!isSceneChange && keyframeData) {\n let driftSum = 0;\n let driftCount = 0;\n // Sample every 4th pixel for speed\n for (let i = 0; i < curData.length; i += 4) {\n driftSum += Math.abs(curData[i] - keyframeData[i]);\n driftCount++;\n }\n const driftAvg = driftSum / driftCount;\n // If cumulative drift is high but per-frame SAD didn't trigger,\n // re-run with lowered thresholds\n if (driftAvg > 30) {\n 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));\n if (fadeResult.isSceneChange) {\n isSceneChange = true;\n confidence = fadeResult.confidence;\n }\n }\n }\n }\n // else: quick-reject - frames are nearly identical, skip WASM call\n // Apply temporal smoothing if enabled\n if (temporalSmoother) {\n const smoothed = temporalSmoother.process(frame.frameNumber, isSceneChange, confidence);\n isSceneChange = smoothed.isSceneChange;\n confidence = smoothed.confidence;\n }\n if (isSceneChange) {\n const scene = {\n frameNumber: frame.frameNumber,\n timestamp: frame.pts,\n timecode: formatTimecode(frame.pts),\n confidence\n };\n scenes.push(scene);\n // Call scene callback\n this.options.onScene(scene);\n // Reset intraCount\n this.state.intraCount = 1;\n // Update keyframe for drift detection\n keyframeData = new Uint8Array(curData);\n }\n else {\n this.state.intraCount++;\n }\n }\n else {\n // First frame is the initial keyframe for drift detection\n keyframeData = new Uint8Array(frame.data);\n }\n // Move current frame to previous\n this.state.prevFrame = this.state.curFrame;\n processedFrames++;\n }, (current, total) => {\n // Enhanced progress with rolling FPS window\n const now = Date.now();\n const elapsed = (now - startTime) / 1000;\n // Add to rolling window\n fpsWindow.push({ time: now, frame: current });\n // Remove samples older than 3 seconds\n while (fpsWindow.length > 1 && (now - fpsWindow[0].time) > 3000) {\n fpsWindow.shift();\n }\n // Calculate instantaneous FPS from rolling window\n let currentFps = 0;\n if (fpsWindow.length >= 2) {\n const oldest = fpsWindow[0];\n const newest = fpsWindow[fpsWindow.length - 1];\n const dt = (newest.time - oldest.time) / 1000;\n if (dt > 0) {\n currentFps = (newest.frame - oldest.frame) / dt;\n }\n }\n // Calculate ETA from instantaneous FPS\n const remaining = currentFps > 0 ? (total - current) / currentFps : undefined;\n const progress = {\n currentFrame: current,\n totalFrames: total,\n percent: Math.round((current / total) * 100),\n eta: remaining,\n fps: currentFps,\n elapsed,\n scenesDetected: scenes.length\n };\n this.options.onProgress(progress);\n });\n // Calculate statistics\n const endTime = Date.now();\n const processingTime = (endTime - startTime) / 1000;\n const framesPerSecond = processedFrames / processingTime;\n // Post-process: compute scene durations\n for (let i = 0; i < scenes.length; i++) {\n if (i < scenes.length - 1) {\n scenes[i].duration = scenes[i + 1].timestamp - scenes[i].timestamp;\n scenes[i].frameCount = scenes[i + 1].frameNumber - scenes[i].frameNumber;\n }\n else {\n // Last scene: duration until end of video\n scenes[i].duration = metadata.duration - scenes[i].timestamp;\n scenes[i].frameCount = metadata.totalFrames - scenes[i].frameNumber;\n }\n }\n // Clean up\n decoder.destroy();\n return {\n scenes,\n metadata,\n stats: {\n processingTime,\n framesPerSecond\n }\n };\n }\n /**\n * Destroy the detector and clean up resources\n */\n destroy() {\n this.wasmBridge.destroy();\n this.state.prevFrame = null;\n this.state.curFrame = null;\n }\n}\n//# sourceMappingURL=detector.js.map","/**\n * keyframes - Scene change detection for Node.js\n *\n * A JavaScript/TypeScript port of vapoursynth-wwxd using Xvid's motion estimation algorithm.\n * Powered by WebAssembly for high performance.\n */\nexport { SceneDetector } from './detection/detector';\nexport { FFmpegDecoder } from './decoder/ffmpeg-decoder';\nexport { WasmBridge } from './detection/wasm-bridge';\nexport { TemporalSmoother } from './detection/temporal-smoother';\nexport { FrameBuffer } from './decoder/frame-buffer';\nexport { BufferPool } from './utils/buffer-pool';\n// Export utilities\nexport { formatTimecode, calculateFcode, calculateThresholds, validateFrame, validateFrameDimensions, calculateMBParam, calculateFrameMemory, estimateProcessingTime } from './utils/frame-processor';\nimport { SceneDetector } from './detection/detector';\nimport { FFmpegDecoder } from './decoder/ffmpeg-decoder';\n/**\n * Detect scene changes in a video file (simple API)\n *\n * @param videoPath Path to video file\n * @param options Detection options\n * @returns Detection results with scene changes and metadata\n *\n * @example\n * ```typescript\n * import { detectSceneChanges } from 'keyframes';\n *\n * const results = await detectSceneChanges('input.mp4');\n * console.log(`Found ${results.scenes.length} scenes`);\n *\n * results.scenes.forEach(scene => {\n * console.log(`Scene at ${scene.timecode} (confidence: ${scene.confidence})`);\n * });\n * ```\n */\nexport async function detectSceneChanges(videoPath, options) {\n const detector = new SceneDetector(options);\n try {\n const results = await detector.detect(videoPath);\n return results;\n }\n finally {\n detector.destroy();\n }\n}\n/**\n * Extract scene thumbnail images from a video\n *\n * @param videoPath Path to video file\n * @param options Detection options\n * @param imageOptions Image extraction options\n * @returns Detection results (images are written to disk)\n */\nexport async function extractSceneImages(videoPath, options, imageOptions) {\n const detector = new SceneDetector(options);\n try {\n const results = await detector.detect(videoPath);\n if (imageOptions) {\n const decoder = new FFmpegDecoder(videoPath);\n const frameNumbers = results.scenes.map(s => s.frameNumber);\n await decoder.extractFrameImages(frameNumbers, imageOptions);\n decoder.destroy();\n }\n return results;\n }\n finally {\n detector.destroy();\n }\n}\n/**\n * Version information\n */\nexport const version = '1.0.0';\n/**\n * Library information\n */\nexport const info = {\n name: 'keyframes',\n version: '1.0.0',\n description: 'Scene change detection for Node.js using Xvid\\'s motion estimation algorithm',\n license: 'GPL-2.0',\n repository: 'https://github.com/yourusername/keyframes',\n author: '',\n credits: {\n original: 'vapoursynth-wwxd by dubhater (https://github.com/dubhater/vapoursynth-wwxd)',\n algorithm: 'Xvid motion estimation (https://www.xvid.com)'\n }\n};\n//# sourceMappingURL=index.js.map"],"names":["ffmpeg","ffmpegInstaller","ffprobeInstaller","fs","path"],"mappings":"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"}
|