Commit Graph
303 Commits
Author SHA1 Message Date
EthanfelandClaude Opus 4.8 4a34a87d37 feat: editor playback + temp cleanup on close + docs (v1.6)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:31:13 +02:00
Ethanfel 4d54f29514 feat: wire editor ops (delete/silence/reverse/trim) + undo/redo + save-as 2026-07-02 18:22:39 +02:00
EthanfelandClaude Opus 4.8 a11e4859dd feat: AudioEditorDialog scaffold + Edit-clip entry point (ops stubbed)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:09:54 +02:00
Ethanfel 68368b4ff6 feat: double-click a merge clip to set its join crossfade/curve override + row labels 2026-07-02 17:50:40 +02:00
EthanfelandClaude Opus 4.8 65200e482e feat: global crossfade curve combo + per-join render/guard plumbing
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:40:01 +02:00
EthanfelandClaude Opus 4.8 449b3dfa72 feat: waveform playhead during audition + docs (v1.5)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:27:37 +02:00
Ethanfel 356cfcc7d7 feat: wire interactive waveform selection to cursor/length (two-way, clamped view) 2026-07-02 17:18:26 +02:00
Ethanfel 25fbf8142f feat: waveform drag-select + wheel zoom (selection_changed/view_changed) 2026-07-02 17:06:46 +02:00
Ethanfel 7ca894d585 feat: waveform view/selection state + band/handle painting 2026-07-02 16:56:36 +02:00
Ethanfel 43326730f2 polish: preview failure dialog + clean audition temp on close + drop redundant Qt imports 2026-07-02 16:35:53 +02:00
EthanfelandClaude Opus 4.8 14ec29dbbe feat: merge temp cleanup on close + v1.4 changelog + README (Phase 2)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 16:21:10 +02:00
Ethanfel 3922fc5174 feat: merge save + preview (crossfade render, duration guard, ffplay preview) 2026-07-02 16:18:29 +02:00
Ethanfel b8aa1606d8 feat: Merge sequence — add (file/selection), reorder, remove 2026-07-02 16:04:01 +02:00
EthanfelandClaude Opus 4.8 de7da3cad6 feat: Merge pane (3rd Audio QToolBox page) — list + crossfade + buttons
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:54:05 +02:00
Ethanfel 578ad87b1a docs: Audio workspace tab (Phase 1) — v1.3 changelog + README; drop orphaned transport spacer 2026-07-02 15:18:38 +02:00
EthanfelandClaude Opus 4.8 c57c078100 feat: play/stop audition of the current audio region
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:13:06 +02:00
Ethanfel 7501c4729b refactor: cap waveform decode length + guard frombuffer + tighten test 2026-07-02 15:00:34 +02:00
Ethanfel 12eaa944a7 feat: read-only waveform strip + manual refresh in the Audio tab 2026-07-02 14:53:32 +02:00
Ethanfel 8e03b97742 feat: extract honors format picker + fade/normalize/gain edits 2026-07-02 14:47:49 +02:00
Ethanfel c9a4ac584f feat: Audio tab QToolBox — Extract & Edit + Scan/Classify panes 2026-07-02 14:35:22 +02:00
Ethanfel 4b3b25ffae feat: audio format + fade/normalize/gain widgets; free them from the transport row 2026-07-02 14:26:06 +02:00
EthanfelandClaude Opus 4.8 52ce2d451a refactor: rename Scan deck tab -> Audio (deck wiring only)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:13:48 +02:00
EthanfelandClaude Opus 4.8 eab5c690c7 feat: audio area length — remove the upper cap + step by 1s
The audio extract length is meant for visualizing/grabbing sequences that can
run minutes long, but the control capped it and stepped in fiddly 0.10s
increments. Raise the range to effectively unlimited (24h; ffmpeg stops cleanly
at end-of-file if the source is shorter) and make the arrows step 1s — typing
still allows sub-second precision. Widen the field for the larger values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 01:11:57 +02:00
EthanfelandClaude Opus 4.8 4445f0e7f4 fix: audio extract honored a silent length clamp — 30s near the end became 3s
_on_extract_audio clamped the duration to (timeline_duration - cursor), so with
the playhead within the requested length of the end (or any under-reported
duration) a 30s request was silently truncated to whatever remained — the user
asked for 30s and got 3s with no indication why.

