32blogby Studio Mitsu

fqmpeg 音声処理: 26動詞でレベル・EQ・無音まで

fqmpegの26動詞 — 音声抽出・ラウドネス・EQ・コンプ・ピッチ・無音検出。実装読みで分かったデフォルトと落とし穴を全部まとめた。

by omitsu31 min read
目次

fqmpeg の C9 クラスタは音声エンジン — メディアファイルの音声トラックを触る26動詞をまとめている。基本5つ(抽出・除去・ミュート・ボリューム・フェード)、ラウドネス3つ(normalizeaudio-normalize-peakloudness-meter)、ダイナミクス3つ(audio-compressorlimiteraudio-gate)、EQ・周波数フィルタ6つ(3バンド audio-eq と単一バンド系4つ+audio-bandpass)、時間/ピッチ/同期4つ(audio-pitchaudio-speedaudio-reverseaudio-delay)、ノイズと無音5つ(audio-noise-reducedetect-silencetrim-silencesilence-insertcensor)。

この記事は fqmpeg 3.0.3src/commands/ を実読して、各動詞が叩いている FFmpeg フィルタ・デフォルト値・出力ファイル名・そして --help だけだと見えない落とし穴を全部洗い出したものだ(normalize は TP/LRA がハードコードされた EBU R128 loudnorm の1パス版、audio-pitchrubberband 依存なのでビルドによっては動かない、audio-delay負値はディレイではなく atrim で頭を削る ので出力が短くなる、censor は音声ビープであって映像モザイクではない、silence-insertapad+adelay 構成なので「指定位置で中割り挿入」ではなく「指定オフセットで音声全体を後ろにずらして末尾にパッドを足す」挙動)。

この記事で得られるもの

  • 26動詞をタスク別(基本/ラウドネス/ダイナミクス/EQ/時間/無音)に選び分ける早見表
  • 各動詞が実際に生成する FFmpeg コマンド(--dry-run で検証済み)
  • 全コマンドのデフォルト値・範囲・単位(dB / 倍率 / Hz / 半音)・出力ファイル名
  • 「ポッドキャスト整音」「ダイアログ清掃」「音楽ベッド準備」の実用レシピ3本

26動詞の全体像

クラスタはタスク別に6グループに分かれる。グループを決めてから動詞を選ぶ流れがラク。

グループ動詞用途
基本audio, strip-audio, mute, volume, audio-fadeMP3抽出・音声除去・範囲ミュート・ゲイン調整・フェード
ラウドネスnormalize, audio-normalize-peak, loudness-meterEBU R128 / ピーク正規化 / LUFS 測定
ダイナミクスaudio-compressor, limiter, audio-gateコンプ・リミッター・ゲート
EQ・フィルタaudio-eq, audio-bass-boost, audio-treble-boost, audio-bandpass, audio-highpass, audio-lowpass3バンドEQ・単一バンドブースト・パス/カットフィルタ
時間・ピッチ・同期audio-pitch, audio-speed, audio-reverse, audio-delayピッチシフト・テンポ変更・逆再生・A/V同期オフセット
ノイズと無音audio-noise-reduce, detect-silence, trim-silence, silence-insert, censorFFTデノイズ・無音検出/削除/挿入・ビープ

読み進む前に押さえておきたい5点:

  1. ほとんどの動詞は -c:v copy で映像をストリームコピーする。 入力が動画ファイルなら映像は再エンコードされない。例外は audio(MP3抽出)、loudness-meter / detect-silence(出力ファイルなし)の3つだけ。
  2. normalizeTP=-1.5 LRA=11 固定の1パス loudnorm。 公開オプションは積分ラウドネスのターゲット(--target、デフォルト -16 LUFS)だけ。2パス測定→適用が必要なら、まず loudness-meter で値を読んで生 FFmpeg に降りる。
  3. volume は倍率とdBの両方を受け付ける。 0.5 で半分、2.0 で倍、3dB-5dB も通る。utils.jsparseVolumeLevel がそれ以外を FFmpeg 実行前にはじく。負の dB(-5dB 等)はシェルで -- 区切りが必要 — 下の volume セクション参照。audio-pitch の負の半音(-3)と audio-delay の負のミリ秒(-200)も同じ。
  4. audio-delay は正負で挙動が違う。 正の値は adelay で音声を後ろにずらす。負の値は atrim+asetpts=PTS-STARTPTS音声の頭を切り落として早める ので、出力は入力よりその分だけ短くなる。
  5. audio-eq のミッド帯域は equalizer=f=1000:t=h:width=500:g=N でハードコード。 中心1kHz・半幅500Hzの固定設定なのでボーカル抜けを足すには良いが、正確な3バンドシェルビングEQではない。中域を精密に弄りたいなら生 FFmpeg の equalizer で自分の中心周波数を指定する。

