32blogby Studio Mitsu

fqmpegで音声ルーティング・チャネル・可視化: 14動詞を実装読みで全網羅

fqmpegの14動詞でチャネルレイアウト・マルチトラック合成・サンプルレート/ビット深度・音声可視化まで。実装由来の挙動と --dry-run 出力を全部載せる。

by omitsu33 min read
目次

fqmpeg の C11 クラスタは音声まわりの「配管と計測器」だ。チャネルレイアウト、マルチトラック合成、データ形式(サンプルレート・ビット深度)、可視化 — 14 動詞が音を移動させたり、形を変えたり、絵にしたりする。C9(レベル/EQ/ダイナミクス)や C10(クリエイティブエフェクト)と違って、C11 は音の 入れ物流れ を変えるもので、サウンドそのものはほとんど変えない。

この記事では fqmpeg 3.0.3src/commands/ を実読しながら、各動詞の元 FFmpeg フィルタ、デフォルト値、出力ファイル名、--help だけでは見えない罠(stereo --mode 5.1surround は完全に同じ、pan-audio は等パワーパンではなく線形減衰、bit-depth は PCM 対応コンテナでしか効かない、audio-visualize --mode waves の色は固定)を全部書く。

この記事で得られるもの

  • 14 動詞をタスクで選ぶ早見表(チャネルレイアウト / マルチトラック / 形式 / 可視化)
  • 各動詞が出す FFmpeg 起動行(--dry-run 検証済み)
  • デフォルト・単位・出力ファイル名 — そして「簡略化された CLI の裏で何が固定されているか」
  • 実例 3 本: デュアルマイクのポッドキャスト合成、多言語授業動画アップロード、波形可視化付き音声 YouTube アップロード

14 動詞の全体図

クラスタは 4 タスクグループに分かれる。グループを選んで、動詞を選ぶ。

グループ動詞やること
チャネルレイアウトstereo, surround, extract-audio-channel, pan-audioチャネル数変更、片側だけ抽出、ステレオフィールド内の位置決め
マルチトラック合成multi-audio, mix-audio, replace-audio, concat-audioトラック追加、BGM ミックス、音声差し替え、結合
形式・品質sample-rate, bit-depthサンプルレート変更、PCM ビット深度変更
可視化audio-visualize, oscilloscope, waveform, spectrumアニメーション動画、ベクトルスコープ overlay、静止画の波形・スペクトログラム

読み始める前に押さえておきたい5つのポイント:

  1. stereosurround は単に -ac をラップしただけ。 チャネル数(1 / 2 / 6)を渡すだけで、実際のダウンミックス/アップミックスマトリクスは FFmpeg のデフォルトに任せる。LFE を意識した処理も Dolby 対応のミックスもない。surround は文字通り stereo --mode 5.1 と同じだ。本格的なステレオ→5.1 アップミックスが欲しいなら、FFmpeg の surround フィルタを直接使う(こちらは別物 — エンベロープ追従型のアップミキサ)。
  2. pan-audio は等パワーパンではなく線形減衰パンだ。 --position 0(中央)では両チャネルとも 1.0 になるので、モノに合算した振幅は両端より +6 dB 大きい。中央定位のセリフからハードパンの音源にクロスフェードすると、中点で音量が膨らむ。
  3. bit-depth は PCM 対応コンテナ専用。 pcm_s16le / pcm_s24le / pcm_s32le を audio codec として強制する。AAC の MP4 や MKV ではこのコマンドは使えない — 普通は WAV ファイルに対して使う。出力拡張子は入力から引き継がれるので .wav を渡すこと。
  4. audio-visualize と静止画ビジュアライザは色とレイアウトが固定。 audio-visualize --mode waves0x00FF00(ターミナルグリーン)固定、--mode spectrumcolor=intensity 固定。静止画の waveform0x00FF00 がデフォルトだが --color で変えられる。静止画の spectrum は 14 種類のカラースキームを --color で選べる。oscilloscope overlay は avectorscope の 320×320 を画面の 70% 位置に貼る固定構成。
  5. multi-audio.mkv を推すのは MP4 のマルチオーディオが安定しないから。 MP4 は仕様上は複数音声をサポートするが、Safari やモバイルブラウザは最初の 1 本しか再生しないことが多い。MKV はトラック切り替えに対して素直。

チャネルレイアウト・ルーティング

stereo — 音声チャネル変換(mono ↔ stereo ↔ 5.1)

FFmpeg の -ac フラグの薄いラッパー。チャネル数を 126 のいずれかに設定する。実際のダウンミックス/アップミックスマトリクスは FFmpeg のデフォルトが決める。

