원클릭으로
daw-master-ffmpeg-audio
FFmpeg audio filter wrapper — codec work, complex filtergraphs, stream operations
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
FFmpeg audio filter wrapper — codec work, complex filtergraphs, stream operations
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when working with the Sleepy Circuits Hypno 2 video synthesizer/resampler — 2-channel video mixer/looper, shader engine, MIDI CC mapping, CV/modulation, sampler. Firmware v0.0.163+.
Hardware instrument skills — reference guides for each device in the music studio setup.
GLSL fragment shader techniques adapted for the Hypno 2 video synthesizer — single-pass generative visuals and video effects optimized for Raspberry Pi 5, 5-uniform limit, CC-mapped parameters
Korg KAOSS DJ — USB DJ controller with X-Y touchpad, Serato DJ Intro integration, KAOSS effects, EQ, crossfader, and MIDI on Linux
Korg KAOSSILATOR dynamic phrase synthesizer (2007 model) — X-Y touchpad, 100 programs, gate arpeggiator, phrase loop recording, USB MIDI on Linux
Use when working with the Korg kaossilator 2S dynamic phrase synthesizer — X-Y touchpad, 150 programs, 50 arp patterns, loop recording, audio player, master recorder, microSD storage, and USB MIDI on Linux.
| name | daw-master:ffmpeg-audio |
| description | FFmpeg audio filter wrapper — codec work, complex filtergraphs, stream operations |
| version | 0.1.0 |
| author | Hermes Agent |
| license | MIT |
| metadata | {"hermes":{"tags":["audio","ffmpeg","filters","codec","stream","multi-input"],"related_skills":["daw-master:sox-engine","daw-master:dawdreamer","daw-master:rubber-band"]}} |
Wraps FFmpeg's audio filters (-af) and multi-input mixing (-filter_complex).
FFmpeg complements SoX by offering:
loudnorm)# Debian/Ubuntu
sudo apt install ffmpeg
# macOS
brew install ffmpeg
# Fedora
sudo dnf install ffmpeg
# Arch
sudo pacman -S ffmpeg
# Verify
ffmpeg -version | head -1
ffprobe -version | head -1
ffmpeg -af "...filter1,filter2,..." call-filter_complex when neededformat paramanalyze() calls go to ffprobe (not ffmpeg)from daw_master.ffmpeg_audio import transform, mix, analyze, probe, ebu_r128_analysis
# Transform with filter chain
transform(
input="input.wav",
pipeline=[
{"op": "volume", "gain": 0.8}, # -80% volume
{"op": "loudnorm", "i": -24, "lra": 11}, # EBU R128
{"op": "fade", "type": "out", "duration": 2.0},
],
output="output.m4a", # format inferred (AAC in MP4)
codec="aac" # explicit codec
)
# Mix multiple files (multi-input filtergraph)
mix(
tracks=[
{"path": "vocals.wav", "gain": 1.0, "delay": 0.0},
{"path": "beats.wav", "gain": 0.7, "delay": 0.05}, # 50ms delay
],
output="mix.wav",
normalize_final=True
)
# Analyze
info = analyze("sample.mp3")
# {'duration': 45.2, 'sample_rate': 44100, 'channels': 2, 'bit_rate': 128000, ...}
volume {gain}
gain: linear multiplier (0.5 = -6dB) or dB string ("3dB", "-6dB")volume=0.8 or volume=3dBloudnorm {i=-24} {lra=11} {tp=-1}
i (RMS/INT): target integrated loudness, e.g. -24 (default)lra: target loudness range, e.g. 11tp: true peak ceiling, e.g. -1 or -2loudnorm=I=-24:LRA=11:TP=-1dynaudnorm
p=0.95:g=10 etc.dynaudnorm=p=0.95acompressor / acompress
threshold, ratio, attack, release, makeup (dB), kneeacompressor=threshold=-20dB:ratio=4:attack=5:release=50:makeup=6dB:knee=2Examples:
{"op": "volume", "gain": 0.5} # -6 dB
{"op": "volume", "gain": "6dB"} # +6 dB
{"op": "loudnorm", "i": -23, "lra": 10} # streaming standard
{"op": "dynaudnorm"} # adaptive
{"op": "acompressor", "threshold": "-20dB", "ratio": 4, "attack": 5, "release": 50}
atrim start={s} end={s} duration={s}
start (seconds), end (seconds), duration (seconds)atrim=start=5:end=30areverse
apad pad_duration={s}
pad_duration (seconds)adelay delays="ms|ms|..."
delays as pipe-separated ms values: "1000|500" for stereoadelay=1000|500Examples:
{"op": "atrim", "start": 10.0, "end": 45.0}
{"op": "areverse"}
{"op": "apad", "pad_duration": 2.0}
{"op": "adelay", "delays": "500|500"} # 0.5s stereo delay
channelmap channels=0,1,...
channels — list of source channel indicespan (stereo or more)
FL/FR/FC etc strings: "FC" for center monopan=FL|c0=0.5|c1=0.5 — mono downmixpan=mono downmixchannelsplit
join (multi-input)
-filter_complex "[0:a][1:a]join=inputs=2[a]"Examples:
{"op": "channelmap", "channels": [0, 1]} # reorder
{"op": "pan", "mode": "stereo", "left": 0.7, "right": 0.3}
lowpass cutoff={freq}
cutoff: Hz (e.g., 2000). FFmpeg: lowpass=f=2000highpass cutoff={freq}
cutoff: Hz (e.g., 80 to remove rumble)bandpass freq={center} width={Q|Hz}
freq center Hz, width (Q factor or Hz bandwidth)equalizer (aka equalizer or bass/shelf family)
freq — frequency to affectwidth_type — "hz" or "q" or "o"width — bandwidthgain — dB adjustmentequalizer=f=1000:width_type=o:width=2:g=3bass {gain}
bass=g=6lowshelvetreble {gain}
treble=g=-3highshelveExamples:
{"op": "lowpass", "cutoff": 8000}
{"op": "highpass", "cutoff": 80}
{"op": "equalizer", "freq": 1000, "width_type": "q", "width": 1.0, "gain": 3}
{"op": "bass", "gain": 6}
{"op": "treble", "gain": -2}
compand (same name as SoX but different syntax)
attacks, decays, points (knee points), soft-knee, gaincompand=attacks=0.01:decays=0.1:points=-80/-80|-20/-3|0/-3compand but different parameterization.acompressor (preferred over compand for music)
threshold, ratio, attack, release, makeup, kneesidechaincompress
threshold, ratio, attack, release, makeup, kneeaecho
delays="ms|ms|...", decays="0.9|0.9", gain_in=0.6, gain_out=0.6aecho=0.05:0.1:0.9:0.9 (0.05s delay, 0.1 decay, 0.9 gains)areverb (simple) / freeverb (better)
freeverb: params scale=0.5:wet=0.3:dry=0.7aconvolve) or VST via avfilter?atempo tempo={factor}
tempo: float (0.5 = half, 2.0 = double)atempo=0.5,atempo=0.5 = quarter speedasetrate + atempo
Examples:
{"op": "acompressor", "threshold": "-20dB", "ratio": 4, "attack": 5, "release": 50}
{"op": "compand", "attacks": "0.01", "decays": "0.1", "points": "-80/-80|-20/-3|0/-3"}
{"op": "aecho", "delays": "500|1000", "decays": "0.8|0.6", "gain_in": 0.6, "gain_out": 0.6}
{"op": "freeverb", "wet": 0.4, "dry": 0.6}
{"op": "atempo", "tempo": 0.88} # slow down 12%
These require -filter_complex and are handled specially by transform() when detected.
amix inputs=2 [base_params]
inputs (count), duration (longest or shortest), dropout_transitionamix=inputs=2:duration=longest:dropout_transition=2amerge inputs=2
sidechaincompress — already covered but needs two inputs.
join — concatenate streams sample-accurately (like sox --combine concatenate).
Each step dict:
{"op": "operation_name", "param1": value1, "param2": value2, ...}
FFmpeg-specific tuning:
codec: override output codec (e.g. "aac", "mp3", "flac", "pcm_s16le")format: container format ("mp4", "wav", "ogg") — inferred from output.ext usuallyextra_output_args: list of extra ffmpeg CLI flags for output stageextra_global_args: list of global flags (e.g., ["-y"] to overwrite)Examples:
pipeline = [
{"op": "volume", "gain": "-3dB"}, # attenuate
{"op": "highpass", "cutoff": 80}, # remove sub-bass rumble
{"op": "acompressor", "threshold": "-20dB", "ratio": 3, "attack": 3, "release": 50},
{"op": "loudnorm", "i": -16, "lra": 5}, # podcast loudness
{"op": "fade", "type": "out", "duration": 1.0},
]
Translates to:
ffmpeg -i input.wav -af "filter1=params,filter2=params,..." -c:a <codec> output
Detected when pipeline contains overlay or when mix() is called.
Uses -filter_complex:
ffmpeg -i a.wav -i b.wav -filter_complex "[0:a][1:a]amix=inputs=2:duration=longest[out]" -map "[out]" output
The transform() function will auto-detect and switch to subprocess with custom
filter_complex string construction.
from daw_master.ffmpeg_audio import transform
transform(
input="podcast.wav",
pipeline=[
{"op": "highpass", "cutoff": 80}, # remove rumble
{"op": "loudnorm", "i": -19, "lra": 5}, # podcast standard
{"op": "fade", "type": "out", "duration": 0.5},
],
output="podcast_normalized.m4a",
codec="aac"
)
# Command: ffmpeg -i podcast.wav -af "highpass=f=80,loudnorm=I=-19:LRA=5,fade=t=out:st=0:d=0.5" -c:a aac output.m4a
transform(
input="long_recording.wav",
pipeline=[
{"op": "atrim", "start": 30.0, "end": 90.0}, # keep 1 min
{"op": "volume", "gain": "2dB"}, # +2 dB
{"op": "aresample", "sample_rate": 22050}, # downsample
],
output="excerpt_22k.mp3",
codec="mp3",
bitrate="128k"
)
from daw_master.ffmpeg_audio import mix
mix(
tracks=[
{"path": "vocals.wav", "gain": 1.0, "pan": "FC"}, # center
{"path": "drums.wav", "gain": 0.8, "pan": "FL+FR"}, # stereo spread
{"path": "bass.wav", "gain": 1.2, "pan": "FC"}, # center, louder
],
output="full_mix.wav",
normalize_final=True
)
# Uses: -filter_complex "[0:a]volume=1.0,pan=FC[a0];[1:a]volume=0.8,pan=FL+FR[a1];... [a0][a1][a2]amix=inputs=3"
transform(
input=None, # no input — generate
pipeline=[
{"op": "sine", "freq": 440, "duration": 5.0, "volume": 0.5},
],
output="A4_tone.wav",
codec="pcm_s16le"
)
# FFmpeg: ffmpeg -f lavfi -i "sine=frequency=440:duration=5" -c:a pcm_s16le out.wav
info = analyze("sample.mp3")
# {
# 'format': 'mp3', 'duration': 185.3, 'size': 2945000,
# 'bit_rate': '128k', 'sample_rate': 44100, 'channels': 2,
# 'codec': 'mp3', 'tags': {'title': '...', 'artist': '...'}
# }
loudness = ebu_r128_analysis("track.wav", target=-23.0)
# {
# 'success': True,
# 'file': '/abs/path/track.wav',
# 'target': -23.0,
# 'integrated_loudness': -18.7, # LUFS
# 'lra': 8.2, # Loudness Range in LU
# 'lra_low': -24.5, # LUFS lower bound
# 'lra_high': -12.3, # LUFS upper bound
# 'threshold': -41.2, # LUFS integrated threshold
# 'stderr': None # only on error
# }
Measures loudness per EBU R128 standard using FFmpeg's ebur128 filter.
Complements the loudnorm transform (which normalizes) by providing analysis.
# 1. sox-engine: fast trim + normalize (simple)
sox.transform("raw.wav", [{"op": "trim", "start": 5, "length": 60}, {"op": "normalize"}], "trimmed.wav")
# 2. ffmpeg-audio: codec conversion + loudness + compression
ffmpeg.transform("trimmed.wav", [
{"op": "loudnorm", "i": -16, "lra": 6},
{"op": "acompressor", "threshold": "-22dB", "ratio": 3},
], "final.m4a", codec="aac")
# 3. dawdreamer: VST color
dawdreamer.transform("final.m4a", [{"op": "load_vst", "path": "tone_vst.vst3"}, ...], "mastered.wav")
Filter syntax cheat sheet: Every op generates key=value pairs for -af.
true/false → 1/0[0,1] → "0|1" (pipe-separated for FFmpeg list params)filter1=...,filter2=...Two-pass loudnorm: For best quality, run loudnorm in two passes (measure then apply). This skill uses single-pass for simplicity. Advanced use: call analyze() → compute loudnorm params → call transform() with dual_pass=True.
Sample-accurate trimming: atrim uses float seconds (e.g., start=12.54321). Much more precise than sox trim which also uses float but FFmpeg can do frame-accurate if you specify in frames too.
Overlay operation: Unlike SoX's -m summing, FFmpeg's amix can optionally delay one track by duration or shortest. Use for echo/dub style delays.
Codec selection: If you don't specify codec, FFmpeg chooses based on container (file extension). To force raw PCM: codec='pcm_s16le' (WAV), codec='flac' for lossless, codec='aac' for AAC.
Quality controls: Pass extra_output_args=['-q:a', '2'] for variable-bitrate MP3/AAC quality (0=best, 9=worst).
Use skill daw-master:ffmpeg-audio transform input="in.wav" pipeline=[...] output="out.m4a"
Or Python:
from daw_master.ffmpeg_audio import transform
result = transform("in.wav", [{"op": "volume", "gain": "3dB"}], "out.wav")