基本

audio — MP3として音声抽出

映像を捨て、音声をMP3 VBR品質2(約190kbps)で再エンコード。

bash
$ npx fqmpeg audio input.mp4 --dry-run

  ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 input-audio.mp3

出力拡張子はソースに関係なく必ず .mp3 — fqmpeg は再エンコードする。AACトラックをロスレスでコピーしたい場合は生 FFmpeg で ffmpeg -i input.mp4 -vn -c:a copy input.m4a を使う。

strip-audio — 音声トラック除去

音声を捨て、映像はストリームコピー。高速、再エンコードなし。

bash
$ npx fqmpeg strip-audio input.mp4 --dry-run

  ffmpeg -i input.mp4 -an -c:v copy input-noaudio.mp4

stackconcat 前の B-roll 整理で重宝する — 音声トラックの不揃いがコンテナレベルで衝突するのを根本的に避けられる。

mute — 指定範囲をミュート

2つのタイムスタンプ間だけ音量0にして、それ以外はそのまま。映像はストリームコピー。

オプションデフォルト備考
-s, --start <秒>0ミュート開始
-e, --end <秒>必須ミュート終了
-o, --output <path><入力名>-muted.<ext>
bash
$ npx fqmpeg mute input.mp4 -s 10 -e 15 --dry-run

  ffmpeg -i input.mp4 -af volume=enable='between(t,10,15)':volume=0 -c:v copy input-muted.mp4

--end は必須(未指定だとエラー終了)。値は秒のみ — HH:MM:SS は受け付けない。

volume — 音量調整

