بنقرة واحدة
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 المهني
| 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")
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.