引数 / オプションデフォルト許容値補足
<input>必須入力動画/音声
--mode <mode>stereomono, stereo, 5.1それぞれ -ac 1-ac 2-ac 6
-o, --output <path><入力 stem>-<mode>.<ext>出力名上書き
bash
$ npx fqmpeg stereo input.mp4 --mode mono --dry-run

  ffmpeg -i input.mp4 -ac 1 -c:v copy input-mono.mp4
bash
$ npx fqmpeg stereo input.mp4 --mode 5.1 --dry-run

  ffmpeg -i input.mp4 -ac 6 -c:v copy input-5.1.mp4

何が固定で、なぜか: ミックスマトリクスは fqmpeg 側ではハードコードされていない — FFmpeg 内蔵の pan-law マトリクスがそのまま動く。ステレオ → モノは L+R を等ゲインで合算(各 −3 dB)。ステレオ → 5.1 は L を FL+BL に、R を FR+BR にコピー、FC に合算、LFE を FC のローパスから合成するだけ — 妥当なデフォルトではあるがクリエイティブなアップミックスではない。エンベロープ追従でアンビエンスを抽出するような本格的な 5.1 化には FFmpeg の surround フィルタを使う(このコマンドではなくフィルタのほう)。

これで足りなくなったとき: カスタムなアップミックスをやりたいなら pan フィルタでマトリクスを明示する:

bash
ffmpeg -i stereo.wav -af "pan=5.1|FL=c0|FR=c1|FC=0.5*c0+0.5*c1|LFE=0.1*c0+0.1*c1|BL=c0|BR=c1" surround.wav

surround — ステレオ音声を 5.1 サラウンドにアップミックス

発見性のための別名。機能的には stereo --mode 5.1 と同じで、両者とも -ac 6 を渡して FFmpeg のデフォルトアップミックスマトリクスに任せる。

引数 / オプションデフォルト補足
<input>必須入力動画/音声
-o, --output <path><入力 stem>-surround.<ext>出力名上書き
bash
$ npx fqmpeg surround input.mp4 --dry-run

  ffmpeg -i input.mp4 -ac 6 -c:v copy input-surround.mp4

なぜ 2 つあるのか: 発見性。fqmpeg --help で「surround」を探すユーザーはこの動詞に直接たどり着く。チャネルレイアウトで考えるユーザーは stereo --mode 5.1 を選ぶ。出力は同じ。

extract-audio-channel — 単一の音声チャネルを抽出

ステレオ音源から左右どちらかを抜き出してモノ出力する。一方のマイクが片チャネルに録音された素材(インタビューリグ、デュアルマイクのフィールドレコーダー)に有用。

引数必須許容値補足
<input>はい入力動画/音声
<channel>はいleft, right残す側
-o, --output <path>いいえ出力名上書き
bash
$ npx fqmpeg extract-audio-channel interview.wav left --dry-run

  ffmpeg -i interview.wav -af pan=mono|c0=FL -c:v copy interview-left.wav

出力は モノpan=mono|...)であって、もう片方が無音のステレオではない。左右をそれぞれ抽出すると同じ長さのモノファイルが 2 本得られる。

pan-audio — 音声を左右にパンニング

ステレオフィールド内で音源の位置を変える。-1.0 = 完全に左、1.0 = 完全に右、0 = 中央。

  • ソース: src/commands/pan-audio.js
  • フィルタ: pan=stereo|c0=<L>*c0+0*c1|c1=0*c0+<R>*c1L = min(1, 1-p)R = min(1, 1+p)
  • 出力: <入力 stem>-panned.<ext>
引数 / オプション必須範囲補足
<input>はい入力動画/音声
<position>はい-1.01.00 = 中央、-1 = 完全左、1 = 完全右
-o, --output <path>いいえ出力名上書き
bash
$ npx fqmpeg pan-audio input.mp4 0.5 --dry-run

  ffmpeg -i input.mp4 -af pan=stereo|c0=0.50*c0+0*c1|c1=0*c0+1.00*c1 -c:v copy input-panned.mp4

パンの法則: 線形減衰、ユニティでクリップ。position 0 で両チャネルとも 1.0、合算モノは両端(position ±1、片側 1.0 もう片側 0)より +6 dB 大きい。これは等パワーパンではない。等パワーなら中央でも各チャネルを −3 dB 減衰させてモノ合算を一定に保つ。中央定位のセリフからハードパンの音源にクロスフェードすると中点で音量が膨らむ理由はこれ。