全体に倍率またはdBゲインを適用。

  • ソース: src/commands/volume.js
  • フィルタ: volume=<level><level> は倍率 0.5, 2.0 か dB 3dB, -5dB
  • 検証: parseVolumeLevel<数値><数値>dB 以外をはじく
  • 出力: <入力名>-vol<整形後level>.<ext>(例: input-vol2.mp4, input-vol-5dB.mp4
bash
$ npx fqmpeg volume input.mp4 2.0 --dry-run

  ffmpeg -i input.mp4 -af volume=2.0 -c:v copy input-vol2.0.mp4

$ npx fqmpeg volume input.mp4 --dry-run -- -5dB

  ffmpeg -i input.mp4 -af volume=-5dB -c:v copy input-vol-5dB.mp4

負の dB は - で始まるので、fqmpeg が使っている CLI パーサ commander.js がオプションフラグと解釈する。素朴な volume input.mp4 -5dBunknown option '-5dB' で弾かれる。end-of-options 区切りとして -- を渡し、--dry-run 等の --* オプションは すべて -- より前に置く。その後の <level> positional はダッシュ付きの値を受け取れる。すでに大きめの音声に倍率 ~3.0 超(または ~+10dB 超)をかけるとクリップする — 後段で limiter を噛ますか、ヘッドルームを残す normalize を使う方が安全。

audio-fade — 音声のフェードイン/アウト

開始の afade=in か、終端付近の afade=out、もしくは両方を適用。映像はストリームコピー。

オプションデフォルト備考
--in <秒>0フェードイン時間(0 でフェードインなし)
--out <秒>0フェードアウト時間(--duration が必須)
--duration <秒>--out > 0 のとき必須音声の総尺。アウトフェード開始位置の計算に使う
bash
$ npx fqmpeg audio-fade input.mp4 --in 2 --out 3 --duration 60 --dry-run

  ffmpeg -i input.mp4 -af afade=t=in:st=0:d=2,afade=t=out:st=57:d=3 -c:v copy input-audiofade.mp4

duration が必要なのは構造的な制約 — FFmpeg の afade=t=out は「終端から逆算」ではなく「明示的な開始時刻」を要求するため。総尺が分からないときは先に npx fqmpeg duration input.mp4 で取る。

ラウドネス測定・正規化

normalize — 1パス EBU R128 loudnorm

loudnorm フィルタを1パスモードで適用し、積分ラウドネス(LUFS)を指定値にそろえる。真のピークとラウドネスレンジは安全側で固定。

  • ソース: src/commands/normalize.js
  • フィルタ: loudnorm=I=<target>:TP=-1.5:LRA=11
  • 範囲: --target-70-5(LUFS)、デフォルト -16
bash
$ npx fqmpeg normalize input.mp4 --target -14 --dry-run

  ffmpeg -i input.mp4 -af loudnorm=I=-14:TP=-1.5:LRA=11 -c:v copy input-normalized.mp4

よく使うターゲット: -23 LUFS(EBU 放送)、-16 LUFS(ポッドキャスト / 配信、デフォルト)、-14 LUFS(Spotify / YouTube)、-10 LUFS(大音量コマーシャル参考)。1パスの loudnorm は近似値 — 放送グレードの精度が必要なら 2パス loudnorm 解説 を参照。

audio-normalize-peak — ピーク値正規化

線形 loudnorm(true-peak only)でいちばん大きいサンプルを --peak dB に揃える。知覚モデルが走らないので loudnorm より速い。

  • ソース: src/commands/audio-normalize-peak.js
  • フィルタ: loudnorm=I=-24:TP=<peak>:LRA=7:linear=true
  • デフォルト: --peak 0(ピークが 0 dBFS に着地。インターサンプルピークのリスクあり)
bash
$ npx fqmpeg audio-normalize-peak input.mp4 --peak -1 --dry-run

  ffmpeg -i input.mp4 -af loudnorm=I=-24:TP=-1:LRA=7:linear=true -c:v copy input-peak-norm.mp4

--peak -1--peak -3 の方が安全 — ロスレスなら 0 dBFS でも問題ないが、MP3/AAC 再エンコード後にインターサンプル再構築でクリップすることがある。

loudness-meter — ラウドネス測定

読み取り専用。ebur128 を走らせて積分ラウドネス・トゥルーピーク・ラウドネスレンジを stderr に出力する。出力ファイルなし。

bash
$ npx fqmpeg loudness-meter input.mp4 --dry-run

  ffmpeg -i input.mp4 -af ebur128 -f null -

実行後、stderr の最後の Summary: ブロックを読む — I:, Threshold:, LRA:, LRA low:, LRA high:, True peak: が並んでいる。数値だけ欲しいなら 2>&1 | grep -E '(I|LRA|True peak):' でフィルタする。

ダイナミクス処理

audio-compressor — ダイナミックレンジ圧縮

小さい音と大きい音の差を acompressor で詰める。

オプションデフォルト備考
--threshold <dB>-20これより上の信号に圧縮を適用
--ratio <n>44 = 4:1, 2 = 2:1
--attack <ms>20圧縮の立ち上がりの速さ
--release <ms>250圧縮の戻りの速さ
bash
$ npx fqmpeg audio-compressor input.mp4 --threshold -18 --ratio 3 --dry-run

  ffmpeg -i input.mp4 -af acompressor=threshold=-18dB:ratio=3:attack=20:release=250 -c:v copy input-compressed-audio.mp4

出力は <入力名>-compressed-audio.<ext> — 映像圧縮の compress<入力名>-compressed.<ext> を吐くので、両方を同じファイルにチェーンしてもファイル名が衝突しないようサフィックスを変えてある。

limiter — ブリックウォール リミッター(alimiter

設定したシーリングを音声が超えないように張る。コンプより速いアタック/リリース。納品前の最終段で使う。

  • ソース: src/commands/limiter.js
  • フィルタ: alimiter=limit=<l>dB:attack=<a>:release=<r>
  • デフォルト: --limit -1 dB, --attack 5 ms, --release 50 ms
  • 出力: <入力名>-limited.<ext>
bash
$ npx fqmpeg limiter input.mp4 --limit -1 --dry-run

  ffmpeg -i input.mp4 -af alimiter=limit=-1dB:attack=5:release=50 -c:v copy input-limited.mp4

-1 dB が配信納品の標準シーリング(インターサンプルピーク用のヘッドルームを残す)。放送TVなら -2 dB、DVD/Blu-ray なら -0.3 まで攻められる。

audio-gate — ノイズゲート

しきい値以下の音声を強制的に無音化する — エアコン音などの暗ノイズが乗ったダイアログのクリーンアップ用。

  • ソース: src/commands/audio-gate.js
  • フィルタ: agate=threshold=<t>dB:attack=<a>:release=<r>
  • デフォルト: --threshold -30 dB, --attack 20 ms, --release 250 ms
  • 出力: <入力名>-gated.<ext>
bash
$ npx fqmpeg audio-gate input.mp4 --threshold -35 --dry-run

  ffmpeg -i input.mp4 -af agate=threshold=-35dB:attack=20:release=250 -c:v copy input-gated.mp4

しきい値はノイズフロアより数 dB 上に置く(loudness-meter か波形で先に確認)。高すぎると小声のダイアログが切れ、低すぎるとゲートが効かない。

EQ・周波数フィルタ

audio-eq — 3バンドイコライザ

ベース / ミッド / トレブルを一発で。内部で bassequalizer(ミッド)、treble をチェーンする。

  • ソース: src/commands/audio-eq.js

  • フィルタ組み立て(0以外のバンドだけ生成される):

    text
    bass=g=<bass>,
    treble=g=<treble>,
    equalizer=f=1000:t=h:width=500:g=<mid>
    
オプションデフォルト範囲
--bass <dB>0-2020
--mid <dB>0-2020(中心 1 kHz、半幅 500 Hz 固定)
--treble <dB>0-2020
bash
$ npx fqmpeg audio-eq input.mp4 --bass 3 --treble 2 --dry-run

  ffmpeg -i input.mp4 -af bass=g=3,treble=g=2 -c:v copy input-eq.mp4

3バンドとも0のときはエラー終了 — --bass/--mid/--treble のうち最低1つは非0が必須。

audio-bass-boost — 単一バンドの低域ブースト

bass=g=<gain>:f=<freq> で中心周波数を細かく指定できる。

bash
$ npx fqmpeg audio-bass-boost input.mp4 --gain 6 --freq 80 --dry-run

  ffmpeg -i input.mp4 -af bass=g=6:f=80 -c:v copy input-bass-boost.mp4

60〜120 Hz はキックドラムや男声の基音帯、200 Hz 以上に行くと中域に色が付き始める。

audio-treble-boost — 単一バンドの高域ブースト

treble=g=<gain>:f=<freq> のラッパー。

bash
$ npx fqmpeg audio-treble-boost input.mp4 --gain 4 --freq 5000 --dry-run

  ffmpeg -i input.mp4 -af treble=g=4:f=5000 -c:v copy input-treble-boost.mp4

3〜5 kHz でボーカルの抜けを足し、8〜12 kHz で「エア感」を付ける。16 kHz 以上は若い耳にだけ効く帯域。

audio-bandpass — バンドパスフィルタ

狭い帯域だけ通して外側を減衰させる。

  • ソース: src/commands/audio-bandpass.js
  • フィルタ: bandpass=f=<freq>:w=<width>
  • デフォルト: --freq 1000 Hz, --width 200 Hz
  • 出力: <入力名>-bandpass.<ext>
bash
$ npx fqmpeg audio-bandpass input.mp4 --freq 1500 --width 400 --dry-run

  ffmpeg -i input.mp4 -af bandpass=f=1500:w=400 -c:v copy input-bandpass.mp4

電話風・無線風(300〜3000 Hz 帯)の効果や、問題周波数をノッチで削る前の特定にどうぞ。

audio-highpass — ハイパス(低域カット)

カットオフ以下を全部削る。ランブル / 空調 / ハンドリングノイズの除去に。

bash
$ npx fqmpeg audio-highpass input.mp4 --freq 80 --dry-run

  ffmpeg -i input.mp4 -af highpass=f=80 -c:v copy input-highpass.mp4

80 Hz は男声を細らせずにランブルだけ取れる安全圏、120 Hz は攻め気味(男声の低音が落ちる)、200 Hz は「電話帯域」レベル。

audio-lowpass — ローパス(高域カット)

カットオフ以上を削る。耳に痛いシビランスやヒスを抑えるのに。

bash
$ npx fqmpeg audio-lowpass input.mp4 --freq 8000 --dry-run

  ffmpeg -i input.mp4 -af lowpass=f=8000 -c:v copy input-lowpass.mp4

デフォルトの 3000 Hz は強烈(こもった水中サウンドになる)。マイクが熱いときのヒス抑えは --freq 1000012000 が無難。

時間・ピッチ・同期

audio-pitch — 速度を変えずにピッチを動かす

Rubber Band ライブラリを使う(あなたの FFmpeg にコンパイルされている必要あり)。

  • ソース: src/commands/audio-pitch.js
  • フィルタ: rubberband=pitch=<factor> (factor = 2^(semitones/12))
  • 引数: <semitones> — 位置引数、正/負の数値(2, -3, -1.5
  • 出力: <入力名>-pitch+<n>.<ext> または <入力名>-pitch<n>.<ext>(符号がファイル名に入る)
bash
$ npx fqmpeg audio-pitch input.mp4 2 --dry-run

  ffmpeg -i input.mp4 -af rubberband=pitch=1.122462 -c:v copy input-pitch+2.mp4

$ npx fqmpeg audio-pitch input.mp4 --dry-run -- -3

  ffmpeg -i input.mp4 -af rubberband=pitch=0.840896 -c:v copy input-pitch-3.mp4

No such filter: 'rubberband' で落ちる場合は FFmpeg が --enable-librubberband 無しでビルドされている。BtbN や gyan.dev のスタティックビルドには入っている、Homebrew のデフォルトも入っている。差し替えできないなら 2半音シフトを asetrate=44100*1.122462,aresample=44100,atempo=1/1.122462 で代用できる(音質は劣るが組み込みフィルタだけで動く)。

audio-speed — ピッチを保ったまま再生速度を変える

atempo=<factor> のラッパー。素のフィルタは 1回で 0.52.0 を受け付ける — それ以上は atempo=2.0,atempo=2.0 で連鎖できるが fqmpeg は自動連鎖しない。0.52.0 の範囲で使う。

bash
$ npx fqmpeg audio-speed input.mp4 1.5 --dry-run

  ffmpeg -i input.mp4 -af atempo=1.5 -c:v copy input-aspeed.mp4

注意:速度が変わるのは音声だけで、映像は -c:v copy のままフレームタイムスタンプを維持する。両方変えたいなら C4 の speed 動詞を使う。

audio-reverse — 音声のみ逆再生

音声だけバックワード再生、映像はフォワードのまま(独特のグリッチ表現)。

bash
$ npx fqmpeg audio-reverse input.mp4 --dry-run

  ffmpeg -i input.mp4 -af areverse -c:v copy input-audio-reversed.mp4

areverse は音声ストリーム全体を RAM にバッファするので長尺ファイルに注意。映像も一緒に逆再生するなら C4 の reverse を使う。

audio-delay — A/V同期オフセット(非対称な仕様)

映像に対して音声を遅らせる/早める。正の値で遅延、負の値で前倒し。

  • ソース: src/commands/audio-delay.js
  • 正(遅延): adelay=<ms>|<ms> — 音声の頭に無音をパッド
  • 負(前倒し): atrim=start=<秒>,asetpts=PTS-STARTPTS — 音声の頭を 切り落とす ので出力はその分だけ短くなる
  • 引数: <ms> — 整数ミリ秒、正負どちらも可
  • 出力: <入力名>-synced.<ext>
bash
$ npx fqmpeg audio-delay input.mp4 200 --dry-run

  ffmpeg -i input.mp4 -af adelay=200|200 -c:v copy input-synced.mp4

$ npx fqmpeg audio-delay input.mp4 --dry-run -- -200

  ffmpeg -i input.mp4 -af atrim=start=0.2,asetpts=PTS-STARTPTS -c:v copy input-synced.mp4

この非対称性が重要 — 音声を 200ms 前倒しすると 最初の 200ms は消える、シフトされるのではない。キャプチャ側のレイテンシ補正で先頭が無音だったケースなら問題ないが、先頭にコンテンツがあると破壊的な操作になる。

ノイズと無音

audio-noise-reduce — FFTベースのデノイズ

afftdn(FFTデノイザー)のラッパー。定常ノイズ(ファン音、車道騒音、テープヒス)に強い。

bash
$ npx fqmpeg audio-noise-reduce input.mp4 --strength 18 --dry-run

  ffmpeg -i input.mp4 -af afftdn=nr=18 -c:v copy input-denoised.mp4

--strength 12 は穏やか(音声に違和感を出さずノイズだけ減らす)、--strength 24 は強烈(クリーンになるが「水中」っぽいアーティファクトが出始める)。本番前に5秒サンプルで適正値を探る。

detect-silence — 無音区間検出(解析のみ)

読み取り専用。silencedetect を走らせて silence_start / silence_end / silence_duration 行を stderr に出す。出力ファイルなし。

オプションデフォルト備考
--threshold <dB>-30これより静かなら無音と判定
--duration <秒>2この長さ未満の無音は無視
bash
$ npx fqmpeg detect-silence input.mp4 --threshold -40 --duration 1 --dry-run

  ffmpeg -i input.mp4 -af silencedetect=noise=-40dB:d=1 -f null -

stderr を grep silence_ でフィルタすれば時刻情報だけ抽出できる。インタビュー素材をシーン単位に切る前の自動シーン検出に便利。

trim-silence — 無音区間を削除

silenceremove で最小尺以上の無音を全部削る。先頭の無音もセクション間の無音もまとめて削る。

  • ソース: src/commands/trim-silence.js

  • フィルタ:

    text
    silenceremove=start_periods=1:
    start_duration=0:
    start_threshold=<t>dB:
    stop_periods=-1:
    stop_duration=<d>:
    stop_threshold=<t>dB
    
  • デフォルト: --threshold -30 dB, --min-duration 0.5

  • 出力: <入力名>-trimmed-silence.<ext>

bash
$ npx fqmpeg trim-silence input.mp4 --threshold -35 --min-duration 1 --dry-run

  ffmpeg -i input.mp4 -af silenceremove=start_periods=1:start_duration=0:start_threshold=-35dB:stop_periods=-1:stop_duration=1:stop_threshold=-35dB -c:v copy input-trimmed-silence.mp4

stop_periods=-1 は「無音区間を全部削る」の意味(先頭1個だけではない)。映像はそのままコピーされるので、音声が短くなった分だけ A/V がズレる。映像も音声に追従させたいなら生 FFmpeg の filter_complexselectaselect をペアで使う必要がある。fqmpeg では detect-silence でタイムスタンプを取って C4 の trim で切るパスを推奨。

silence-insert — 指定位置に無音を挿入

apad + adelay で末尾に無音を足す。

  • ソース: src/commands/silence-insert.js
  • フィルタ: apad=pad_dur=<dur>:pad_len=0,adelay=<atMs>|<atMs>
  • 引数: <at>(挿入オフセット、秒)と <duration>(無音の長さ、秒)
  • 出力: <入力名>-silence-ins.<ext>
bash
$ npx fqmpeg silence-insert input.mp4 10 3 --dry-run

  ffmpeg -i input.mp4 -af apad=pad_dur=3:pad_len=0,adelay=10000|10000 -c:v copy input-silence-ins.mp4

注意:これは時刻 <at>きれいに中割り する操作ではない。apad+adelay の連鎖だと、まずパッドを末尾に足してから音声全体を <at> ミリ秒後ろにずらす — 結果として元の音声は <at> 秒から始まり、末尾に <duration> 秒のパッドが付く。本物の中割り(元音声 0…10 → 無音 → 元音声 10…末尾)が必要なら生 FFmpeg のマルチ入力 filter graph を書く。

censor — 指定範囲をビープ音で隠す(映像ではなく音声)

範囲内の音声をサイン波ビープで置き換える。これは 音声 の検閲であり映像モザイクではない — 映像をぼかすには blurpixelate を使う。

  • ソース: src/commands/censor.js

  • フィルタ: 範囲内の元音声を 0 にして、同じ範囲のサイン波を生成・ミックス:

    text
    [0:a]volume=enable='between(t,<s>,<e>)':volume=0[a0];
    [1:a]volume=enable='between(t,<s>,<e>)':volume=1:eval=frame[a1];
    [a0][a1]amix=inputs=2:duration=first[aout]
    
オプションデフォルト備考
-s, --start <秒>0ビープ開始
-e, --end <秒>必須ビープ終了
--freq <Hz>1000ビープ周波数
bash
$ npx fqmpeg censor input.mp4 -s 10 -e 12 --dry-run

  ffmpeg -i input.mp4 -f lavfi -i sine=frequency=1000 -filter_complex [0:a]volume=enable='between(t,10,12)':volume=0[a0];[1:a]volume=enable='between(t,10,12)':volume=1:eval=frame[a1];[a0][a1]amix=inputs=2:duration=first[aout] -map 0:v? -map [aout] -c:v copy -shortest input-censored.mp4

出力は -map 0:v?(映像オプション)なので音声のみファイルでも動く。-shortest でサイン生成がソース尺を超えないようにしている。

実用レシピ

複数動詞をつなぐエンドツーエンドの音声パイプライン3本。

1. ポッドキャスト整音(gate → compress → normalize → limit)

収録インタビューの標準的な納品チェーン。順序が重要 — まずゲートで環境音、次にコンプでレベルを揃え、normalizeでターゲットラウドネスに、最後にリミッターでオーバーシュート防止。

bash
# 1. -45 dB 以下の環境音をゲートで切る
npx fqmpeg audio-gate raw.wav --threshold -45 -o step1.wav

# 2. コンプ(3:1、穏やかなアタック)
npx fqmpeg audio-compressor step1.wav --threshold -18 --ratio 3 -o step2.wav

# 3. ポッドキャスト標準(-16 LUFS)に正規化
npx fqmpeg normalize step2.wav --target -16 -o step3.wav

# 4. -1 dB でブリックウォール リミット
npx fqmpeg limiter step3.wav --limit -1 -o final.wav

大量に回すなら中間 .wav を名前付きパイプにするか、ffmpeg -af gate,acompressor,loudnorm,alimiter 一発に詰める。各動詞の --dry-run がそのままビルディングブロックになる。

2. ダイアログ清掃(highpass → denoise → 高域抑制)

マイクのランブル・室内ヒス・耳に痛いシビランスが乗ったダイアログを整える:

bash
# 1. 80 Hz 以下のランブルを除去
npx fqmpeg audio-highpass dialogue.wav --freq 80 -o step1.wav

# 2. 広帯域のヒス(定常ノイズ)を抑える
npx fqmpeg audio-noise-reduce step1.wav --strength 15 -o step2.wav

# 3. 最終段の前にラウドネスを確認
npx fqmpeg loudness-meter step2.wav 2>&1 | grep -E '(I|LRA|True peak):'

# 4. 10 kHz の穏やかなローパスでシビランスを抑える
npx fqmpeg audio-lowpass step2.wav --freq 10000 -o final.wav

ステップ間に loudness-meter を挟むのは形状クラスタの crop-detect と同じ発想 — 計測してから判断、そして適用。

3. 音楽ベッドの同期準備(同期補正 → 正規化 → フェード)

ボイスと別撮りした音楽トラックを「下に敷く」前の整音:

bash
# 1. 同期ドリフトを修正(音楽がボイスより 350ms 早い場合)
npx fqmpeg audio-delay music.wav 350 -o synced.wav

# 2. ボイスにぶつからないよう小さめのターゲット(-22 LUFS)に正規化
npx fqmpeg normalize synced.wav --target -22 -o quiet-music.wav

# 3. 頭と尻に 3 秒フェード
npx fqmpeg audio-fade quiet-music.wav --in 3 --out 3 --duration 120 -o bed.wav

# 4. ボイスとミックス(生 FFmpeg か C11 の mix-audio 動詞)
ffmpeg -i voice.wav -i bed.wav -filter_complex amix=inputs=2:duration=longest:weights=1.5\ 1 final.wav

最終ミックスの直前まで fqmpeg で完結 — ミックス段で生 FFmpeg に降りるか、C11 の mix-audio 動詞を使う(音声ルーティング詳解で解説)。

よくある質問

normalizevolume の違いは?

volume は固定ゲイン倍率または dB オフセット — 全サンプルを同じ量だけシフトするだけでラウドネスは考えない。normalizeloudnorm(EBU R128)を走らせて 測定された 積分ラウドネスがターゲット LUFS に揃うようゲインを動かす。「他のプラットフォーム素材と同じ音量感にしたい」なら normalize、「正確に6dB大きく」なら volume

normalize のターゲット LUFS はどれを使えばいい?

-23 LUFS で EBU 放送TV(欧州)。-24 LUFS で ATSC A/85(米国放送)。-16 LUFS でポッドキャスト(多くのホスティングサービスがこの辺りをターゲット — fqmpeg のデフォルト)。-14 LUFS でストリーミング音楽(Spotify、YouTube、Apple Music はマスターをこの辺に正規化する)。-10 LUFS は「ラウドネス戦争」のコマーシャル参考値(実際にこれで納品するとプラットフォーム正規化で逆に細部を失う)。

audio-pitch が "No such filter: rubberband" で失敗する

FFmpeg が --enable-librubberband 無しでビルドされている。BtbNgyan.dev のスタティックビルドには入っている。macOS の Homebrew ffmpeg フォーミュラも対応、Linux の公式 Debian パッケージも対応。差し替えできない場合は2半音シフトを asetrate=44100*1.122462,aresample=44100,atempo=1/1.122462 で代用できる(音質は落ちるが組み込みフィルタだけで動く)。

audio-fade と C4 の fade の違いは?

C4 の fade は映像のみ(ビジュアル・クロスフェード or 黒へのディップ)。audio-fade は音声トラックだけを触り、映像はストリームコピー。両方同時にやりたければ順に実行する:npx fqmpeg fade ... → 結果に対して npx fqmpeg audio-fade ...

loudness-meterdetect-silence の出力をどう取る?

両方とも stderr に出力する&ファイルを書かない。2> でリダイレクトするか 2>&1 でパイプにつなぐ:

bash
npx fqmpeg loudness-meter input.mp4 2>&1 | grep -E '(I|LRA|True peak):'
npx fqmpeg detect-silence input.mp4 --threshold -40 2>&1 | grep silence_

CI やスクリプトでは stderr 行を必要な値だけパース。

trim-silence は A/V 同期を保つ?

保たない。映像ストリームはそのままコピーされ、音声だけ無音区間を削った分短くなる — 出力は A/V がズレる。「映像も音声カットに追従する」インタビュー編集が欲しいなら、selectaselect をペアで指定した1パスの filter_complex が必要。fqmpeg はこれを直接公開していない — 生 FFmpeg に降りるか、detect-silence でタイムスタンプを取って C4 の trim で事前に切る。

censor は映像モザイク?

違う。censor は音声をサイン波ビープで置き換える。映像の検閲は C6 の blurpixelate をクロップ領域に当てるか、不透明な四角形なら C8 の drawbox で合成する。

中間ファイル無しで音声フィルタを連鎖したい

2〜3ステップなら fqmpeg の中間ファイル方式で十分 — ディスクは速いし SSD ならIOコストは無視できる。長いチェーンを 1パスにまとめたいなら、各動詞に --dry-run をかけて -af の値をコピーし、コンマで繋ぐ:

bash
ffmpeg -i input.wav -af "highpass=f=80,afftdn=nr=15,loudnorm=I=-16:TP=-1.5:LRA=11,alimiter=limit=-1dB:attack=5:release=50" -c:v copy out.wav

これは fqmpeg の単発コマンドが内部でやっていることそのもの — 連鎖はディスクのラウンドトリップを削るだけ。

fqmpeg は出力にどの音声コーデックを使う?

ほとんどの動詞では、出力コンテナがデフォルトでネゴシエートする再エンコードコーデックに任せる(MP4 なら AAC、WebM なら Vorbis/Opus、.mp3 なら MP3)。fqmpeg は -c:a を明示しないので、出力拡張子に合わせて FFmpeg が決める。例外は audio 動詞で、常に libmp3lame -q:a 2 で MP3 を出力する。

まとめ

fqmpeg の C9 クラスタは音声エンジニアの日常ツールボックス — ポッドキャストマスタリング・ダイアログ清掃・音楽ベッド同期を、フィルタグラフを一行も書かずに 26 動詞のチェーンで組める。直感的でない箇所 — audio-delay の非対称な仕様、audio-pitch の Rubber Band 依存、audio-eq のハードコードされたミッド帯域、trim-silence の A/V ドリフト、silence-insert の末尾シフト — は上で全部書いたので本番で踏まないはず。

次の2手:

  1. 上のどの動詞でも npx fqmpeg <動詞> --help でライブのオプション一覧が見られる。
  2. クリエイティブ系のエフェクト(リバーブ・エコー・コーラス・フェイザー等)が欲しいなら C10 詳解(クリエイティブ音声エフェクト)へ。ルーティング・チャンネル・可視化(波形・スペクトログラム)なら C11 詳解(音声ルーティング・可視化)へ。

次に -af フィルタに手を伸ばしそうになったら、まず動詞一覧を見てみてください。