Commit Graph
100 Commits
Author SHA1 Message Date
EthanfelandClaude Opus 4.6 97986d5138 fix: save/restore scrollbar position to prevent playlist scroll jumping
setCurrentRow, setHidden, and setText all trigger Qt internal scroll
recalculation. Now save scrollbar value before these operations and
restore it after, then use scrollToItem only to bring off-screen
selections into view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 23:40:17 +02:00
EthanfelandClaude Opus 4.6 3c903c7188 feat: right-click keyframe diamond on timeline to delete it
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:11:32 +02:00
EthanfelandClaude Opus 4.6 bef08be091 fix: crop keyframe in lock mode updates video overlay and preview lines
The lock-mode path was only updating the crop bar but not the video
overlay or random overlays. Now sets _crop_center and calls the
appropriate overlay update.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:10:02 +02:00
EthanfelandClaude Opus 4.6 ccc94ccb5c fix: preview crop lines match main overlay colors
Portrait lines are red, square lines are blue — matching the video
overlay. Both shown simultaneously when both random options are on.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:07:07 +02:00
EthanfelandClaude Opus 4.6 d031d6c285 fix: hide-exported checkbox state applied on session resume
_apply_playlist_filters now syncs _hide_exported from checkbox before
refreshing visibility, so exported files are hidden immediately on
startup without needing to toggle the checkbox.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:03:08 +02:00
EthanfelandClaude Opus 4.6 9696b94b0c fix: preview crop shows lines only (no dim), updates on random toggle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 17:00:44 +02:00
EthanfelandClaude Opus 4.6 633e421a68 feat: show crop region overlay on end-frame preview
PreviewLabel widget replaces plain QLabel, draws dimmed areas outside
the crop window and blue border lines matching the crop bar position.
Updates live when portrait ratio or crop center changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:58:31 +02:00
EthanfelandClaude Opus 4.6 a543c72ff5 fix: prevent scroll jumping by batching visibility and layout updates
- _apply_visibility wraps setHidden loop with setUpdatesEnabled and
  scrolls back to current item after
- _refresh_playlist_checks wraps mark_done/unmark_done loop similarly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:55:21 +02:00
EthanfelandClaude Opus 4.6 31772b898c fix: hidden files reappear on restart, scroll jumps on selection
- Centralize item visibility in _apply_visibility: hidden if
  profile-hidden OR (hide_exported AND done)
