- Track subject checkbox: auto-adjusts crop center per sub-clip using
YOLOv8-nano detection on each start frame
- Detects target nearest to user's crop click, follows same class across clips
- Graceful fallback when ultralytics not installed or detection fails
- Fix end-frame preview not updating on clip/spread change (retry on busy grabber)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Playlist marks show [N] instead of ✓ to indicate how many clips exported
- Export counter scans from 1 to find first available slot instead of only advancing
- Refresh playlist checks and counter after marker/group deletion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- VAAPI: hwdownload before CPU filters, skip HW setup for image sequences
- Delete old DB rows before overwrite re-insert to prevent duplicates
- Stash cursor at export time so async completion uses correct position
- Restore crop_center on marker click, fix falsy 0-value checks
- Remove stale pending marker on export error
- Guard double mpv termination in closeEvent
- SnapPreviewWindow recursion guard for dock/follow moves
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add HW encode checkbox (auto-detects NVENC/VAAPI/QSV/AMF/VideoToolbox),
caps GPU workers to 3 to avoid concurrent session limits
- Add workers spinbox next to Export button to control parallel ffmpeg count
- Enable mpv hwdec=auto for GPU-accelerated video decoding during playback
- Add timestamped terminal logging for startup, file load, export, errors
- Reorder settings row: video settings (Resize, Portrait) then encoding
(Format, HW, Clips, Spread, random crops)
- Fix filename label wrapping by using QSizePolicy.Ignored + no word wrap
- Alternating row colors in playlist for readability
- Snap-to-edge preview window: docks to main window edges, follows on move
- Fix SEGV on exit: explicit mpv shutdown in MainWindow.closeEvent before
Qt tears down QObjects
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "1 random square" checkbox (1:1 crop) alongside random portrait (9:16);
both share the same ~1-per-3 quota when enabled together
- Multi-overlay system: portrait guides in red, square guides in blue, both
visible simultaneously on the paused frame
- Replace editable profile QComboBox with non-editable dropdown + "New profile..."
item via QInputDialog — fixes markers not updating on profile switch
- Refresh playlist checkmarks on profile switch (add/remove done marks)
- Add "?" button and ?/F1 shortcut to show keyboard shortcuts dialog
- Re-render video on widget resize to preserve aspect ratio
- Compute letterbox/pillarbox video rect for correct overlay + click mapping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switching profiles now clears the overwrite path, button states, and
next-label so stale state from the old profile doesn't persist.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous border:none rule hid the dropdown indicator entirely,
making combos look like plain text fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each profile has its own set of timeline markers, so the same video
can be cut with different settings (e.g. landscape vs portrait) without
markers interfering. Profile selector in the top bar, persisted in
QSettings, stored per-row in the DB.
- Add `profile` column to ProcessedDB schema (migrates existing rows
to 'default')
- Scope find_similar, get_markers, _get_markers_for by profile
- Add get_profiles() for populating the combo dropdown
- Thread profile through _DBWorker, _after_load, _refresh_markers,
_on_clip_done, dropEvent, _on_open_files
- Editable profile QComboBox in top bar, refreshed after each export
- 5 new tests for profile isolation and backward compatibility (54 total)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add timeline-style SVG banner with markers, playhead, and branding
- Rewrite README to reflect current features (batch export, SELVA
annotation, group delete/overwrite, playlist, shortcuts)
- Remove outdated mask generation references
- Update test count to 49
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Style QComboBox/QSpinBox/QDoubleSpinBox/QCheckBox in dark theme
- Delete and overwrite now operate on the full clip group, not just one sub-clip
- Add get_group/delete_group to ProcessedDB with tests
- Restructure control rows: transport+actions / annotation+path / encoding
- Add "Open Files" button to queue panel (replaces drag-drop-only)
- Playlist right-click to remove items
- Compact time display (1:23.4 / 5:00.0), window title shows filename
- Short side: QLineEdit → QSpinBox with validation
- Tooltips with keyboard shortcuts on all interactive widgets
- Fix arrow hint direction, remove stale mask comment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dead code — masking is handled externally via ComfyUI. Removes
SetupWorker, MaskWorker, SettingsDialog, build_mask_output_dir,
the mask UI row, Settings button, and associated test cases.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Suppress global shortcuts (E/J/L/K/M/Space/P/arrows) when typing in
text fields via ShortcutOverride event filter
- Add delete confirmation dialog before removing clips from disk + DB
- Export button turns red "Overwrite" when a marker is selected
- Reset stale overwrite/delete state when switching files
- Remove auto-advance after export; add N shortcut to advance manually
- Widen marker hit zones (±6→±10px click, ±4→±8px hover)
- Marker tooltip shows filename instead of full path
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Parallelize batch ffmpeg exports with ThreadPoolExecutor
- Show playback progress as color fill in timeline selection region
- Single click moves playhead, double-click selects/deselects markers
- Reset clip count and spread to defaults when switching videos
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Emit marker_clicked before seek, and use a flag to prevent
_on_cursor_changed from immediately clearing the overwrite state
and settings that were just restored.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Legacy records get new columns with sensible defaults and are preserved
as markers. No more data loss on schema upgrade.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DB now stores short_side, portrait_ratio, crop_center, format,
clip_count, and spread per export. Clicking a marker restores all
fields to the original export settings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each batch export creates a subfolder named after the group (e.g.
clip_001/) containing all sub-clips and their audio files. Keeps
the top-level export folder clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pending marker uses cursor position for the whole batch. DB markers
deduplicated by start_time since all sub-clips share the same cursor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the random portrait checkbox is on and portrait dropdown is Off,
the crop bar appears and the video overlay shows 2 red vertical lines
(instead of filled red bands) indicating the 9:16 crop boundaries.
Clicking the crop bar or video adjusts the crop center position.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Small panel to the right of the video displays the frame at cursor +
clip_span. Updated with 300ms debounce on cursor move, spread/clip
count change, and file load. Uses ffmpeg to grab a single PNG frame
off the main thread.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Checkbox '1 random portrait' in settings row. When checked, one random
clip in each batch receives a randomly chosen portrait ratio (9:16, 4:5,
or 1:1) with a random crop center. The rest use the global portrait
setting. Disabled for single-clip overwrite exports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each export generates clip_NNN_0, clip_NNN_1, clip_NNN_2 offset by the
spread value (2–8s, default 3s). Preview plays the full span covered by
all three clips. Marker click still overwrites a single clip.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Targets last export by default; targets marker-selected clip when one is
active (shown as "Delete <name>"). Clears on cursor move if no last export.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each exported clip writes an entry to <folder>/dataset.json containing
its relative path, sound label, and fps. Re-exporting to the same path
updates the existing entry (upsert). Empty labels are skipped.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>