Drop the clamp: pass the requested length straight to ffmpeg, which stops
cleanly at end-of-file if the source is shorter. Then ffprobe the result and,
when it comes up short, say so ("Saved 3.0s — source ended before 30.0s
requested") instead of silently shrinking. When there's room, 30s now yields
exactly 30s.

Adds core.ffmpeg.probe_duration(). Verified end-to-end: a fitting request
returns the exact length; a genuine near-end request returns the available
audio (rc=0) and is reported as truncated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:07:35 +02:00
EthanfelandClaude Opus 4.8 ed63d04abf feat: Extract audio area — exact-length audio slice from the playhead, save-as
A dedicated "♪ Extract audio" button on the transport row grabs an exact
length of audio (set via the adjacent length box, from the playhead) and opens
a Save As dialog. Output format follows the chosen extension — WAV (pcm_s16le),
MP3 (libmp3lame), FLAC, m4a/aac, ogg/opus — re-encoding as needed; unknown
extensions let ffmpeg pick from the container.

- core.ffmpeg.build_audio_clip_command(input, start, duration, out_path):
  fast-seek + exact -t duration + -vn, codec by extension. Verified end-to-end
  (wav/mp3/flac all land at exactly the requested duration).
- Timeline shows the audio area as a distinct teal dashed band spanning
  [cursor, cursor+length], updated live as the playhead or length changes, so
  you see exactly what will be extracted.
- Length + last save dir persist in QSettings; button enabled once a file loads.

Tests: 3 core (codec-by-extension, exact length, case-insensitive) + 2 GUI
(controls exist, band tracks cursor/length).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:48:24 +02:00
EthanfelandClaude Opus 4.8 7ae1720b9e fix: subcategory export buttons hidden by ghost entries + give them their own centered row
Two issues with the per-subprofile (subcategory) export buttons:

1. Visibility was decided by a fuzzy `f.endswith("_" + suffix)` match against
   the hidden-subcats set. A ghost "_blowjob" (empty-base leftover from the
   trailing-slash folder bug) or an unrelated "mp4_no_clap" would match and
   hide the wrong button — so enabling a subcategory in the Sub menu never
   revealed its export button. Match the exact "<base>_<suffix>" folder name
   instead (same name the menu shows and _hidden_subcats stores).

2. The buttons were crammed into the transport row after Export. Move them to
   their own row with stretches on both ends so the (often many) "▸ name"
   buttons stay centered and out of the transport controls.

Also cleared the polluted hidden_subcats/POV_Front set in the user's QSettings
(ghost "_*" names + a hide-all'd set of real "mp4_*"), so every subcategory is
visible again. Regression test added for the exact-match predicate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:19:20 +02:00
EthanfelandClaude Fable 5 514607eddd fix: harden export-folder base derivation against a trailing slash
A folder ending in "/" made os.path.basename() return "", so subprofile
folders/labels became "_blowjob" instead of "mp4_blowjob" — cluttering the
subcategory menu and breaking the marker↔category match. rstrip the trailing
separator in _tab_export_folder and the three basename(_txt_folder) sites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-19 13:54:32 +02:00
EthanfelandClaude Fable 5 4299de5f97 fix: keep length control + mode in sync on every active-tab switch; dup preserves LTX-2; auto-export + frames use legal LTX-2 length
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 15:35:46 +02:00
EthanfelandClaude Fable 5 86ab606059 docs: changelog + README for LTX-2 mode + tab features (v1.2)
Bump APP_VERSION to 1.2 and add a 1.2 changelog entry covering the
per-tab export folder + mismatch guardrail, Duplicate tab, and LTX-2
export mode. README Interface section gains matching bullets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 15:16:18 +02:00
EthanfelandClaude Fable 5 87ccd8650c feat: honor LTX-2 mode in re-export and auto-export
Mirror the manual export path: re-export and auto-export now read the
active tab's LTX-2 params via _ltx2_export_params() and override
short_side/duration plus thread target_fps/snap32/frames through to
ExportWorker. Foley tabs return None and keep byte-identical behavior.
For auto-export, params are captured at batch-build time so queued
batches keep their own geometry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 15:16:02 +02:00
EthanfelandClaude Fable 5 ad9e564991 feat: LTX-2 frames length control + route 25fps/÷32/exact-frames through export
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 15:10:07 +02:00
EthanfelandClaude Fable 5 4baac54930 feat: per-tab LTX-2 mode toggle + [LTX2] badge (pipeline wiring in next stage)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 15:03:32 +02:00
EthanfelandClaude Fable 5 1eb7de2a1a fix: duplicate-tab folder is a sibling, not a child, when source ends in /
".../AlexisCrystal/" + "_copy" was producing ".../AlexisCrystal/_copy"; rstrip
the trailing separator first → ".../AlexisCrystal_copy". Regression test uses a
trailing-slash source folder.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 14:52:12 +02:00
EthanfelandClaude Fable 5 bf4b6dad2d feat: right-click "Duplicate tab" — clone files into a new tab with adapted name + own folder
New tab copies the source tab's video list + separators, gets a unique
"<name> copy" label and an adapted own export folder ("<folder>_copy"), and
inherits the tab-named-folder flag. No files are moved or copied — you export
into the new tab's folder. Keeps Foley/variant datasets separate without the
file-shuffling that a misexport used to require.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-18 14:36:47 +02:00
EthanfelandClaude Fable 5 4715c0ce49 fix: sync export folder when selecting a file in a side-by-side list; tighten guardrail; rename per-tab attr
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-16 01:06:21 +02:00
EthanfelandClaude Fable 5 e5ce59c065 feat: bind export folder to each file-list tab + export-folder mismatch guardrail
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-16 00:56:55 +02:00
EthanfelandClaude Fable 5 cbbdfeadb1 feat: logo-based icon set + accent aligned to brand palette
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:56:54 +02:00
EthanfelandClaude Fable 5 8a7d761815 chore: drop stale scaffolding comments flagged in final review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:47:41 +02:00
EthanfelandClaude Fable 5 140a424469 docs: changelog + README for the UI overhaul (v1.1)
Bump APP_VERSION to 1.1 with a "What's new" entry covering the menu bar,
tabbed control deck, side-by-side panels, status bar, and visual polish.
Add an Interface section to the README. Shortcuts unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:39:53 +02:00
EthanfelandClaude Fable 5 bc6e30a2d4 change: deck split shows exactly the pinned panels (no leftover column)
Pinning 2 of 3 panels previously showed a 3rd "leftover" tab-column, which
read as all-three-pinned and was confusing. Now the split view shows exactly
the pinned panels (pin 2 -> 2 columns, pin 3 -> 3). Adds an always-available
View > Side-by-side panels submenu of checkable toggles as the way to pin a
panel while already in split view (the right-click-tab gesture only works in
tabbed mode). Tests assert exactly-N-columns and the menu-pin path; the win
fixture now resets deck state so tests don't depend on persisted layout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:26:35 +02:00
EthanfelandClaude Fable 5 2ea3a9149a fix: allow pinning the 3rd deck panel from split mode; dedupe header height
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:50:04 +02:00
EthanfelandClaude Fable 5 780832d4aa feat: side-by-side mode for the control deck (pin panels into columns)
Mirror the playlist pin→side-by-side pattern for the Export / Crop &
Track / Scan control-deck panels. Right-click a deck tab → "Show
side-by-side"; pinning 2+ panels lays them out as resizable QSplitter
columns, with any unpinned panel kept reachable in a leftover tab-column.
The ✕ header returns a panel to tabs. State persists across launches via
the deck_pinned QSettings key.

- _DeckTabBar: minimal QTabBar emitting pin_toggle_requested(idx).
- _build_control_deck wraps _control_deck + a split container in a
  QStackedWidget (_deck_stack), mounted in right_layout in its place;
  sets _pinned/_label/_deck_key on each page; builds _deck_panels.
- _refresh_deck_layout / _detach_deck_panels / _clear_deck_split /
  _on_deck_pin_toggle / _on_deck_unpin / _save_deck_layout, guarded by
  _deck_loading. Reparented pages are setVisible(True) so they don't
  render blank (same gotcha the playlist documents).
- Restore block at the end of __init__ reads deck_pinned (str/list).
- Height-pin now targets _deck_stack and fits the tallest split-mode
  column (22px header + content) so split mode never clips.

Default (nothing pinned) behaves exactly like the prior tabbed deck.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:36:03 +02:00
EthanfelandClaude Fable 5 035eaf3894 style: unified theme, primary Export, group separators, clearer labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:19:25 +02:00
EthanfelandClaude Fable 5 35ea1baec8 fix: keep Subprofiles▸Remove menu in sync with subprofile changes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:15:07 +02:00
EthanfelandClaude Fable 5 6a71386ed8 fix: robust deck height, state-aware Scan/Train menu items, import cleanup
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:04:15 +02:00
EthanfelandClaude Fable 5 d1fb35af8e refactor: populate Crop & Scan tabs; menu-only buttons hidden; drop settings row
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:54:10 +02:00
EthanfelandClaude Fable 5 c55693094d refactor: add control deck; move export/encode controls into Export tab
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:48:26 +02:00
EthanfelandClaude Fable 5 5832d08b26 feat: real status bar replaces inline status label
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:37:52 +02:00
EthanfelandClaude Fable 5 b4cfa7561a fix: resolve menu-bar shortcut collision, checkmark desync, brittle test
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:33:05 +02:00
EthanfelandClaude Fable 5 0ccc29709e feat: add menu bar wired to existing handlers; move profile selector and help into menu-bar corner
Adds MainWindow._build_menubar building File/Edit/Scan/View/Help menus
whose actions reuse the existing handler methods. Profile combo and the
? shortcuts button move from top_bar into a TopRightCorner widget. Adds
_show_about and _rebuild_remove_subprofile_menu helpers. Bidirectional
sync for Hide exported / Show hidden; forward-only sync for Review mode
(reverse added in a later stage).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 11:24:24 +02:00