Commit Graph
447 Commits
Author SHA1 Message Date
Ethanfel 678f6e5cc4 feat: add heal cut ffmpeg command 2026-07-04 20:14:19 +02:00
Ethanfel fec08cfcb3 docs: plan audio heal cut implementation 2026-07-04 20:13:21 +02:00
Ethanfel 7ff870ee88 docs: design audio timeline picker and heal cut 2026-07-04 19:42:17 +02:00
Ethanfel 158483ce42 feat: '+ To library' — add the current audio area straight to the clip library 2026-07-04 01:11:05 +02:00
EthanfelandClaude Opus 4.8 0e82a82cde feat: auto-add extracted/edited clips to the library + library Edit opens the editor (v1.7)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 00:54:43 +02:00
Ethanfel f32d303d26 feat: persistent Library tab in ScanResultsPanel (survives per-file rebuilds) 2026-07-04 00:20:23 +02:00
Ethanfel 5dc7499d7f feat: AudioLibraryTab — persistent extracted-clip library (add/edit/re-export/play/remove) 2026-07-04 00:06:10 +02:00
Ethanfel 7f414d80b8 feat: Audio tab drives timeline audio-mode; drag the band to set the extract region 2026-07-03 02:23:30 +02:00
Ethanfel a993de615c feat: timeline audio-mode — hide clip span, draggable/resizable audio band 2026-07-03 02:10:04 +02:00
EthanfelandClaude Opus 4.8 283bc65588 fix: escape ampersand in 'Extract && Edit' QToolBox title
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 01:57:43 +02:00
EthanfelandClaude Opus 4.8 d8b890d679 fix: editor cleanup on Escape/reject + stop main audition on open
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:41:41 +02:00
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 1553d7faf0 feat: destructive audio op command builders (delete/silence/reverse region) 2026-07-02 17:54:11 +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
Ethanfel a298418156 feat: per-join crossfade durations + acrossfade curve in build_crossfade_merge_command 2026-07-02 17:35:26 +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 ee7de4d83c feat: pixel<->time geometry helpers for the waveform 2026-07-02 16:54:00 +02:00
EthanfelandClaude Opus 4.8 86980b38cf docs: Phase 3a implementation plan — interactive waveform selection
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 16:52:29 +02:00
EthanfelandClaude Opus 4.8 799b064703 docs: Phase 3 design — interactive waveform + per-join crossfade/curves + destructive editor
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 16:51:29 +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 52417ea1ee feat: build_crossfade_merge_command — chained acrossfade / concat 2026-07-02 15:45:33 +02:00
EthanfelandClaude Opus 4.8 7573277a03 docs: audio merge (crossfade) — Phase 2 design + implementation plan
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:37:31 +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 4c5c4276c1 feat: core/waveform — peak reduction + ffmpeg region decode 2026-07-02 14:51:47 +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
Ethanfel f584e54a8c feat: audio_edit_filters helper + optional -af chain on build_audio_clip_command 2026-07-02 14:09:14 +02:00
EthanfelandClaude Opus 4.8 8f18c7a817 docs: audio tab Phase 1 implementation plan (extract/edit/classify)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:36:37 +02:00
EthanfelandClaude Opus 4.8 e14cebd081 docs: audio workspace tab design (2-phase: extract/edit/classify + dataset)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:33:19 +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