Commit Graph

269 Commits

Author SHA1 Message Date
Ethanfel 3417a0f603 fix: crash when switching folder in train dialog (signal recursion)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 22:00:23 +02:00
Ethanfel cd0552197f feat: prefetch audio during Scan All, fix file-switch interruption, fix Windows setup
- Prefetch next video's audio while GPU processes current embeddings
- Don't cancel Scan All when switching files in playlist
- Windows setup script now creates venv, installs PyTorch + requirements
- 8cut.bat auto-detects venv

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:50:33 +02:00
Ethanfel 7dffcb08eb feat: interruptible Scan All — stop after current video, resume later
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:37:47 +02:00
Ethanfel 93bcb23fa7 docs: document embedding cache and fast rescan loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:26:14 +02:00
Ethanfel eda7826a40 fix: safe PATH fallback for Windows DLL loading, deduplicate model restore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:14:44 +02:00
Ethanfel e7e20b0fe6 fix: review mode playback line, model restore dedup, auto-rescan on rollback
- Show bright green playback position line in review mode
- Model history button next to scan model dropdown
- Skip backup on restore if identical timestamped copy already exists
- Auto-rescan when restoring a model version

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:05:40 +02:00
Ethanfel 814ef946eb fix: add missing shortcuts to help dialog (disable, undo, drag resize)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 20:47:52 +02:00
Ethanfel 2e738df9ae docs: rewrite install guide with venv steps and dataset sizing guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 20:40:23 +02:00
Ethanfel 6ddfcde8ee feat: disable/resize scan regions, undo, training fixes, cross-platform cleanup
- Scan regions can be disabled (Del/Backspace) instead of deleted, shown greyed out
- Resize scan regions by dragging timeline edges or editing table cells
- Grey ghost overlay shows trimmed portions of resized regions
- Ctrl+Z undo for disable, resize, drag, and negative toggle actions
- Fix training stats including scan-exported clips when checkbox unchecked
- Switch classifier to HistGradientBoostingClassifier (multi-threaded)
- Timestamped model saves with latest copy at base path
- Fix next-folder counter not detecting scan export folders
- Each scan area exports to its own numbered clip folder
- Platform-aware HW encoder detection (Linux/Windows/macOS)
- Auto-detect VAAPI render device instead of hardcoding
- Use shutil.move for cross-drive safety on Windows
- Comprehensive README rewrite with scan workflow documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 20:34:56 +02:00
Ethanfel b161412d94 feat: scan workflow — region fusion, hard negatives, review mode, versioned models
- Fuse overlapping scan regions before display (merge adjacent 1s-hop windows)
- Hard negatives: mark false positives from scan panel for training feedback
  - Toggle with "Add to Negatives" button, red text + red timeline regions
  - Stored in dedicated hard_negatives table, always included in training
- Model versioning: auto-backup on retrain, right-click model combo to rollback
- Scan review mode: "Review" toggle hides spread/markers for free navigation
- Scan exports: saved to DB with scan_export flag, no timeline markers
  - Training dialog checkbox to optionally include scan exports
  - Single group folder per batch with area numbering (clip_042_a1_0.mp4)
- Export scan results: skip negatives, skip regions < 8s, respect spread
  - Button shows estimated clip count, updates on spread/fuse/negative changes
- Timeline: reload scan regions on file load, "Clear all markers" context menu
- Default training model changed to HUBERT_XLARGE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 18:43:05 +02:00
Ethanfel 5a9e068903 fix: 6 bugs — profile isolation, export stashing, auto-negative guard
- Stash profile and crop_center at export start for async safety
- Scope get_group/delete_group by profile to prevent cross-profile leaks
- Guard auto-negative sampling when no markers exist (prevents flood)
- Wrap ffmpeg subprocess with clean timeout error message
- Fix scan-all panel reload to use stashed profile, not live value
- Remove dead warnings import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 16:28:51 +02:00
Ethanfel 6870e5aaf3 feat: scan results panel, model switching, batch scan, and training improvements
- Replace librosa with direct ffmpeg subprocess for 10x faster audio loading
- Add ScanResultsPanel with per-model tabs, seek-on-click, delete, and export
- Persist scan results in DB per (filename, profile, model)
- Add model selector dropdown to switch between trained embedding models
- Add "Scan All" button for batch scanning playlist videos
- Support manual negative examples via negative class folder
- Configurable auto-negative margin (default 30s, 0 = disabled)
- Deduplicate nearby training markers (8s min gap)
- Parallel audio loading with ThreadPoolExecutor during training
- Progress callbacks from training for UI status updates
- Cache bypass in scan_video (skip audio loading when embeddings cached)
- Move all caches (models, embeddings, downloads) into project directory
- Add 8cut.sh launcher script with auto venv/conda detection
- Fix 11 bugs across thread safety, signal handling, and state management

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 16:12:52 +02:00
Ethanfel f597ff29e8 chore: move model storage into project models/ directory
Models now live in <project>/models/ instead of ~/.8cut_models/ so
everything stays self-contained. Updated .gitignore to exclude
models/, .venv/, *.joblib, and *.pt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 13:05:20 +02:00
Ethanfel e1789d4e71 fix: bug audit — broken test imports, training data overlap, cleanup
- Fix test_utils.py importing build_annotation_json_path from main
  instead of core.annotations (all 59 tests pass now)