等パワーが必要なとき: sqrt 重み付けで pan マトリクスを書く:

bash
# position 0.5(やや右)の等パワーパン: L = sqrt((1-p)/2), R = sqrt((1+p)/2)
ffmpeg -i in.wav -af "pan=stereo|c0=0.500*c0|c1=0.866*c1" out.wav

マルチトラック合成

multi-audio — 動画に音声トラックを複数追加

入力動画に対して 追加の 音声ストリームとして音声ファイルをくっつける(既存トラックは残る)。多言語版書き出しで便利 — プレイヤー側で音声を切り替えてもらう。MP4 のマルチオーディオはプレイヤーの実装が信用できないため、出力は .mkv がデフォルト。

  • ソース: src/commands/multi-audio.js
  • フラグ: -map 0:v -map 0:a? -map 1:a -map 2:a ... -c copy
  • 出力: <動画 stem>-multi-audio.mkv.mkv 強制)
引数 / オプション必須補足
<video>はい入力動画
<audios...>はい(≥1)追加する音声ファイル
-o, --output <path>いいえ出力名上書き(.mkv 推奨)
bash
$ npx fqmpeg multi-audio video.mp4 jp.aac es.aac --dry-run

  ffmpeg -i video.mp4 -i jp.aac -i es.aac -map 0:v -map 0:a? -map 1:a -map 2:a -c copy video-multi-audio.mkv

全部 -c copy: 動画も音声も再エンコードしない。すべての入力が出力コンテナ(デフォルト .mkv)が受け付けるフォーマットでなければならない。-map 0:a?オプショナル マッピング(末尾の ?)なので、入力動画に音声がなくても落ちない。

.mkv を選んだ理由: Matroska は無制限の音声ストリームを素直に受け付け、プレイヤー(VLC、mpv、<video> + track switching な近代ブラウザ)も切り替えに対応している。MP4 は名目上マルチオーディオに対応しているが、iOS Safari や一部 Android ブラウザはプライマリ以外の音声を無視する。

mix-audio — 副音声トラック(BGM・ナレーション)をミックス

2 本目の音声ファイルを元動画にブレンドする。デフォルト音量は 30 % — セリフを潰さずに BGM として機能する程度。

  • ソース: src/commands/mix-audio.js
  • フィルタ: [1:a]volume=<v>[bgm];[0:a][bgm]amix=inputs=2:duration=first
  • 出力: <入力 stem>-mixed.<ext>
引数 / オプションデフォルト範囲補足
<input>必須入力動画
<audio>必須ミックス用音声
--volume <level>0.30.01.0ミックスする音声の音量
--shortestoffフラグ短い方のストリーム終端で出力を打ち切る
-o, --output <path><入力 stem>-mixed.<ext>出力名上書き
bash
$ npx fqmpeg mix-audio video.mp4 bgm.mp3 --dry-run

  ffmpeg -i video.mp4 -i bgm.mp3 -filter_complex [1:a]volume=0.3[bgm];[0:a][bgm]amix=inputs=2:duration=first -map 0:v -c:v copy video-mixed.mp4

duration=first: 出力は 1 本目(元動画)の音声 が終わったところで終わる。BGM が動画より長いと切られ、短いと途中で止まって以降は元音声だけが流れる。タイトループにしたいなら --shortest で BGM 長にも揃える。

amix の正規化のクセ: FFmpeg の amix フィルタはデフォルトで合算後に入力本数で割る(クリッピング防止のため)。2 本入力なら 各入力が合算前に半分 になる。fqmpeg の --volume 0.3 は BGM に amix の前に 適用されるので、最終出力での BGM は実効的に 0.3 / 2 = 0.15(−16 dB)。BGM が静かすぎたら --volume 0.6 を試す。0.3 を「−10 dB のつもり」と思うとズレる。

replace-audio — 音声トラックを完全に差し替える

元音声を捨てて、新しい音声ファイルに差し替える。ストリームコピー(再エンコードなし)なので、新音声は出力コンテナが受け付ける形式でなければならない。

引数 / オプションデフォルト補足
<input>必須入力動画
<audio>必須新しい音声ファイル
--shortestoff動画と新音声の短い方で終端
-o, --output <path><入力 stem>-newaudio.<ext>出力名上書き
bash
$ npx fqmpeg replace-audio video.mp4 voiceover.aac --dry-run

  ffmpeg -i video.mp4 -i voiceover.aac -map 0:v -map 1:a -c:v copy video-newaudio.mp4

