ffmpeg でオーディオ入力のラウドネスをリアルタイムに計測する

ffmpeg のオーディオフィルタには、EBU R 128 で採用されているアルゴリズム (ITU-R BS.1770) を用いて音声のラウドネスを計測できるものがある*1

これと、ffmpeg のオーディオ入力デバイスからリアルタイムに音声をキャプチャする機能を組み合わせることで、ffmpegコマンドライン上で動くリアルタイムラウドネスモニターとして使うことができる。

ffmpeg で各種入力デバイスから音声や映像を取り出す手段は OS ごとに異なる。macOS だと AVFoundation を用いるものが使えるし、Windows だと DirectShow、Linux であれば ALSA / PulseAudio + V4L あたり、というかんじっぽい。

AVFoundation でキャプチャするには、入力デバイスを番号で指定する必要があるので、狙ったデバイスをどの番号で指定したらよいのか一旦調べる必要がある。-list_devices というオプション付きで以下のようなコマンドを実行するとよい。

% ffmpeg -f avfoundation -list_devices true -i ""
(なんかめっちゃログが出る)
[AVFoundation indev @ 0x7fd68c521040] AVFoundation video devices:
[AVFoundation indev @ 0x7fd68c521040] [0] CamTwist
[AVFoundation indev @ 0x7fd68c521040] [1] Microsoft® LifeCam Studio(TM)
[AVFoundation indev @ 0x7fd68c521040] [2] CamTwist (2VUY)
[AVFoundation indev @ 0x7fd68c521040] [3] FaceTime HD Camera (Built-in)
[AVFoundation indev @ 0x7fd68c521040] [4] Capture screen 0
[AVFoundation indev @ 0x7fd68c521040] [5] Capture screen 1
[AVFoundation indev @ 0x7fd68c521040] AVFoundation audio devices:
[AVFoundation indev @ 0x7fd68c521040] [0] Microsoft® LifeCam Studio(TM)
[AVFoundation indev @ 0x7fd68c521040] [1] BlackHole 16ch
[AVFoundation indev @ 0x7fd68c521040] [2] Built-in Microphone

ここでは Built-in Microphone からの音声を処理してみたいので、2 番を指定したらよさそう、ということがわかる。

というわけで、以下のように実行することで、Built-in Microphone からの音声のラウドネスを計測できる:

% ffmpeg -f avfoundation -i ":2" -filter_complex ebur128 -f null /dev/null
Input #0, avfoundation, from ':2':
  Duration: N/A, start: 164969.992630, bitrate: 2822 kb/s
    Stream #0:0: Audio: pcm_f32le, 44100 Hz, stereo, flt, 2822 kb/s
[Parsed_ebur128_0 @ 0x7fc25912bfc0] Summary:

  Integrated loudness:
    I:         -70.0 LUFS
    Threshold:   0.0 LUFS

  Loudness range:
    LRA:         0.0 LU
    Threshold:   0.0 LUFS
    LRA low:     0.0 LUFS
    LRA high:    0.0 LUFS
Stream mapping:
  Stream #0:0 (pcm_f32le) -> ebur128
  ebur128 -> Stream #0:0 (pcm_s16le)
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
    Metadata:
      encoder         : Lavc58.91.100 pcm_s16le
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.0999792  TARGET:-23 LUFS    M:-120.7 S:-120.7     I: -70.0 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.211583   TARGET:-23 LUFS    M:-120.7 S:-120.7     I: -70.0 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.311583   TARGET:-23 LUFS    M:-120.7 S:-120.7     I: -70.0 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.411583   TARGET:-23 LUFS    M: -25.0 S:-120.7     I: -25.0 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.511583   TARGET:-23 LUFS    M: -25.2 S:-120.7     I: -25.1 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.623208   TARGET:-23 LUFS    M: -25.1 S:-120.7     I: -25.1 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.723208   TARGET:-23 LUFS    M: -24.9 S:-120.7     I: -25.1 LUFS       LRA:   0.0 LU
[Parsed_ebur128_0 @ 0x7fc25743c940] t: 0.834812   TARGET:-23 LUFS    M: -24.9 S:-120.7     I: -25.0 LUFS       LRA:   0.0 LU
^C
size=N/A time=00:00:00.89 bitrate=N/A speed=0.99x
video:0kB audio:161kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x7fc25743c940] Summary:

  Integrated loudness:
    I:         -25.0 LUFS
    Threshold: -35.0 LUFS

  Loudness range:
    LRA:         0.0 LU
    Threshold:   0.0 LUFS
    LRA low:     0.0 LUFS
    LRA high:    0.0 LUFS

-i ":2" の部分がデバイスの指定。-i "[[video]:[audio]]" の形式でデバイスの番号を指定してくれとドキュメントにある。ここでの [] は optional ですよという意味であり、今回は video は必要ないので、単になにも指定しなければ良い。

また、最終的に null output に吐き出すことで、出力先のことを気にせずにフィルタだけ便利に使うことができる。


とはいえ、ふつうにリアルタイムにラウドネスを見たいだけなら Youlean Loudness Meter とかを使うほうが 100 倍くらい手軽だとは思う……。Free バージョンでも、プラグインだけじゃなくてスタンドアロンのアプリがついてくるので便利。

youlean.co

*1:EBU R 128 はラウドネスノーマライゼーションに関する規格で、ITU-R BS.1770 はその中で用いられているラウドネスの測定法である、という理解