- Fix get_training_data double-counting clips at same start_time
  in both positive and soft sets — subtract positive from soft
- Add cancel_flag to train_classifier so training can be interrupted
  between videos (TrainWorker passes self as cancel_flag)
- Remove orphaned core/export.py (was for deleted server API)
- Remove stale Dockerfile and docker-compose.yml (referenced server)
- Clean up leftover server/__pycache__ and client/ build artifacts
- Add torch to requirements.txt (was only mentioned in comments)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 12:55:58 +02:00
Ethanfel 7834b1d05c chore: remove server and client — unused in desktop app
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 12:49:20 +02:00
Ethanfel 12ed183f1b feat: integrate training UI, BEATs model, and clean up legacy code
- Remove legacy distance-mode scanning (build_profile, _similarity, etc.)
  and hand-crafted intensity features — pipeline is now embedding-only
- Integrate Microsoft BEATs as embedding option alongside wav2vec2/HuBERT
- Add TrainDialog with positive class selector, model picker, video dir
  fallback, and live training stats
- Add TrainWorker QThread with cancel support and proper lifecycle cleanup
- Add source_path column to DB for robust source video tracking
- Add get_export_folders/get_training_data/get_training_stats to DB
- Wire source_path in all export DB writes (_on_clip_done, _on_auto_clip_done)
- Cancel scan/train workers in closeEvent to prevent use-after-free crashes
- Add setup_env.sh supporting both conda and python venv (CUDA 12.8)
- Update requirements.txt with all actual dependencies
- Update 8cut_train.py with --positive flag for new DB-driven training

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 11:52:27 +02:00
Ethanfel f2c38aee79 feat: rewrite audio scan with MFCC+delta+spectral contrast pipeline
Root cause of poor discrimination: MFCC[0] (energy) dominated the
feature vector, making cosine similarity see all audio as similar.

Changes:
- Skip MFCC[0], use 12 coefficients instead of 20
- Add delta MFCCs for temporal dynamics
- Add 7-band spectral contrast for tonal vs noise quality
- Switch from cosine similarity to euclidean-distance-based score
- Pre-compute STFT once for whole file (10-20x faster)
- Vectorized sliding window via cumulative sums (no Python loop)
- Lower sample rate 22050→16000 Hz (faster, no quality loss)
- 62-dim feature vector (was 40-dim mean+std of raw MFCCs)
- Default threshold 0.05 (new similarity scale)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 15:28:44 +02:00
Ethanfel 8ab5bdba77 fix: use mean+std MFCC vectors (40-dim) for better discrimination
Mean-only vectors were too similar across different audio segments,
causing everything to match even at threshold 0.99. Adding std
captures temporal dynamics and makes the similarity scores much
more spread out.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:27:11 +02:00
Ethanfel c6c5934fe8 fix: threshold step 0.05 → 0.01 for finer control
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:21:14 +02:00
Ethanfel 73d5367424 fix: three audio scan bugs — signal shadow, re-entrancy, S-key jump
1. Rename ScanWorker.finished → scan_done to stop shadowing
   QThread.finished. Previously, cancelled scans leaked the QThread
   because the custom signal was never emitted.

2. Block signals on combobox reset in _on_scan_ref_changed to
   prevent re-entrant call when user cancels folder dialog.

3. Merge overlapping scan regions into clusters before S-key
   navigation so it jumps to the next distinct match, not 1s forward
   through overlapping windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:12:24 +02:00