新音声は ストリームコピー-c:a フラグの上書きがないため、フィルタグラフが触らないストリームは FFmpeg のデフォルトで copy 扱い)。新音声が .wav でコンテナが .mp4 だと FFmpeg が拒否することがある(PCM in MP4 は標準ではない)。事前に AAC に変換するか、出力拡張子を変える。

concat-audio — 複数の音声ファイルを連結

2 本以上の音声を順に繋ぐ。FFmpeg の concat デマクサ(list ファイル方式)を使うので、全入力が同一コーデック・サンプルレート・チャネルレイアウトでなければ stream-copy 結合は失敗する。fqmpeg は最初の入力ファイルのディレクトリに list ファイルを自動生成し、結合実行、終了時に自動削除する。

  • ソース: src/commands/concat-audio.js
  • フラグ: -f concat -safe 0 -i <listfile> -c copy
  • 出力: <最初の入力 stem>-joined.<最初の入力 ext>
引数 / オプション必須補足
<inputs...>はい(≥2)順に並べた音声ファイル 2 本以上
-o, --output <path>いいえ出力名上書き
bash
$ npx fqmpeg concat-audio part1.mp3 part2.mp3 part3.mp3 --dry-run

  # File list (auto-generated):
  # file '/abs/path/part1.mp3'
  # file '/abs/path/part2.mp3'
  # file '/abs/path/part3.mp3'

  ffmpeg -f concat -safe 0 -i filelist.txt -c copy part1-joined.mp3

concat デマクサの要件: 全入力が同じコーデック + サンプルレート + チャネルレイアウト。part1 が 48 kHz ステレオ MP3 で part2 が 44.1 kHz モノ MP3 だと stream-copy 結合は失敗する。事前に共通形式に変換するか、再エンコードする concat フィルタ(デマクサではなく)を直接使う:

bash
ffmpeg -i p1.mp3 -i p2.mp3 -filter_complex "[0:a][1:a]concat=n=2:v=0:a=1[out]" -map "[out]" joined.mp3

list ファイル内は絶対パス: fqmpeg は各入力を絶対パスに解決してから list ファイルを書くので、list ファイルの置き場所に依らず結合できる。list ファイルは最初の入力のディレクトリに .fqmpeg-concat-audio-<timestamp>.txt のような名前で作られ、終了時に削除される。

形式・品質

sample-rate — 音声サンプルレート変更

-ar でターゲットレートにリサンプリングする。FFmpeg のデフォルトリサンプラ(モダンビルドなら soxr、それ以外は aresample)が上下どちらにも対応する。

引数 / オプション必須補足
<input>はい入力動画/音声
<rate>はい(正の整数 Hz)一般的: 44100(CD)、48000(動画/放送)、96000(マスタリング)
-o, --output <path>いいえ出力名上書き
bash
$ npx fqmpeg sample-rate input.wav 48000 --dry-run

  ffmpeg -i input.wav -ar 48000 -c:v copy input-48000hz.wav

enum でない理由: description は 44100/48000/96000 を例示しているが、validator は 正の整数 しか要求しない。ニッチなレート(レトロな電話音声向けの 22050、ハイレゾマスタの 192000)も通る。FFmpeg の swresample が受け付けるものは何でも。

再エンコードは必須。 stream-copy ではサンプルレートを変えられない。fqmpeg は -c:a を渡さないので、FFmpeg は出力コンテナのデフォルトコーデック(MP4 なら AAC、WAV なら PCM など)で再エンコードする。コーデックを明示したいなら raw FFmpeg に降りる。

bit-depth — 音声ビット深度変更(PCM)

audio codec を 16 / 24 / 32 bit の PCM に強制する。実用上は出力が PCM 対応コンテナ(WAV、MKV、AIFF)でなければならない — AAC の MP4 では使えない。

  • ソース: src/commands/bit-depth.js
  • フラグ: -c:a pcm_s16le / pcm_s24le / pcm_s32le
  • 出力: <入力 stem>-<bits>bit.<ext>
引数必須許容値補足
<input>はい入力動画/音声(普通は WAV)
<bits>はい16, 24, 32ターゲットビット深度
-o, --output <path>いいえ出力名上書き
bash
$ npx fqmpeg bit-depth master.wav 24 --dry-run

  ffmpeg -i master.wav -c:a pcm_s24le -c:v copy master-24bit.wav

コンテナ互換性: .wav は 16/24/32 全部受け付ける。.mkv も受け付ける(PCM in Matroska は valid)。.mp4失敗するpcm_s24le は ISO BMFF(MP4)の有効コーデックではない。.mp4 を渡すなら出力拡張子を -o.mkv.wav に変える。

