UNPKG

contaigents

Version:

Modular AI Content Ecosystem with Audio Generation

168 lines (167 loc) • 8.04 kB
import { FFmpegTool } from '../services/tools/FFmpegTool.js'; import path from 'path'; import fs from 'fs/promises'; export async function testShotDetection() { console.log('šŸŽ¬ Testing Video Shot Detection with FFmpeg'); console.log('==================================================\n'); const baseDir = process.cwd(); const ffmpegTool = new FFmpegTool(baseDir); const testVideo = 'demo/video/multishotvideo.mov'; // Check if test video exists try { await fs.access(path.join(baseDir, testVideo)); console.log(`āœ… Test video found: ${testVideo}\n`); } catch (error) { console.log(`āŒ Test video not found: ${testVideo}`); console.log('Please ensure the test video exists before running this test.\n'); return; } // Test 1: Detect shots and output timestamps console.log('šŸ“ Test 1: Shot Detection - Timestamps Output'); console.log('šŸŽÆ Detecting shot boundaries and saving timestamps...'); try { const timestampsResult = await ffmpegTool.execute({ operation: 'detect_shots', input_file: testVideo, output_file: 'demo/shot_timestamps.txt', scene_threshold: '0.3', output_format: 'timestamps' }); if (timestampsResult.success) { console.log('āœ… Timestamps detection completed!'); console.log(`šŸ“ Output: ${timestampsResult.data?.output_file}`); console.log(`ā±ļø Execution time: ${timestampsResult.data?.execution_time}ms\n`); // Try to read and display the first few timestamps try { const timestampsContent = await fs.readFile(path.join(baseDir, 'demo/shot_timestamps.txt'), 'utf-8'); const timestamps = timestampsContent.trim().split('\n').filter(line => line.trim()); console.log(`šŸŽÆ Found ${timestamps.length} shot boundaries:`); timestamps.slice(0, 10).forEach((timestamp, index) => { console.log(` ${index + 1}. ${parseFloat(timestamp).toFixed(2)}s`); }); if (timestamps.length > 10) { console.log(` ... and ${timestamps.length - 10} more\n`); } else { console.log(''); } } catch (readError) { console.log('šŸ“„ Timestamps file created but could not read content\n'); } } else { console.log(`āŒ Timestamps detection failed: ${timestampsResult.error}\n`); } } catch (error) { console.log(`āŒ Test 1 failed: ${error.message}\n`); } // Test 2: Detect shots with different threshold console.log('šŸ“ Test 2: Shot Detection - Lower Threshold (More Sensitive)'); console.log('šŸŽÆ Using lower threshold (0.1) to detect more subtle changes...'); try { const sensitiveResult = await ffmpegTool.execute({ operation: 'detect_shots', input_file: testVideo, output_file: 'demo/shot_timestamps_sensitive.txt', scene_threshold: '0.1', output_format: 'timestamps' }); if (sensitiveResult.success) { console.log('āœ… Sensitive detection completed!'); console.log(`šŸ“ Output: ${sensitiveResult.data?.output_file}`); console.log(`ā±ļø Execution time: ${sensitiveResult.data?.execution_time}ms\n`); } else { console.log(`āŒ Sensitive detection failed: ${sensitiveResult.error}\n`); } } catch (error) { console.log(`āŒ Test 2 failed: ${error.message}\n`); } // Test 3: Metadata output console.log('šŸ“ Test 3: Shot Detection - Metadata Output'); console.log('šŸŽÆ Generating detailed metadata about shot boundaries...'); try { const metadataResult = await ffmpegTool.execute({ operation: 'detect_shots', input_file: testVideo, output_file: 'demo/shot_metadata.txt', scene_threshold: '0.3', output_format: 'metadata' }); if (metadataResult.success) { console.log('āœ… Metadata detection completed!'); console.log(`šŸ“ Output: ${metadataResult.data?.output_file}`); console.log(`ā±ļø Execution time: ${metadataResult.data?.execution_time}ms\n`); } else { console.log(`āŒ Metadata detection failed: ${metadataResult.error}\n`); } } catch (error) { console.log(`āŒ Test 3 failed: ${error.message}\n`); } // Test 4: Demonstrate splitting workflow console.log('šŸ“ Test 4: Complete Splitting Workflow'); console.log('ļæ½ Demonstrating how to split video using detected timestamps...'); try { // Read the timestamps we detected earlier const timestampsContent = await fs.readFile(path.join(baseDir, 'demo/shot_timestamps.txt'), 'utf-8'); const timestamps = timestampsContent.trim().split('\n').filter(line => line.trim()).map(t => parseFloat(t)); if (timestamps.length > 0) { console.log(`šŸ“Š Found ${timestamps.length} shot boundaries, creating ${timestamps.length + 1} segments:`); // Create first segment (start to first boundary) const firstSegmentResult = await ffmpegTool.execute({ operation: 'trim', input_file: testVideo, output_file: 'demo/segment_001.mp4', start_time: '0', end_time: timestamps[0].toString() }); if (firstSegmentResult.success) { console.log(`āœ… Segment 1: 0s → ${timestamps[0].toFixed(2)}s`); } // Create middle segments for (let i = 0; i < timestamps.length - 1; i++) { const segmentResult = await ffmpegTool.execute({ operation: 'trim', input_file: testVideo, output_file: `demo/segment_${String(i + 2).padStart(3, '0')}.mp4`, start_time: timestamps[i].toString(), end_time: timestamps[i + 1].toString() }); if (segmentResult.success) { console.log(`āœ… Segment ${i + 2}: ${timestamps[i].toFixed(2)}s → ${timestamps[i + 1].toFixed(2)}s`); } } console.log('šŸŽ¬ Video successfully split into segments based on shot detection!\n'); } } catch (error) { console.log(`āŒ Splitting workflow failed: ${error.message}\n`); } console.log('ļæ½šŸŽ‰ Shot Detection Tests Completed!'); console.log('\nšŸ’” Usage Tips:'); console.log(' • Lower scene_threshold (0.1-0.2) = More sensitive, detects subtle changes'); console.log(' • Higher scene_threshold (0.4-0.6) = Less sensitive, only major scene changes'); console.log(' • timestamps format = Simple list of shot boundary times'); console.log(' • metadata format = Detailed information about each shot'); console.log('\nšŸ”§ Complete Workflow for Video Splitting:'); console.log(' 1. detect_shots → get timestamps.txt'); console.log(' 2. Read timestamps from file'); console.log(' 3. Use trim operation for each segment'); console.log(' 4. Result: Individual video files for each shot'); console.log('\nšŸŽÆ Integration Examples:'); console.log(' • Auto-segment content for video editing workflows'); console.log(' • Analyze video structure for content summarization'); console.log(' • Create highlight reels by detecting scene changes'); console.log(' • Generate video thumbnails at shot boundaries'); console.log(' • Build automated video processing pipelines'); } // Run the test if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { testShotDetection().catch(console.error); }