Ethanfel 1e2cebd424 fix: prevent deleteLater on still-running ScanWorker QThread
When cancelling a scan during file change, connect finished signal
to deleteLater instead of calling it immediately on a running thread.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:02:35 +02:00
Ethanfel c439aca9b9 feat: add S shortcut and clear scan on file change
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:59:47 +02:00
Ethanfel afda9b2d9f feat: add scan UI controls and start_scan handler
Add Scan button, threshold spinner, mode combobox, and reference source
combobox to the settings row. Implement handler methods for starting scans,
handling results/errors, cleanup of workers, and reference folder selection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:57:56 +02:00
Ethanfel fd42791c9f feat: add get_all_export_paths to ProcessedDB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:55:39 +02:00
Ethanfel 4cf54f2642 feat: add ScanWorker QThread for background scanning
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:54:20 +02:00
Ethanfel e7f4de9ec1 feat: timeline scan region rendering
Add scan region storage and rendering to TimelineWidget:
- _scan_regions list in __init__ for (start, end, score) tuples
- set_scan_regions() and clear_scan_regions() methods
- paintEvent draws semi-transparent blue rectangles with score-based opacity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:53:18 +02:00
Ethanfel 9cf9e3233f feat: add scan_video with average and nearest modes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:50:47 +02:00
Ethanfel e17d8f67aa feat: add audio_scan module with build_profile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:48:18 +02:00
Ethanfel b1980de6d1 fix: 9 bugs in audio scan implementation plan
- Swap Task 5/6 order so get_all_export_paths exists before UI uses it
- Remove cosine similarity clamping to preserve anti-correlation signal
- Use os.path.exists instead of os.path.isfile (handles image sequences)
- Add worker cleanup to disconnect stale signals before new scan
- Remove lock from get_all_export_paths (matches read-only convention)
- Always use get_all_export_paths for Current Profile (not current-file-first)
- Filter export paths with os.path.exists for deleted files
- Use abs() for float comparison in tests instead of ==
- Add cancel_flag to ScanWorker and scan_video for interruptible scans

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:43:53 +02:00
Ethanfel 85e0641440 docs: add audio scan implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:36:56 +02:00
Ethanfel 834b89b682 docs: add audio similarity scanning design
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:33:25 +02:00
Ethanfel a67e189aa0 fix: mpv loadfile index arg, cache polling, and sidebar CSS
- Pass integer index (-1) to mpv loadfile command for newer mpv versions
- Poll /api/cache/status instead of streaming endpoints to avoid
  downloading video bodies during readiness checks
- Cancel previous polling when selecting a new file
- Fix sidebar flex-shrink and file name text overflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 08:17:23 +02:00
Ethanfel 2b6c56cd15 fix: add CORS middleware to server for Tauri webview requests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:49:53 +02:00
Ethanfel 0f6082061f feat: add folder navigation to file browser
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:25:03 +02:00
Ethanfel 9662b815db feat: add server URL input to profile bar
Type URL + Enter or click Set. Persisted via localStorage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:15:42 +02:00
Ethanfel 9776b83ac5 fix: client bug fixes from review
- FileBrowser: reload hidden files when profile changes
- WebSocket: wrap JSON.parse in try-catch
- WebSocket: exponential backoff on reconnect (2s -> 30s max)
- WebSocket: clean up connection on destroy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:09:21 +02:00
Ethanfel 39f873bec2 fix: server bug fixes from review
- DB: add threading.Lock on all write methods and multi-step reads
- export.py: check audio extraction return code, raise on failure
- routes/export: counter race condition fix with _counter_lock
- routes/export: delete validation accepts EXPORT_DIR_suffix siblings
- routes/export: evict old finished jobs to prevent unbounded growth
- client plan: fix 10 bugs (mpv IPC, encodePath, input_path sep, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:53:38 +02:00
Ethanfel 409eb82e5c feat: configure Linux packaging (deb + AppImage)
Renamed to 8-cut, 1200x800 window, .deb builds at 3.9MB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:52:40 +02:00
Ethanfel 297aafa51c feat: add settings persistence via localStorage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:50:01 +02:00
Ethanfel b4cf972d59 feat: wire up main app layout with all components
Sidebar file browser, canvas timeline, transport bar, export panel,
profile bar, keyboard shortcuts, quality-reactive stream reload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:48:54 +02:00
Ethanfel 5cc1e52e75 feat: add profile bar component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:10:32 +02:00
Ethanfel 6bf0b0ae99 feat: add export panel component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:10:03 +02:00
Ethanfel b6fbda01dd feat: add canvas-based timeline component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:07:21 +02:00
Ethanfel 51d41f0a56 feat: add file browser component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 19:06:41 +02:00
Ethanfel 16bd1a9ae0 feat: add mpv TypeScript bridge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:46:35 +02:00
Ethanfel 2036c49b52 feat: add mpv sidecar IPC and Tauri commands
Persistent BufReader + request_id matching for correct event handling.
Audio-file passed during loadfile for frame-accurate sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:46:01 +02:00
Ethanfel b12758c53c feat: add WebSocket client for export progress
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:41:12 +02:00
Ethanfel 3d484952c2 feat: add Svelte stores for app state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:40:43 +02:00
Ethanfel 12dae93671 feat: add server API client module
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:34:23 +02:00
Ethanfel 1e65fd6b0f feat: scaffold Tauri + Svelte client
SvelteKit in SPA mode with Tauri v2. Builds and produces .deb bundle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:33:45 +02:00