24-bit の内部表現: pcm_s24le は 24 bit のサンプルを 32 bit のコンテナ(リトルエンディアン、上位 8 bit がパディング)に格納する。ファイルサイズは 16 bit の 1.5 倍(32 bit の場合は 2 倍ちょうど)。

ビット深度 ≠ 音質。 16 bit ソースから生成した 24 bit ファイルは より細かい情報を含まない — 増えた 8 bit はゼロ詰め。元素材が実際に高ダイナミックレンジ(マルチマイクのフィールドレコーディング、マスタリング素材)でないと意味がない。

可視化

audio-visualize — アニメーション付き音声可視化動画

音声を 3 種類のライブビジュアライザのどれかで動画化する: 流れる波形(waves)、流れるスペクトログラム(spectrum)、ヒストグラム(histogram)。出力は入力拡張子に関わらず .mp4(H.264 + yuv420p)。

  • ソース: src/commands/audio-visualize.js
  • フィルタ(waves): showwaves=s=<W>x<H>:mode=cline:rate=30:colors=0x00FF00
  • フィルタ(spectrum): showspectrum=s=<W>x<H>:mode=combined:color=intensity:slide=scroll
  • フィルタ(histogram): ahistogram=s=<W>x<H>:rheight=0.5
  • 出力: <入力 stem>-visualize.mp4.mp4 強制)
引数 / オプションデフォルト許容値補足
<input>必須入力音声(動画も可、音声ストリームのみ使う)
--mode <mode>waveswaves, spectrum, histogram可視化スタイル
--size <WxH>1920x1080解像度文字列出力動画サイズ
-o, --output <path><入力 stem>-visualize.mp4出力名上書き
bash
$ npx fqmpeg audio-visualize song.mp3 --dry-run

  ffmpeg -i song.mp3 -filter_complex showwaves=s=1920x1080:mode=cline:rate=30:colors=0x00FF00 -c:v libx264 -pix_fmt yuv420p song-visualize.mp4
bash
$ npx fqmpeg audio-visualize song.mp3 --mode spectrum --dry-run

  ffmpeg -i song.mp3 -filter_complex showspectrum=s=1920x1080:mode=combined:color=intensity:slide=scroll -c:v libx264 -pix_fmt yuv420p song-visualize.mp4

何が固定か:

  • waves: 色 0x00FF00(ターミナルグリーン)、描画モード cline(中央線、スクロール)、リフレッシュレート 30 fps
  • spectrum: モード combined(ステレオペアごとに 1 バンド)、カラースキーム intensity、スクロールモード slide=scroll
  • histogram: rheight=0.5(相対バー高さ)
  • 全モード: video codec libx264 + yuv420p(普遍再生互換)

waves の 0x00FF00 は 32blog のブランドカラーに合わせているが、それ以上に showwaves がデフォルトで黒背景なので緑が読みやすいから。違う色が欲しいなら raw FFmpeg に降りる:

bash
ffmpeg -i song.mp3 -filter_complex "showwaves=s=1920x1080:mode=cline:rate=30:colors=0xFF6600" \
  -c:v libx264 -pix_fmt yuv420p song-orange.mp4

これで足りなくなったとき: スタイライズされたビジュアライザ(3D バー、Spotify 風ピークホールド付きイコライザ、パーティクル系)は FFmpeg だけでは無理。ミュージックビデオ用途なら Specterrbutterchurn(ブラウザで動く MilkDrop)を見る。fqmpeg のビジュアライザは機能はするが地味。

oscilloscope — 既存動画にオシロスコープ overlay

avectorscope(円形のフェイズ相関ディスプレイ)を既存動画に重ねる。ステレオイメージを見せること自体が美的要素になっているミュージックビデオや電子音楽デモ向け。

  • ソース: src/commands/oscilloscope.js
  • フィルタ: avectorscope=s=320x320:zoom=1.5:draw=line,format=yuva420p[osc];[0:v][osc]overlay=W*0.7:H*0.7
  • 出力: <入力 stem>-oscilloscope.<ext>
引数 / オプションデフォルト補足
<input>必須音声付き入力動画
-o, --output <path><入力 stem>-oscilloscope.<ext>出力名上書き
bash
$ npx fqmpeg oscilloscope musicvideo.mp4 --dry-run

  ffmpeg -i musicvideo.mp4 -filter_complex avectorscope=s=320x320:zoom=1.5:draw=line,format=yuva420p[osc];[0:v][osc]overlay=W*0.7:H*0.7 -c:a copy musicvideo-oscilloscope.mp4

