From video-editing
Extract audio from a video (or analyze a standalone audio file) and report loudness — integrated LUFS, true peak (dBTP), loudness range — against a target like YouTube (-14 LUFS) or broadcast (-23 LUFS). Use when the user says "check loudness", "is this normalized", "extract the audio", "audio analysis", or "what LUFS is this". Read-only on the source — does not normalize.
npx claudepluginhub danielrosehill/claude-code-plugins --plugin video-editingThis skill is limited to using the following tools:
Pull the audio out of a video (or take a standalone audio file) and run an EBU R128 loudness pass. Output is a short markdown report with LUFS / dBTP / LRA and a recommendation against a chosen target.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Pull the audio out of a video (or take a standalone audio file) and run an EBU R128 loudness pass. Output is a short markdown report with LUFS / dBTP / LRA and a recommendation against a chosen target.
This skill does not normalize. Apply normalization separately (with transcode or a future normalize-audio skill) once you've decided on a target.
| Field | Default |
|---|---|
| Source | required (video or audio) |
| Mode | extract / analyze / both (default both) |
| Target | youtube (-14 LUFS / -1 dBTP) / broadcast (-23 / -2) / podcast (-16 / -1) / streaming-spotify (-14 / -1) |
| Output dir | sibling audio/ (or project's assets/ if inside an index project) |
If the source is a video, pull the audio. Prefer stream-copy when the codec is sane (aac/opus/flac/mp3); otherwise re-encode to wav for analysis.
CODEC=$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$SRC")
case "$CODEC" in
aac|mp3|opus|flac) EXT="$CODEC"; ARGS="-vn -acodec copy" ;;
*) EXT="wav"; ARGS="-vn -ac 2 -ar 48000 -c:a pcm_s24le" ;;
esac
mkdir -p "$OUT_DIR"
EXTRACTED="$OUT_DIR/$(basename "${SRC%.*}").$EXT"
ffmpeg -hide_banner -y -i "$SRC" $ARGS "$EXTRACTED"
ffmpeg -hide_banner -nostats -i "$EXTRACTED" -af 'ebur128=peak=true:framelog=quiet' -f null - 2>&1 | tail -25
Parse the summary block at the end:
[Parsed_ebur128_0 @ ...] Summary:
Integrated loudness:
I: -18.4 LUFS
Threshold: -28.5 LUFS
Loudness range:
LRA: 8.1 LU
Threshold: -38.5 LUFS
LRA low: -22.2 LUFS
LRA high: -14.1 LUFS
True peak:
Peak: -1.3 dBFS
Pull I (integrated), LRA, and Peak with grep/awk.
Also probe stream metadata:
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,sample_rate,channels,bits_per_sample -of default=nw=1 "$SRC"
| Target | Integrated | True Peak |
|---|---|---|
| YouTube | -14 LUFS | -1 dBTP |
| Spotify | -14 LUFS | -1 dBTP |
| Apple Music | -16 LUFS | -1 dBTP |
| Podcast | -16 LUFS | -1 dBTP |
| Broadcast (EBU R128) | -23 LUFS | -2 dBTP |
Compute deltas (measured_I - target_I).
<OUT_DIR>/<basename>.loudness.md:
# Loudness report — <basename>
- Source: `<absolute path>`
- Stream: aac, 48 kHz, 2 ch
- Target: YouTube (-14 LUFS / -1 dBTP)
| Metric | Measured | Target | Delta |
|--------|---------:|-------:|------:|
| Integrated | -18.4 LUFS | -14 LUFS | **-4.4 LU** (too quiet) |
| True peak | -1.3 dBTP | -1 dBTP | -0.3 dB (ok) |
| LRA | 8.1 LU | — | — |
**Recommendation:** raise integrated by ~4.4 LU. Use ffmpeg `loudnorm` (two-pass) or apply gain when re-encoding.
Show the table inline so the user doesn't have to open the file. Offer:
transcode with a loudnorm step.