Purpose
Insert deliberate audio dropouts ("silence beats") at precise timestamps without changing the total duration or video frames. Each beat mutes the audio from at to at + dur seconds. This is the mechanical implementation of the "silence beat" device described in CREATOR_GRAMMAR.md §6:
A deliberate 0.25–0.6s audio dropout used as a tension beat or act break — placed before a reveal or between acts.
If the source is a video file, the video stream passes through untouched; only the audio is modified. If the source is an audio-only file, the output is an audio-only file.
Inputs
--source(required) — path to the source audio or video file.--beats(optional) — a JSON array string of beat specs:[{"at": <seconds>, "dur": <seconds>}, ...]. Either--beatsor at least one--beatmust be provided.--beat(optional, repeatable) — a single beat asat,dur(comma-separated seconds, e.g.1.0,0.5). Can be repeated for multiple beats.--output(required) — output file path. Extension determines container format (.mp4for video,.mp3/.aac/.m4afor audio).
At least one beat must be provided via --beats or --beat.
Workflow
- Verify
ffmpeg/ffprobeare on PATH and the source file exists. - Parse all beat specs from
--beats(JSON) and/or--beat(repeatable) arguments. - Validate each beat:
at ≥ 0,dur > 0,at + dur ≤ source_duration(warn if a beat extends past end). - Build an ffmpeg
volumefilter expression that zeros audio within each beat window:volume=enable='between(t,AT,AT+DUR)':volume=0Multiple beats are composed with+in the enable expression. - If source is video: pass
[0:v]through with-c:v copy(no re-encode); apply volume filter to[0:a]. - If source is audio-only: apply volume filter to
[0:a]and re-encode as AAC. - Write output file and
manifest.jsonto the output file's parent directory.
Run:
python3 skills/atoms/audio-editing/insert-silence-beat/scripts/insert_silence.py \
--source /path/to/source.mp4 \
--beats '[{"at": 2.5, "dur": 0.4}, {"at": 8.1, "dur": 0.3}]' \
--output /path/to/output.mp4
Or using repeatable --beat flags:
python3 skills/atoms/audio-editing/insert-silence-beat/scripts/insert_silence.py \
--source /path/to/source.mp4 \
--beat 2.5,0.4 \
--beat 8.1,0.3 \
--output /path/to/output.mp4
Output
- Output file at the specified path with silence beats applied.
manifest.jsonin the same directory as the output, containing:skill_name,run_id,source,beats_applied(list of{at, dur}dicts),source_duration_seconds,output_file,status,warnings,errors.
Note: video duration and frame content are unchanged. Only the audio within the specified windows is zeroed.
Quality Checks
- Output file exists and is non-zero size.
ffprobereports the same duration as the source (±0.1s).- For video sources:
ffprobereports the same video codec and resolution as the source. - Audio within each beat window is silent or near-silent (RMS < −60 dBFS).
- Audio outside beat windows is unchanged (no clipping or distortion artifacts).
manifest.jsonexists withstatus: "pass"and all beats listed underbeats_applied.
Failure Modes
- Source not found — script exits with a clear error before processing.
- No beats provided — script exits with a usage error.
- Beat extends past source duration — the beat is clamped to the source end and a warning is written to
manifest.json. - Beat with
dur ≤ 0— that beat is skipped and recorded inmanifest.jsonerrors. ffmpegnot installed — install viabrew install ffmpeg.- Source has no audio stream — script exits with an error; there is nothing to silence.
- Overlapping beats — overlapping windows merge correctly in the enable expression (the
between()addition is OR-semantics); no error is raised, but a warning is added.