avectorscope はステレオ相関を読む。 ドットパターンが左右チャネルの瞬間ごとの関係を表す: 縦線 = モノ(完全相関)、横線 = 逆相(モノ合算で打ち消し)、円形の雲 = ワイドステレオ。デュアルモノのセリフだと縦線 1 本、ワイドなシンセパッドだとざらついた楕円になる。

音声は保持(-c:a copy、フィルタグラフが映像を触るので動画は再エンコードされる。

これで足りなくなったとき: 元の avectorscope フィルタはもっと多くのパラメータを持つ(zoomm=peak/mode=binary、色用の rc/gc/bct=draw/line/dot)。fqmpeg の表面に出ていない範囲に踏み込むなら --dry-run のフィルタをコピーして編集する:

bash
# トレースに色をつけ、ズーム下げ、ドット描画
ffmpeg -i input.mp4 -filter_complex "avectorscope=s=480x480:zoom=1.0:draw=dot:rc=255:gc=128:bc=0,format=yuva420p[osc];[0:v][osc]overlay=W*0.5-240:H*0.5-240" -c:a copy out.mp4

waveform — 静止画の波形

音声トラック全体を 1 枚の PNG 波形にレンダリングする — ポッドキャストカバーや音声→動画変換で見る「オーディオグラム」のあれ。

  • ソース: src/commands/waveform.js
  • フィルタ: aformat=channel_layouts=mono,showwavespic=s=<W>x<H>:colors=<hex>
  • 出力: <入力 stem>-waveform.png.png 強制)
引数 / オプションデフォルト補足
<input>必須入力音声/動画
--size <WxH>1920x200出力画像サイズ — ポッドキャストカバーなら横長、レコード風なら縦長
--color <hex>0x00FF00hex 色(FFmpeg が受け付ける任意の色仕様 — 0xRRGGBB または Color@Alpha
-o, --output <path><入力 stem>-waveform.png
bash
$ npx fqmpeg waveform song.mp3 --dry-run

  ffmpeg -i song.mp3 -filter_complex aformat=channel_layouts=mono,showwavespic=s=1920x200:colors=0x00FF00 -frames:v 1 song-waveform.png

先にモノ化する: aformat=channel_layouts=mono で描画前に音声をモノ化する。これは意図的 — ステレオ波形画像は 2 段重ねの波形だと読みにくいし、静止画ではステレオの動きは表現できない。2 チャネル表示が欲しいなら aformat を外して showwavespic を調整:

bash
ffmpeg -i song.mp3 -filter_complex "showwavespic=s=1920x400:colors=0x00FF00|0xFF6600:split_channels=1" -frames:v 1 song-stereo.png

-frames:v 1 で 1 枚の PNG: showwavespic はトラック全体の波形を含む 1 フレームを生成する。このフラグで FFmpeg にシーケンスではなく 1 枚画像を書かせる。

spectrum — 静止画のスペクトログラム

音声の周波数 vs 時刻スペクトログラムを 1 枚 PNG にする。意図しないハム音(60 Hz の水平線)を探したり、高域ヒス(8 kHz 以上のエネルギー)を見つけたり、トラックのスペクトル指紋をジャケット用に可視化したり。

  • ソース: src/commands/spectrum.js
  • フィルタ: showspectrumpic=s=<W>x<H>:color=<scheme>
  • 出力: <入力 stem>-spectrum.png.png 強制)
引数 / オプションデフォルト許容値補足
<input>必須入力音声/動画
--size <WxH>1920x512解像度文字列スペクトラム領域のサイズ。デフォルトの legend がマージンを足すので、最終 PNG はさらに大きい(1920x512 で約 2200×640)
--color <mode>intensityintensity, rainbow, moreland, nebulae, fire, fiery, fruit, cool, magma, green, viridis, plasma, cividis, terrainカラースキーム
-o, --output <path><入力 stem>-spectrum.png
bash
$ npx fqmpeg spectrum song.mp3 --dry-run

  ffmpeg -i song.mp3 -filter_complex showspectrumpic=s=1920x512:color=intensity -frames:v 1 song-spectrum.png
bash
$ npx fqmpeg spectrum song.mp3 --color viridis --dry-run

  ffmpeg -i song.mp3 -filter_complex showspectrumpic=s=1920x512:color=viridis -frames:v 1 song-spectrum.png

