Skip to content

Snap clip boundaries into detected silence to avoid mid-word cuts#132

Merged
alexkroman merged 1 commit into
mainfrom
claude/elegant-lamport-kebbrh
Jun 12, 2026
Merged

Snap clip boundaries into detected silence to avoid mid-word cuts#132
alexkroman merged 1 commit into
mainfrom
claude/elegant-lamport-kebbrh

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Summary

Add automatic silence detection and boundary snapping to the clip command so that clip cuts land in pauses rather than mid-word. When enabled (the default), ffmpeg's silencedetect filter identifies silence intervals in the source media, and clip boundaries are moved into adjacent silence up to a configurable reach distance, keeping a small amount of silence next to the speech.

Key Changes

  • Silence detection & parsing (clip_select.py):

    • parse_silences() extracts silence intervals from ffmpeg silencedetect filter output
    • Handles edge cases: trailing silence (runs to end-of-file), negative starts (decoder priming), unpaired edges
    • Regex-based parsing of silence_start and silence_end log lines
  • Boundary snapping (clip_select.py):

    • snap_to_silences() moves clip boundaries into adjacent silence intervals
    • _snap_start() and _snap_end() implement directional snapping logic
    • Configurable reach (SNAP_REACH = 1.5s) and lead (SNAP_LEAD = 0.25s) constants
    • Respects existing padding, re-merges overlapping segments after snapping
    • No-op when snapping is disabled or no silences detected (graceful degradation)
  • Integration (clip_exec.py):

    • _detect_silences() runs a dedicated ffmpeg pass with silencedetect filter
    • Best-effort: detection failures return empty silence list, cut proceeds at selected times
    • New snap boolean option in ClipOptions (default: True)
    • Snapping happens after padding/merging but before cutting
  • CLI (commands/clip.py):

    • New --snap/--no-snap flag (default: snap enabled)
    • Updated help text to document the feature
  • Tests:

    • Comprehensive test suite for parse_silences() covering normal cases, edge cases, and error handling
    • snap_to_silences() tests covering reach bounds, narrow silences, overlapping segments, trailing silence
    • Integration tests verifying snapping in the full run_clip() workflow
    • Tests for graceful failure when detection fails or snapping is disabled
    • Updated existing tests to account for the new silencedetect ffmpeg pass

Implementation Details

  • Silence detection uses -30dB threshold with 0.2s minimum duration (typical pause in speech)
  • Snapping is one-directional per boundary: starts move backward, ends move forward
  • A boundary already inside silence stays put (honors --padding exactly)
  • Snapping reach is limited to prevent moving across multiple silence gaps
  • Segments that snap into the same silence are re-merged to avoid duplicating pauses
  • The silencedetect pass runs on stderr (info level), separate from the cutting pass

https://claude.ai/code/session_0196aTXN8jmNQwuwBDLTfmqU

assembly clip now runs one ffmpeg silencedetect pass over the source and
moves any clip boundary that lands mid-speech into the adjacent silence:
a start backs into the previous silence (keeping the word it was chopping),
an end runs forward into the next one, each settling SNAP_LEAD (0.25s)
from the speech edge. Boundaries already in silence stay exactly where
selected (so --padding is honored), boundaries with no silence within
SNAP_REACH (1.5s) stay put, and a failed detection falls back to the
selected times rather than failing the cut. --no-snap restores exact-time
cuts.

Also add the Steve Jobs commencement-speech clip example to the README.

https://claude.ai/code/session_0196aTXN8jmNQwuwBDLTfmqU
@alexkroman alexkroman enabled auto-merge June 12, 2026 21:42
@alexkroman alexkroman added this pull request to the merge queue Jun 12, 2026
Merged via the queue into main with commit 9bf2374 Jun 12, 2026
16 checks passed
@alexkroman alexkroman deleted the claude/elegant-lamport-kebbrh branch June 12, 2026 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants