- Wrap the playlist in a QTabWidget; each tab is its own file list
- "+" corner button adds tabs; double-click a tab to rename inline; tabs are closable (last tab protected) and movable
- self._playlist now resolves to the active tab's PlaylistWidget
- Persist tabs (label + files + separators) per profile as JSON; falls back to legacy session_files/separators on first load
- Filter box and playlist filters apply to the active tab; tab switches reapply filters and refresh marks
- Profile switch/duplicate/delete now save/load/copy/remove per-profile tab state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Context menu offers both "Add/Remove separator above" and "below"
- "Below" anchors to the next visible file, or a trailing line via end sentinel when clicking the last file
- End sentinel preserved across rebuilds and persisted per profile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Train dialog: multi-select positive subcategories via checkbox list, optional model name suffix ({profile}_{model}_{name}.joblib)
- list_trained_models recognizes named model variants
- Disable a video per-subcategory: moves its clips to a sibling {subcat}_disabled folder, rewrites DB output_path, migrates dataset.json, marks the name red
- Disabled clips excluded from training, stats, timeline, and playlist counts
- Playlist per-video count reflects only visible, non-disabled subcategories
- Persist subcategory show/hide visibility per profile across restarts
- Add/remove playlist separator rows (right-click) to mark batches, persisted per profile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add speech detection via faster-whisper with red waveform coloring for speech regions
- Add format variant export buttons (P/S) next to Export and subprofile buttons when portrait/square enabled
- Add force_ratio parameter to _on_export for deterministic format exports
- Add subcategory show/hide with persistent checkbox menu (no longer closes on toggle)
- Show crop overlay lines during video playback, not just when paused
- Delete marker now also removes files from disk and cleans up annotations
- Clear all markers also deletes files and DB entries
- Add playlist text filter, clip spread tick lines on timeline
- Fix LD_PRELOAD for GLIBCXX in conda launcher
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ProcessedDB.update_source_paths() to re-resolve missing or stale
source_path entries by matching filenames against a directory listing
and the current playlist. Exposed as "Update paths" button in the
train dialog next to the video dir field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The context menu hit test only searched the current folder's markers.
Now also checks other-folder markers so the delete option appears
for subprofile markers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Subprofile/subfolder exports now appear as colored markers (yellow,
green, blue, purple, orange) with their own numbering, separate from
the main folder's red markers. Each folder gets its own color and
independent sequence numbers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Subprofile exports (folder_suffix) created markers that interleaved
with main folder markers, shifting their numbering. Now get_markers
and _get_markers_for accept an export_folder parameter and use
SQL LIKE to only return markers whose output_path is in that folder.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thin 8px scrollbar appears above the ruler when the timeline is zoomed.
Shows a draggable thumb representing the current view window. Click
outside the thumb to jump, drag the thumb to pan. Ruler and track
shift down to make room. Scrollbar hidden when not zoomed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The marker format was extended to include clip_span but the overlap
check in _on_export still unpacked 3 values, causing a crash on export.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mpv's "absolute" seek lands on the nearest keyframe before the target,
causing playback to start ~3s before the marker. Switch to
"absolute+exact" for both seek() and play_loop() so playback starts
at the precise requested time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revert span opacity back to 35 (was fine). The actual issue was the
play position line disappearing when scrolled out of the zoomed view.
Now set_play_position auto-pans the view window to keep the playback
marker visible with a 10% margin.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- _on_marker_clicked now explicitly sets cursor and seeks mpv to start_time
instead of relying on the timeline's indirect seek chain
- Doubled clip span area opacity (35 → 70) so spans are always visible
- Trigger end-frame preview after config restoration on marker click
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Per-profile playlist persistence (session_files/{profile} in QSettings)
- Training data resolves source videos via playlist paths before fallback dir
- Guard against deleted video files in _load_file
- Fix marker double-click to seek to exact marker time instead of click pixel
- Show manual clip spans as light amber areas on the timeline
- Extend marker tuples with clip_span from DB (clip_duration + overlap)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add clip duration spinner (2–30s, default 8s) replacing all hardcoded
8.0 references. Store clip_duration in DB for accurate re-export span
calculations. Add x2/x4 playback speed toggle buttons. On Windows, mpv
renders directly into the widget's native window handle (WId embedding)
instead of slow FBO readback; crop overlays use a transparent child
widget. Fix _poll_render crash when player is None after closeEvent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-export dialog now offers two modes: keep section length (adjust clip
count) or keep clip count (adjust section length). Files shared with
other profiles are preserved during re-export. Vid folder is resolved
before DB deletions to reuse existing folders. Add delete profile option
with confirmation dialog. Profile duplication now copies all tables
including processed exports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-export button (next to Spread spinner) re-exports all manual clips
for the current file into the current folder with the new spread value.
Old files are deleted from their original locations first.
Duplicate profile option in the profile dropdown copies scan_results,
hard_negatives, and hidden_files to a new profile name (exports are not
copied since they reference file paths tied to the source profile).
Also widened get_profiles() to include profiles that only have
scan_results or hard_negatives, not just exports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a scan result row is clicked, if the active region falls outside
the current zoomed view the view centers on the region (and widens if
the region is larger than the current span).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ctrl+scroll zooms the timeline view around the mouse. Middle-mouse drag
pans when zoomed. Scrolling all the way out clamps back to full view.
While dragging a scan region edge with Shift, the view auto-pans when
the mouse approaches the widget border so you can extend a region past
the visible range.
All paint and hit-test paths now route through _time_to_x / _pos_to_time
helpers backed by a _view_start / _view_span window, so existing
interactions (seek, marker click, edge resize, keyframe context menu)
all adapt naturally to the zoom level.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add "Merge N rows" context-menu option that combines selected scan rows
into one (min start, max end, max score), with full undo support.
Ctrl+Z is now an application-wide shortcut so it works regardless of
which widget has focus. Negatives undo now respects the exported-green
row color instead of reverting to default.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Scan panel button now reads "Export Selected (N)" while rows are
selected, mirroring the clip-count estimate used for full exports.
Selection changes fire an explicit signal so the label refreshes.
- Export markers remain visible on the timeline in scan/review mode.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Right-click on exported (green) rows shows "Delete export" to wipe
associated clip files, annotations, DB rows and empty vid folders;
scan panel, markers and playlist badge refresh afterwards.
- Exporting with rows selected in the scan panel now runs a partial
export: prior scan exports are preserved, and the area index for new
clip filenames is offset past existing a-suffixes in the vid folder
to avoid collisions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Scan panel rows whose range contains an exported clip's start time
are colored green. Priority: disabled > negative > exported > default.
Exported state refreshes automatically after an auto-export batch
completes on the current file.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Draws a yellow outline around the scan region corresponding to the
selected/clicked row, so overlapping regions can be distinguished.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Time column click still seeks to clip start. End column click seeks
to end - 3s so you can preview the tail of the clip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Waveform peaks are saved as .npy files keyed by MD5 of the video
path. Subsequent loads of the same video read from cache instead
of re-running ffmpeg extraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the current item is deselected via Ctrl+click, fall back to
the last remaining selected item instead of staying on the
deselected row.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Was using selectedItems()[0] which always returns the first item in
the selection, not the most recently clicked one. Changed to
currentItem() which tracks the last clicked row.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When starting a scan export batch, delete old scan_export entries for
the same file+profile before writing new ones. Logs a warning when
replacing. Prevents stale entry buildup from repeated scan exports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Queue scan exports back-to-back: when an export is running, new
batches are queued and drain automatically on completion. Each batch
snapshots its state (file path, jobs, settings) so the user can
switch videos while exports run.
Also updates ScanWorker default and slider initial value to 0.50
to match the core threshold change.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Manual clips now follow the same pattern as scan exports:
clip_003_m1_0.mp4 (manual) vs clip_003_a1_0.mp4 (auto-scan).
The clip number matches the vid folder number.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clip_001_a1_0 now matches vid_001 instead of using an independent
counter that created confusing double numbering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
load_for_file and add_scan_results triggered N redundant timeline repaints
via tab_changed → _on_scan_regions_edited for each tab add/remove.
blockSignals(True) during programmatic tab operations eliminates the cascade.
Also adds EAT_LARGE embedding model (1024-dim) and updates design docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Export layout changed from clip_NNN group dirs to vid_NNN per-video folders
- Automatic DB migration rewrites old paths and moves files on startup
- Per-video counter with DB cross-check to prevent overwrites
- Changelog popup on version bump with "don't show again" checkbox
- Scan region resize now requires Shift+drag to prevent accidental edits
- Recalculate vid folder and counter on file load
- Add EAT_LARGE embedding model variant
- Update tests for new flat export path structure
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tab_changed was only updating export count, not the timeline overlay.
Now calls _on_scan_regions_edited which refreshes both.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use microsecond-precision timestamps to prevent version merging on
sub-second scans
- Clear undo stack when switching scan versions (stale row references)
- Parse timestamp labels robustly instead of hard-coded string slicing
- "Clear All" in hard negatives dialog respects active model filter
- Remove time.sleep from tests (no longer needed with microsecond timestamps)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New HardNegativesDialog shows all hard negatives in a table with model
filter dropdown, multi-select delete, and clear all. Accessible from
TrainDialog via "Manage..." button next to the hard negatives checkbox.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add source_model column to hard_negatives table with migration. New
get_hard_negatives() returns full rows, delete_hard_negatives_by_ids()
for bulk deletion. get_training_data() gains use_hard_negatives param.
TrainDialog has "Use hard negatives" checkbox. Scan panel passes current
model name when marking negatives.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each model tab now has a version combo showing scan history. When multiple
versions exist for a (file, model), users can switch between them to
compare results across training iterations. Added _current_table() and
_tab_table() helpers to unwrap the new container→table widget hierarchy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Training cancel: connect finished signal to re-enable button (was stuck disabled)
- Waveform worker: disconnect stale signal and wait on file switch, clean up on close
- DatasetStatsDialog: numeric sort via DisplayRole, remove dead widget allocation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Details button in Train dialog opens a stats view showing:
- Class totals (positive/soft/negative) with colored balance bar
- Per-video table sortable by column
- Warnings for low clip counts, class imbalance, negative-only videos
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- WaveformWorker extracts low-res audio envelope via ffmpeg, drawn as
green polygon on timeline track
- _safe_disconnect() replaces bare TypeError catches for signal cleanup
- Train button toggles to Cancel during training, calls worker.cancel()
- Dynamic GPU batch sizing: 64 for ≥16GB VRAM, 32 for ≥8GB, 16 default
- Overlap warning before exporting clips that intersect existing markers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fresh databases were missing scan_export column — broke first export
- Threshold slider now filters existing scan results without rescanning
- N key toggles hard negative on selected scan regions
- All 59 tests passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- setup-windows.ps1 and setup_env.sh detect nvidia-smi for CUDA vs CPU PyTorch
- Startup logs Python version, venv path, PyTorch/CUDA/GPU, scikit-learn, librosa
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>