スペクトログラムの読み方: 横軸が時刻(左 → 右)、縦軸が周波数(下が低、上が高、log スケール)、色がエネルギー量。クリーンな声トラックは 100 Hz〜4 kHz にエネルギーが集中して呼吸の隙間が見える。キックドラムは 60〜100 Hz の縦の線。意図しないグラウンドループハムは 50 か 60 Hz の真水平な線。マスタリングの診断には EQ + スペクトラムアナライザより速い。

showspectrumpic vs showspectrum: pic 接尾辞付きはファイル全体の静止画を生成する。pic なしのほうはアニメーション動画を生成する(audio-visualize --mode spectrum がこちら)。混同しない。

実用ユースケース

Recipe 1: デュアルマイクのポッドキャスト — トラック分離 → 個別 normalize → 再合成

Zoom 系のポッドキャスト録音で「ホストが左、ゲストが右」のステレオファイル 1 本に録られたものを、各話者ごとに別ゲイン・別 EQ でマスタリングして再合成するパターン:

bash
# Step 1: 各サイドを抜く
npx fqmpeg extract-audio-channel raw.wav left -o host.wav
npx fqmpeg extract-audio-channel raw.wav right -o guest.wav

# Step 2: 各々 normalize(C9 動詞)
npx fqmpeg normalize host.wav -o host-n.wav
npx fqmpeg normalize guest.wav -o guest-n.wav

# Step 3: 元のサイドにそれぞれ配置してステレオに戻す
ffmpeg -i host-n.wav -i guest-n.wav \
  -filter_complex "[0:a]apad,pan=stereo|c0=c0|c1=0[hL];[1:a]apad,pan=stereo|c0=0|c1=c0[gR];[hL][gR]amerge=inputs=2,pan=stereo|c0=c0+c2|c1=c1+c3" \
  podcast-final.wav

最後の手順は raw FFmpeg を使う — fqmpeg には「2 本のモノからステレオを作る」動詞がないため。pan チェーンでホストを左、ゲストを右に置き、amerge でまとめ、最後の pan で真のステレオに畳む。

Recipe 2: 多言語授業動画 — 1 動画に 3 音声トラック

50 分の授業動画と 3 言語のボイスオーバー(日本語・英語・スペイン語)がある。全部入りの MKV を YouTube や校内 CMS にアップしたい:

bash
# 全ボイスオーバーが動画と同じ長さである必要あり。
# (違うなら fqmpeg trim で trim するか、padding する)
npx fqmpeg multi-audio lecture.mp4 lecture-ja.aac lecture-en.aac lecture-es.aac
# → lecture-multi-audio.mkv

出力は元動画 + 元音声(あれば) + 追加 3 音声の MKV。トラック切替対応プレイヤー(VLC、mpv、近代の HTML5 video)なら、視聴者は別ダウンロードなしで言語を切り替えられる。

Recipe 3: 波形ビジュアル付き音声 YouTube アップロード

インタビューポッドキャストを YouTube にアップしたい。YouTube は動画が必要だが手元には音声しかない。音声反応する波形動画を絵として作る:

bash
# Step 1: 全長のアニメーション波形動画を作る
npx fqmpeg audio-visualize interview.mp3 --size 1920x1080 -o interview-visual.mp4

# Step 2: ビジュアライザの(無音の)音声を元音声に差し替え
npx fqmpeg replace-audio interview-visual.mp4 interview.mp3 -o interview-final.mp4

audio-visualize は音声付き動画を出すが、別バージョン(normalize 済みのを乗せたい、別イントロを足した版を使いたい)を当てたい場合は replace-audio で素直に差し替える。

同じインタビューの サムネイル には spectrum で 1 枚スペクトログラムを生成:

bash
npx fqmpeg spectrum interview.mp3 --color viridis --size 1920x1080 -o interview-cover.png

よくある質問

stereo --mode 5.1surround は本当に同じ?

はい — どちらも ffmpeg -i input -ac 6 -c:v copy output を実行する。違いは出力ファイル名のサフィックス(-5.1 vs -surround)とコマンド名だけ。fqmpeg が両方持っているのは利用者の心の中のメンタルモデルが違うから — 「チャネル数を変えたい」なら stereo、「5.1 サラウンドが欲しい」なら surround に手が伸びる。

pan-audio --position 0 のほうが --position 1 より大きい音に聞こえるのはなぜ?