- mark_done/unmark_done no longer touch setHidden directly
- Session resume selects first visible item after filters applied
- add_files defers to _select_first_visible to skip hidden items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:53:17 +02:00
EthanfelandClaude Opus 4.6 9b8d742fde fix: scroll to selected item to prevent list jumping on click
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:49:01 +02:00
EthanfelandClaude Opus 4.6 8392c022f6 feat: session resume, hide exported files, profile-based file hiding
- Resume last session: reload previous playlist files on startup
- Hide exported checkbox: filter out files with existing clips
- Profile-based hiding: right-click → "Hide in profile" persists via DB
- Playlist scrollbar fix: disable updates during batch add
- Drop event and profile switch use unified _apply_playlist_filters()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:47:44 +02:00
EthanfelandClaude Opus 4.6 d4357f0da4 feat: cursor lock with crop keyframing, remove fuzzy filename matching
- Lock button (G key) freezes export cursor, timeline scrubs playback only
- In lock mode, clicking crop bar sets a keyframe at current playback time
- Orange diamonds on timeline show keyframe positions
- Export resolves per-clip crop center from nearest preceding keyframe
- Crop bar/overlay updates while scrubbing to preview effective crop
- Unlocking clears all keyframes
- Replace fuzzy filename matching with exact match to prevent marker bleed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:34:49 +02:00
EthanfelandClaude Opus 4.6 2dcf9bc856 fix: preview window stays on top and raises with main window
- Add WindowStaysOnTopHint to keep preview above other windows
- Raise preview on main window activation (alt-tab, taskbar click)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 15:39:49 +02:00
EthanfelandClaude Opus 4.6 703874721b feat: YOLO subject tracking for per-clip crop centering, fix end-frame preview
- 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>
2026-04-13 15:12:17 +02:00
EthanfelandClaude Opus 4.6 bd37938a4a fix: playlist shows clip count per file, export counter fills gaps after delete
- 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>
2026-04-13 13:37:59 +02:00
EthanfelandClaude Opus 4.6 e28af38743 fix: compact playlist rows by replacing word wrap with middle ellipsis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 13:16:24 +02:00
EthanfelandClaude Opus 4.6 039d383cf6 fix: VAAPI filter chain, overwrite duplicates, export cursor stash, shutdown guards
- 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>
2026-04-13 13:07:20 +02:00
EthanfelandClaude Opus 4.6 e283d96417 feat: HW encode toggle, workers control, GPU decode, verbose logging, UI polish
- 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>
2026-04-13 12:56:00 +02:00
EthanfelandClaude Opus 4.6 1e99035393 feat: random square crop, shortcuts dialog, profile dropdown, video aspect fix
- 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>
2026-04-13 12:10:39 +02:00
EthanfelandClaude Opus 4.6 0e38c5666e fix: reset overwrite/delete state on profile switch
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>
2026-04-13 11:22:20 +02:00
EthanfelandClaude Opus 4.6 f9c5a42453 fix: make QComboBox dropdown arrow visible in dark theme
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>
2026-04-13 11:20:09 +02:00
EthanfelandClaude Opus 4.6 f8b148f77d feat: profile support for independent marker sets
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>
2026-04-13 11:08:50 +02:00
EthanfelandClaude Opus 4.6 462af36bce docs: replace SELVA references with foley
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 03:01:38 +02:00
EthanfelandClaude Opus 4.6 ae15f9ef32 docs: add social preview SVG/PNG and logo PNG
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 03:00:45 +02:00
EthanfelandClaude Opus 4.6 2ef387d87b docs: update README and add SVG logo
- 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>
2026-04-13 02:58:47 +02:00
EthanfelandClaude Opus 4.6 bcdda9c783 fix: UI audit — dark theme styling, group delete/overwrite, layout cleanup
- 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>
2026-04-13 02:56:26 +02:00
EthanfelandClaude Opus 4.6 e2b4f9bf8d remove: mask generation, venv setup, and settings dialog
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>
2026-04-12 15:53:31 +02:00
EthanfelandClaude Opus 4.6 bb6e3c623a fix: UX audit — shortcuts in text fields, delete confirmation, overwrite indicator
- 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>
2026-04-12 15:49:27 +02:00
EthanfelandClaude Opus 4.6 89e0478777 feat: parallel export, playback position, double-click markers, reset clips on video switch
- 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>
2026-04-12 11:42:40 +02:00
EthanfelandClaude Sonnet 4.6 c287788d9e fix: marker click properly restores settings without cursor clear race
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>
2026-04-12 11:01:29 +02:00
EthanfelandClaude Sonnet 4.6 5a5961ae21 fix: default short_side to 512 in DB schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 02:55:09 +02:00
EthanfelandClaude Sonnet 4.6 c174d891fb fix: migrate DB schema with ALTER TABLE instead of dropping old data
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>
2026-04-12 02:53:12 +02:00
EthanfelandClaude Sonnet 4.6 74e8656335 feat: save and restore all export config on marker click
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>
2026-04-12 02:52:02 +02:00
EthanfelandClaude Sonnet 4.6 206b95fc28 feat: restore label and category when clicking a marker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 02:49:48 +02:00
EthanfelandClaude Sonnet 4.6 f11b3e298e feat: group clips into subfolders (clip_001/, clip_002/, etc.)
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>
2026-04-12 01:05:10 +02:00
EthanfelandClaude Sonnet 4.6 22e2ad27a0 fix: show one marker per batch, not one per sub-clip
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>
2026-04-12 00:41:41 +02:00
EthanfelandClaude Sonnet 4.6 fee907f26f fix: raise clip count limit from 10 to 99
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 00:37:57 +02:00
EthanfelandClaude Sonnet 4.6 122f89547b feat: show crop bar with vertical lines when random portrait is enabled
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>
2026-04-12 00:30:49 +02:00
EthanfelandClaude Sonnet 4.6 b6e7b660a8 fix: scale end-frame preview to 320x240
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 00:18:48 +02:00
EthanfelandClaude Sonnet 4.6 2304286147 fix: make end-frame preview a floating tool window
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:55:43 +02:00
EthanfelandClaude Sonnet 4.6 abe9e6ee66 feat: end-frame preview panel showing last frame of clip spread
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>
2026-04-11 23:52:56 +02:00
EthanfelandClaude Sonnet 4.6 01961e9192 fix: move QSettings init before timeline setup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:44:46 +02:00
EthanfelandClaude Sonnet 4.6 d3e48f5276 fix: random portrait uses configured crop position, only randomizes which clip
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:43:16 +02:00
EthanfelandClaude Sonnet 4.6 0996670020 fix: random portrait always uses 9:16
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:40:47 +02:00
EthanfelandClaude Sonnet 4.6 ffb99d3e66 fix: scale random portrait count — 1 per 3 clips (e.g. 2 for 6 clips)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:39:42 +02:00
EthanfelandClaude Sonnet 4.6 439bc85505 feat: random portrait — one clip per batch gets a random crop ratio + position
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>
2026-04-11 23:38:56 +02:00
EthanfelandClaude Sonnet 4.6 13973dd53d fix: read clip_count/spread from settings before timeline init
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:34:03 +02:00
EthanfelandClaude Sonnet 4.6 9e07910df1 feat: make clip count configurable (1–10, default 3)
Clips spinbox in settings row alongside Spread. Preview span and export
batch size adjust dynamically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:28:12 +02:00
EthanfelandClaude Sonnet 4.6 25250d6d8d fix: use lossless PCM audio in MP4 exports
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:26:02 +02:00
EthanfelandClaude Sonnet 4.6 93cee40b06 feat: export 3 overlapping 8s clips per press with configurable spread
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>
2026-04-11 23:22:41 +02:00
EthanfelandClaude Sonnet 4.6 47ea6199fa feat: add Delete button to remove exports from disk, DB, and dataset.json
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>
2026-04-07 14:23:16 +02:00
EthanfelandClaude Sonnet 4.6 8bc42cabd9 fix: store absolute paths in dataset.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:10:06 +02:00
EthanfelandClaude Sonnet 4.6 8148971aae refactor: remove fps from annotation — path + label only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:09:08 +02:00
Ethanfel a8d8bd7fdc Revert "fix: pass source fps to ffmpeg export via fps filter"
This reverts commit fc9287a5a6.
2026-04-07 14:08:00 +02:00
Ethanfel f0484fac86 Revert "feat: write fps.txt alongside WebP sequence audio"
This reverts commit cf62940b84.
2026-04-07 14:08:00 +02:00
EthanfelandClaude Sonnet 4.6 fd25e8fa37 feat: add migration script to generate dataset.json from DB history
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:04:29 +02:00
EthanfelandClaude Sonnet 4.6 c3c480acc7 feat: replace dataset.tsv with dataset.json annotation file
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>
2026-04-07 14:01:50 +02:00
Ethanfel cf62940b84 feat: write fps.txt alongside WebP sequence audio 2026-04-07 13:56:13 +02:00
Ethanfel fc9287a5a6 fix: pass source fps to ffmpeg export via fps filter 2026-04-07 13:54:38 +02:00
Ethanfel 1256819dde ui: warn mask generation is untested, recommend ComfyUI 2026-04-07 12:35:44 +02:00
Ethanfel 58043dd7e3 docs: warn mask generation is untested, recommend ComfyUI 2026-04-07 12:35:13 +02:00
Ethanfel a652872d15 docs: add GPL v3 license and GitHub source link 2026-04-07 12:34:13 +02:00
EthanfelandClaude Sonnet 4.6 9d7791557b revert: restore ff0cd00 (label history, overwrite mode, crop overlay)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:11:36 +02:00
EthanfelandClaude Sonnet 4.6 2352d530d0 feat: queue done marks, export UX, scrub-while-playing, counter fix
- Queue ✓: mark files green after export and on drop if already in DB
- Export folder auto-created if missing
- Scrub while playing: cursor drag seeks and continues playback
- Counter auto-advances past existing files on disk
- Instant pending marker on timeline when export starts
- WebP quality 92 + lanczos scaling
- seek() guard against unloaded state (SystemError fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:41:07 +02:00
Ethanfel 6e02a08046 Revert "feat: label history, overwrite mode, crop overlay, UX improvements"
This reverts commit ff0cd00309.
2026-04-07 11:36:40 +02:00
EthanfelandClaude Sonnet 4.6 ff0cd00309 feat: label history, overwrite mode, crop overlay, UX improvements
- Editable label combo with DB history (most recent first)
- Click marker to arm overwrite mode (↺ indicator, re-exports same file)
- Portrait crop overlay: red bands on cut regions (paused only)
- Cache video dimensions to avoid mpv property reads in paintEvent
- Queue marks done files with ✓ on drop and after export
- Export folder created automatically if missing
- Play continues from new position when scrubbing during playback
- Counter auto-advances past existing files on disk
- Instant marker on timeline when export starts (optimistic)
- Marker right-click delete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:34:47 +02:00
EthanfelandClaude Sonnet 4.6 6573fa6e05 feat: mpv Wayland embedding, timeline redesign, UX polish
mpv embedding:
- Replace wid/QOpenGLWidget with QOffscreenSurface + QOpenGLFramebufferObject
  + QPainter readback — works on Wayland/KDE without sub-surface compositing
- Force desktop OpenGL 3.3 core profile before QApplication (fixes black output on GLES)
- Timer-based render polling (16 ms) replaces signal-flood from mpv C thread;
  fixes playback animation and scrubbing preview
- Fix AB-loop: set ab-loop-a/b to "no" on stop (0 means infinite in mpv)

Timeline:
- Full redesign: time ruler with adaptive major/minor ticks, playhead triangle
  handle, selection region with edge lines, numbered marker badges
- Height 160 px; layout collapsed from 4 rows to 2 below timeline
- Markers appear immediately on export (optimistic update before ffmpeg finishes)
- Right-click marker → context menu to delete from DB

Hotkeys:
- Replace keyPressEvent with QShortcut(ApplicationShortcut) so keys work
  regardless of focused widget; MpvWidget gets NoFocus policy

Export:
- WebP: switch lossless→lossy quality 85, compression_level 1 (~10x faster)
- Add -threads 0 for full CPU utilisation during decode/filter
- Remember last export folder across sessions via QSettings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 22:22:58 +02:00
Ethanfel 7931a0e3db debug: write mpv log to /tmp/8cut-mpv.log 2026-04-06 20:56:14 +02:00
Ethanfel 939199717f fix: use QOpenGLContext.getProcAddress for mpv render context proc lookup 2026-04-06 20:54:19 +02:00
Ethanfel 8863634bce debug: add mpv log output and initializeGL trace 2026-04-06 20:51:11 +02:00
Ethanfel e5f2c732d9 fix: wrap get_proc_address as CFUNCTYPE for mpv render context 2026-04-06 20:50:02 +02:00
Ethanfel 1e0c1ae892 fix: replace wid embedding with OpenGL render context — works on Wayland and X11 2026-04-06 20:48:59 +02:00
Ethanfel 2c95c2618a debug: print platform/wid/WAYLAND_DISPLAY at mpv init 2026-04-06 20:41:55 +02:00
Ethanfel c130010e36 fix: hide WAYLAND_DISPLAY during mpv init so it uses X11 wid embedding 2026-04-06 20:41:16 +02:00
Ethanfel 02c63bdfde fix: force QT_QPA_PLATFORM=xcb so mpv embeds correctly on Wayland sessions 2026-04-06 20:39:12 +02:00
Ethanfel f30955b63c debug: print drag-drop events to diagnose Wayland DnD 2026-04-06 20:37:13 +02:00
Ethanfel c80ebf9383 fix: move drag-drop to MainWindow to bypass QListWidget viewport on Wayland 2026-04-06 20:35:47 +02:00
Ethanfel 3d92a66660 fix: re-apply LC_NUMERIC=C after QApplication resets locale 2026-04-06 20:33:51 +02:00
Ethanfel bdfb9354ca fix: set LC_NUMERIC=C before mpv init to prevent segfault on non-C locales 2026-04-06 20:32:56 +02:00
Ethanfel 41c36267e9 fix: use NoDragDrop mode + viewport.setAcceptDrops for Wayland/KDE compatibility 2026-04-06 20:31:37 +02:00
Ethanfel d720fc0541 fix: accept dragMoveEvent so file drops work on all desktop environments 2026-04-06 20:30:31 +02:00
Ethanfel 31f4df4c5b fix: suppress QFrame paintEvent on mpv native window 2026-04-06 20:29:06 +02:00
Ethanfel 39bbfedb9d fix: suppress paintEngine warnings from mpv native window embedding 2026-04-06 20:28:00 +02:00
Ethanfel 025d5afe1f chore: add shebang for direct execution 2026-04-06 20:25:07 +02:00
EthanfelandClaude Sonnet 4.6 191d1cf299 fix: move SELVA_CATEGORIES to module level, harden append_to_tsv, fix tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:48:46 +02:00
EthanfelandClaude Sonnet 4.6 c76eb9ec84 feat: add label/category annotation fields and TSV export for SELVA
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:45:29 +02:00
Ethanfel 8fb8782e65 fix: use correct venv path on Windows (Scripts/python.exe) 2026-04-06 18:30:37 +02:00
Ethanfel a74e5022b3 docs: add README 2026-04-06 18:28:59 +02:00
EthanfelandClaude Sonnet 4.6 e62a712de2 perf: skip redundant repaints, cache fps, O(1) playlist dedup, fix worker leak
- TimelineWidget.set_cursor: skip update() when clamped value is
  unchanged (e.g. clicking at the boundary repeatedly).
- MainWindow: cache container_fps in self._fps on file load; keyPressEvent
  reads the cached value instead of hitting the mpv property on every key.
- PlaylistWidget: add _path_set (set[str]) alongside _paths (list[str])
  so duplicate detection in add_files is O(1) instead of O(N).
- SettingsDialog._on_install: quit+wait any previous SetupWorker before
  starting a new one, preventing leaked threads and duplicate signal
  connections on repeated installs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:18:31 +02:00
EthanfelandClaude Sonnet 4.6 16e0bc231c perf: playlist O(1) updates, marker hover cache, crop pen cache, keyboard debounce, export marker fast-path
- PlaylistWidget._select: only update the two items whose label changes
  (old current → plain name, new current → add ▶) instead of rewriting
  every item in the playlist.
- TimelineWidget: pre-compute (t/duration, path) fractions in
  _hover_cache on set_markers/set_duration so mouseMoveEvent avoids
  dividing by duration on every pixel of mouse movement.
- CropBarWidget: cache QPen in __init__ instead of recreating per frame.
- _step_cursor: update label/state immediately and start the timeline's
  existing _seek_timer instead of calling _on_cursor_changed directly,
  so held arrow keys are debounced the same as mouse drag.
- _refresh_markers: call _get_markers_for(filename) directly after
  export (exact match known) and only fall back to fuzzy find_similar
  when no exact-match rows exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:07:58 +02:00
EthanfelandClaude Sonnet 4.6 4c44d78c37 perf: seek debounce, cached paint resources, async DB lookup, regex pre-compile
- TimelineWidget: debounce cursor_changed signal with 16ms timer so
  mpv.seek is called at most ~60/s during drag; flush on mouseRelease.
  Cache QPen/QFont objects in __init__ instead of recreating per frame.
- _normalize_filename: compile _QUALITY_RE and _SEP_RE once at module
  level instead of on every call.
- ProcessedDB: add check_same_thread=False; add _get_markers_for() to
  avoid a second find_similar pass; store db path.
- _DBWorker(QThread): runs find_similar + _get_markers_for off the main
  thread. _after_load starts the worker instead of blocking; stale
  results discarded if the user loads a different file first.
- MainWindow: reuse self._settings instead of creating a new QSettings
  instance in the mask row setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 18:04:18 +02:00
EthanfelandClaude Sonnet 4.6 b57131a3d9 feat: keyboard navigation for timeline
Arrow keys / J / L: step one frame; Shift = 1 second jump
Space / P: toggle play/pause
K: pause and return to cursor
E: trigger export
M: jump to next export marker (wraps)

Keys are suppressed when a text field has focus.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:35:46 +02:00
EthanfelandClaude Sonnet 4.6 9652b249ba feat: extract audio alongside WebP image sequence
Adds build_audio_extract_command and runs it in ExportWorker after the
frame sequence completes. Audio written to <sequence_dir>.wav (lossless
pcm_s16le). Extraction failure (no audio stream) is silently ignored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:20:40 +02:00
Ethanfel fe3e642dfa fix: guard mask generation against WebP sequence export path 2026-04-06 17:19:03 +02:00
Ethanfel 855797a1b3 docs: clarify _last_export_path holds dir path for WebP sequence 2026-04-06 16:07:44 +02:00
Ethanfel f9649f7584 feat: wire WebP sequence format into export flow 2026-04-06 16:05:26 +02:00
Ethanfel 13c8a8aeab style: rename fmt_idx to idx in _cmb_format setup 2026-04-06 16:04:30 +02:00
Ethanfel c163b298c4 feat: add format combo (MP4 / WebP sequence) to export row 2026-04-06 16:02:26 +02:00
Ethanfel d3c4dea597 fix: guard makedirs in ExportWorker.run inside try/except 2026-04-06 16:01:16 +02:00
Ethanfel f86442322f feat: ExportWorker supports image_sequence mode 2026-04-06 15:59:17 +02:00