agentleFS
timelapsetechtimelapsetech/mediaskills/.agents/skills/audio/SKILL.md

audio

Skill1 starsChanged 3 months agoMITView on GitHub

Extract, convert, trim, concatenate, normalize, fade, resample, and silence-detect audio using ffmpeg. Use when you need to modify audio tracks, change format or sample rate, edit timeline segments, or prepare audio for muxing back onto video.

8 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. 0 are common, 1 is distinctive, and 7 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If your tools showed a filesystem path when loading this SKILL.md, strip SKILL.md and use that folder.

    line 43
  2. Very specific:

    If you already ran another mediaskills script (for example .../audio/scripts/extract.py), this skill is a sibling of that folder: same …

    line 44
  3. Very specific:

    Prefer absolute paths for --input / --output when cwd is uncertain.

    line 67
  4. Distinctive:

    Before running any script, treat these two failures differently:

    line 72
  5. Very specific:

    Only escalate sandbox permissions if the error is explicitly a permission denial (e.g.

    line 75
  6. Very specific:

    Run inspect on the source to confirm duration and audio codec.

    line 81
  7. Very specific:

    Use output_path from JSON for downstream transcription or editing.

    line 97
  8. Very specific:

    Read data.silence_starts / data.silence_ends (seconds) to split on pauses or detect dead air.

    line 120

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Audio

Audio processing with ffmpeg. Use this skill when you need to change audio — not just read metadata (use inspect for that).

When to use

  • This skill — extract audio from video, convert formats, trim/concat timeline edits, loudness normalize, fade, resample, find silence.
  • inspect — read-only metadata before editing (duration, codecs, sample rate). Always probe first when unsure about input format.
  • video-transformation — mux normalized or extracted audio back onto video (replace_audio.py and similar ops).
  • Raw ffmpeg — fine for one-off filter chains, but these scripts return consistent JSON and auto-generate output paths.

Gotchas

  • Trim with -c copy — trim.py stream-copies for speed. Works for WAV and many containers; can fail or produce glitches on MP3/AAC with frame boundaries. Re-encode with ffmpeg manually if copy fails.
  • Concat requires matching codecs — concat.py uses the concat demuxer with -c copy. All inputs must share codec, sample rate, and channel layout. Convert/resample first if needed.
  • Normalize outputs WAV — loudnorm writes PCM WAV. Mux back to video with video-transformation replace_audio.py, or convert with convert.py.
  • Fade is fixed 1 s in — fade.py applies afade=t=in:st=0:d=1 only. Custom fade curves need raw ffmpeg.
  • Silence threshold is fixed — silence_detect.py uses noise=-30dB:d=0.5. Pure tones (e.g. test fixtures) may report no silence; real speech/podcast material works best.
  • Extract vs video extract — extract.py strips video (-vn) to WAV. For video-specific workflows, check video-transformation extract_audio.py too.

Running scripts

This skill's scripts live in scripts/ alongside this file. Before running any script, resolve its absolute path from this skill's own directory — do not assume the shell cwd is the skill folder, the repo root, or the workspace. Stay in the workspace (so media paths resolve) and pass the absolute script path to uv run:

uv run <skill_directory>/scripts/normalize.py --input "<path-to-media>"

<skill_directory> is a placeholder. Never pass those angle brackets to the shell — the command will fail. Replace it with a real absolute directory before invoking uv run.

How to get that directory (do this yourself; do not ask the user first; do not skip the skill):

  1. If your tools showed a filesystem path when loading this SKILL.md, strip SKILL.md and use that folder.
  2. If you already ran another mediaskills script (for example .../audio/scripts/extract.py), this skill is a sibling of that folder: same parent, directory name audio.
  3. Otherwise search standard install locations and confirm the script exists:
NAME=audio
for d in \
  "$HOME/.agents/skills/$NAME" \
  "$HOME/.cursor/skills/$NAME" \
  "$HOME/.codex/skills/$NAME" \
  "$HOME/.claude/skills/$NAME" \
  "$PWD/.agents/skills/$NAME" \
  "$PWD/.cursor/skills/$NAME" \
  "$PWD/skills/$NAME"
do
  if [ -f "$d/SKILL.md" ] && [ -e "$d/scripts/normalize.py" ]; then
    SKILL_DIR=$(cd "$d" && pwd)
    break
  fi
done
[ -n "$SKILL_DIR" ] || { echo "mediaskills: $NAME not found" >&2; exit 1; }
uv run "$SKILL_DIR/scripts/normalize.py" --input "<path-to-media>"

Prefer absolute paths for --input / --output when cwd is uncertain.

Missing binaries vs permissions

Before running any script, treat these two failures differently:

  • If a required binary (uv, ffmpeg, ffprobe) reports No such file or directory or command not found: this is a missing or unreachable binary, not a permissions issue. Escalating sandbox permissions will not fix it. Run command -v uv, command -v ffmpeg, and command -v ffprobe to see whether they resolve at all. If not, install or re-link them (install-media-tools doctor/install) rather than retrying with wider permissions.
  • Only escalate sandbox permissions if the error is explicitly a permission denial (e.g. Operation not permitted, Permission denied).

Recipes

Normalize then put audio back on video

  1. Run inspect on the source to confirm duration and audio codec.
  2. Normalize:
uv run <skill_directory>/scripts/normalize.py --input clip.mp4
  1. Mux the normalized WAV onto the original video with video-transformation replace_audio.py.
  2. Optional: specify bitrate/codec on replace for a smaller proxy encode.

Extract clean audio only

uv run <skill_directory>/scripts/extract.py --input clip.mp4 --output dialogue.wav

Use output_path from JSON for downstream transcription or editing.

Convert for 48 kHz AAC for delivery

uv run <skill_directory>/scripts/resample.py --input master.wav --sample-rate 48000 --output master_48k.wav
uv run <skill_directory>/scripts/convert.py --input master_48k.wav --format aac --output master.m4a

Trim a segment and join clips

uv run <skill_directory>/scripts/trim.py --input intro.wav --start 0 --end 30 --output intro_trim.wav
uv run <skill_directory>/scripts/trim.py --input outro.wav --start 5 --end 60 --output outro_trim.wav
uv run <skill_directory>/scripts/concat.py --paths intro_trim.wav outro_trim.wav --output final.wav

Find silence for auto-editing

uv run <skill_directory>/scripts/silence_detect.py --input podcast.wav

Read data.silence_starts / data.silence_ends (seconds) to split on pauses or detect dead air.

Troubleshooting

Error / symptomLikely causeAction
ffmpeg not foundBinary missingRun install-media-tools doctor/install
Concat fails / corrupt outputMismatched codecs or sample ratesResample/convert inputs to identical format first
Trim produces empty or tiny fileStart ≥ end or beyond durationCheck duration with inspect; verify --start / --end
-c copy trim failsCodec doesn't support arbitrary cut pointsRe-encode: ffmpeg -ss START -to END -i IN -c:a pcm_s16le OUT.wav
Normalize sounds wrongAlready heavily compressed sourceInspect peaks; consider manual loudnorm params via raw ffmpeg
No silence regions detectedThreshold too strict or continuous toneExpected on sine test tones; try real speech audio

Available scripts

ScriptPurposeKey flags
scripts/probe.pyFull ffprobe JSON for an audio file--input
scripts/extract.pyStrip video, write WAV--input, --output
scripts/convert.pyChange format (mp3, aac, flac, …)--input, --format, --output
scripts/trim.pyCut a time range--input, --start, --end, --output
scripts/concat.pyJoin multiple files--paths, --output
scripts/normalize.pyEBU-style loudness normalize--input, --output
scripts/fade.py1-second fade-in--input, --output
scripts/resample.pyChange sample rate--input, --sample-rate, --output
scripts/silence_detect.pyList silence regions--input

Outputs default to the workspace root .mediaskills/generated/ unless --output is set. Override with $MEDIASKILLS_DATA_DIR/generated/ when set.

Acceptance checks (agent must pass before delivery)

  1. Contract: exit 0, ok: true, every output_paths entry exists and is non-empty.
  2. Probe: inspect.describe on each audio output — duration, sample rate, and format match the request.
  3. Spot-check: for trim/concat, duration ≈ sum of requested ranges; for normalize, listen/spot peaks are not clipped silence.
  4. On failure: fix or escalate; do not present empty or truncated audio as complete.

Do not use for

  • Probing media metadata (use inspect)
  • Video transforms (use video-transformation)
  • Speech-to-text (use speech-captions)

Related skills

  • install-media-tools — install ffmpeg/ffprobe
  • inspect — read-only metadata before processing
  • video-transformation — mux/replace audio on video

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.