パン法則が等パワーではなく線形減衰(ユニティでクリップ)だから。position 0 で両チャネル 1.0、position 1(完全右)で left=0、right=1。モノ合算すると position 0 は L+R = 2.0 = +6 dB、position 1 は R だけ = 1.0。モノ合算を一定に保つ等パワーパンが欲しいなら pan フィルタを sqrt 重み付けで自分で書く: c0=sqrt(1-p)*c0|c1=sqrt(1+p)*c1p は 0–1)。

bit-depth 24 が MP4 で失敗する — なぜ?

MP4(ISO BMFF)は audio codec として pcm_s24le を受け付けないから。ビット深度変更が動くのは PCM 対応コンテナだけ: .wav.mkv.aiff.flac。元 MP4 を一度 WAV に出して(ffmpeg -i in.mp4 -vn -c:a pcm_s16le audio.wav)から bit-depth を当て、最後に再 mux するか、出力拡張子を -o video-24bit.mkv.mkv に変える。

mix-audio --volume 0.3 の BGM がやけに静かなんだけど?

FFmpeg の amix フィルタは出力を入力本数で割るから(クリッピング防止のため)。2 入力なら 各々が合算前に半分 になる。volume=0.3 の BGM は最終出力では実効的に 15 %(0.3 / 2 = 0.15、約 −16 dB)。元音声も半分になり、合算される。BGM がセリフに対して静かすぎたら「気づける程度」なら --volume 0.6、「ほぼ対等にミックス」なら --volume 1.0 を試す。

サンプルレートやコーデックが違う音声を concat-audio で繋げる?

concat-audio では無理 — concat デマクサ を使うので、stream-copy には同じコーデック + サンプルレート + チャネルレイアウトが必要。違う場合は 2 案: (1) 各ファイルを共通形式に事前変換(npx fqmpeg sample-rate part1.mp3 48000 -o part1-48k.mp3 を全ファイルに)、(2) 再エンコードする concat フィルタ を raw FFmpeg で直接使う:

bash
ffmpeg -i p1.mp3 -i p2.wav -i p3.aac -filter_complex "[0:a][1:a][2:a]concat=n=3:v=0:a=1[out]" -map "[out]" joined.mp3

audio-visualize --mode waves がいつも緑なのはなぜ?

元のフィルタ呼び出しが colors=0x00FF00 をハードコードしているから(ターミナルグリーン、32blog ブランドカラー)。この動詞には --color オプションがない。違う色が欲しいなら --dry-run 出力をコピーして hex 値を編集して FFmpeg を直接叩く。静止画版の waveform--color を持つので、単発の色違いが欲しいだけなら静止画を生成してポスター画像として使うほうが簡単。

audio-visualize --mode spectrumspectrum の違いは?

audio-visualize --mode spectrumアニメーション動画(流れるスペクトログラム、showspectrum フィルタ、.mp4 出力)。spectrum静止画 1 枚(トラック全体を 1 枚 PNG に、showspectrumpic フィルタ、.png 出力)。アニメ版は音声アップロードの背景動画、静止版はジャケットや一目診断に使う。

multi-audio は何か再エンコードする?

しない — 全ストリームが -c copy。動画も全音声トラックもストリームコピー。つまり入力音声ファイルは出力コンテナ(デフォルト .mkv)が受け付ける形式でなければならない。AAC、MP3、Opus、Vorbis、PCM はどれも OK。Apple Lossless(ALAC)を厳格な .mp4 に多重化しようとすると動くが(MP4 は ALAC に対応している)、ブラウザによっては再生できない。

まとめ

C11 の 14 動詞は「音声トラックがある」状態から「納品物に合った形になっている」状態の間を埋める:

  • stereosurroundextract-audio-channelpan-audio — チャネルレイアウト(最初の 2 つは -ac の薄いラッパー、pan-audio は等パワーではなく線形減衰)
  • multi-audiomix-audioreplace-audioconcat-audio — マルチトラック合成(mix の amix は各入力を半分にする — BGM が静かすぎたら --volume を上げる、concat は stream-copy に同一コーデック/SR/レイアウトが必要)
  • sample-ratebit-depth — 形式変換(bit-depth は PCM 専用 — MP4 ではなく WAV か MKV を渡す)
  • audio-visualizeoscilloscopewaveformspectrum — 可視化(アニメ版は色固定、静止画版は「オーディオグラム」ジャケット制作のワークフロー)

すべての動詞が --dry-run で元の FFmpeg 起動行を出すので、簡略化された CLI で足りないとき(カスタムパン法則、複数コーデックの concat、2 チャネルスペクトログラム)はフィルタをコピー・編集して FFmpeg を直接叩く。fqmpeg 全体マップは fqmpeg complete guide を参照。