danielrosehill/claude-video-editor-plugin/normalize-audio

Claude Code and agent skill by danielrosehill/claude-video-editor-plugin

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Apply ffmpeg loudnorm (two-pass EBU R128) to a video or audio file, hitting the user's preferred LUFS / true-peak target (or one specified inline). Use when the user says "normalize this", "fix the levels", "make this -14 LUFS", "loudnorm this", "normalize for YouTube/podcast/broadcast". Pairs with audio-analysis (analyze recommends, this skill applies). Re-muxes video stream-copy when the input is video.

Install

npx vskill@latest install danielrosehill/claude-video-editor-plugin/normalize-audio

SKILL.md

Normalize Audio

Two-pass loudnorm to hit a precise integrated LUFS + true-peak target. Reads the user's default target from preferences.json if present; otherwise accepts an inline target.

This is the apply step that pairs with the read-only audio-analysis skill.

Procedure

1. Inputs
FieldDefault
Sourcerequired (video or audio)
Targetfrom preferences.json (loudness.target); else ask. Choices: youtube (-14/-1), spotify (-14/-1), apple-music (-16/-1), podcast (-16/-1), broadcast (-23/-2)
Outputsibling <basename>.normalized.<ext> (or project's working/ if inside an index project)

Resolve target → I (integrated LUFS), TP (true peak), LRA (default 11).

bash
DATA_DIR="${CLAUDE_USER_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/claude-plugins}/video-editing"
PREFS="$DATA_DIR/preferences.json"
if [ -f "$PREFS" ] && [ -z "$TARGET" ]; then
TARGET=$(jq -r '.loudness.target // empty' "$PREFS")
fi
case "$TARGET" in
youtube|spotify) I=-14; TP=-1; LRA=11 ;;
apple-music|podcast) I=-16; TP=-1; LRA=11 ;;
broadcast) I=-23; TP=-2; LRA=11 ;;
custom) ;; # caller sets I/TP/LRA
*) echo "Unknown target: $TARGET"; exit 1 ;;
esac
2. Pass 1 — measure
bash
PASS1=$(ffmpeg -hide_banner -nostats -i "$SRC" \
-af "loudnorm=I=$I:TP=$TP:LRA=$LRA:print_format=json" \
-f null - 2>&1 | sed -n '/^{/,/^}/p')
MI=$(echo "$PASS1" | jq -r '.input_i')
MTP=$(echo "$PASS1" | jq -r '.input_tp')
MLRA=$(echo "$PASS1"| jq -r '.input_lra')
MTHRESH=$(echo "$PASS1" | jq -r '.input_thresh')
OFFSET=$(echo "$PASS1" | jq -r '.target_offset')

Sanity-check: if any of these are "-inf" or null, the source has silence-only or non-finite measurements. Fall back to single-pass loudnorm and warn.

3. Pass 2 — apply with measured values
bash
LOUDNORM="loudnorm=I=$I:TP=$TP:LRA=$LRA:measured_I=$MI:measured_TP=$MTP:measured_LRA=$MLRA:measured_thresh=$MTHRESH:offset=$OFFSET:linear=true:print_format=summary"
If source is video

Stream-copy video, re-encode audio only:

bash
ffmpeg -hide_banner -y -i "$SRC" \
-map 0:v -map 0:a \
-c:v copy \
-af "$LOUDNORM" \
-c:a aac -b:a 192k \
-movflags +faststart \
"$OUT"

If the source has multiple audio tracks, normalize only a:0 and stream-copy the rest unless the user asked otherwise.

If source is audio-only

Pick the output codec from the input extension; default to wav for lossless intermediates, mp3/aac for delivery:

bash
ffmpeg -hide_banner -y -i "$SRC" -af "$LOUDNORM" "$OUT"
4. Verify

Re-run a quick ebur128 pass on the output and confirm integrated is within ±0.5 LU of target and true-peak is at or below the ceiling:

bash
ffmpeg -hide_banner -nostats -i "$OUT" -af 'ebur128=peak=true:framelog=quiet' -f null - 2>&1 | tail -25
5. Report

Print a one-table summary:

Source : path/to/in.mp4
Target : YouTube (-14 LUFS / -1 dBTP)
Before : I=-19.2 LUFS, TP=-2.1 dBTP, LRA=8.3 LU
After : I=-14.0 LUFS, TP=-1.0 dBTP, LRA=7.9 LU
Output : path/to/in.normalized.mp4

Notes

  • linear=true keeps dynamics intact when the source already fits within the target LRA. Drop it (or omit) if you want loudnorm to compress to fit.
  • For batch normalization (folder), iterate this same two-pass over each file. Don't try to share Pass-1 measurements across files — each clip is measured independently.
  • This skill never overwrites the source. Output goes to a sibling file or the project's working/ directory.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
6
7-day trend score
10

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/danielrosehill/claude-video-editor-plugin/normalize-audio/badge)](https://verified-skill.com/skills/danielrosehill/claude-video-editor-plugin/normalize-audio)

Something wrong with this skill or its page? Tell us.