ffmpegでのmp3エンコード
- 2016/01/30
- 06:02
ffmpegでのmp3エンコードの話
ffmpegはビルド時にlibmp3lameを組み込むことでmp3のエンコードが可能になります。
このlibmp3lameはlameのエンコード/デコード部分のライブラリでlameと性能は全く同じなんですが、実はffmpegでエンコードするのとlameを使ってエンコードするのは微妙に違います。
これはけっこう大事なことではあるのですが語られることが少ないような気もします。
mp3のエンコードはビットレートが低い場合それに応じたローパスフィルタがかけられるようになっています。情報量の多い高域をカットして全体の音質を保つのが目的。
たとえばlameでステレオ96Kbpsでエンコードする場合のフィルタのカットオフは15KHz。それ以上の周波数の音はばっさり切られます。
アプリケーション版のlameではデフォルトではこのカットオフ周波数に合わせて自動的にリサンプルされサンプルレートも変化します。前述の96Kbpsのエンコードの場合、サンプルレートも32KHzにリサンプルされます。15KHzのローパスフィルタでばっさり切られた音声を44.1KHzのサンプルレートで表現するのはビットの無駄使い。まずは最低限の情報に圧縮しようというわけです。
実はこれが音質維持に大きく効いてきます。
ffmpegの場合は-arオプションなどで明示的にサンプルレートを指定しない限りは入力と同じサンプルレートが適用されます。つまり上記のような96Kbpsの場合でも入力が44.1KHzのサンプルレートなら44.1KHzのサンプルレートとしてエンコードされます。
たとえばこの二つのエンコードを比較してみます。
(src.wavはステレオ2ch、44.1KHzのサンプルレート)
ffmpeg -i src.wav -c:a libmp3lame -b:a 96k dest.mp3
lame -b 96 src.wav dest.mp3
同じ96Kbpsのエンコードでもffmpegは44.1KHz、lameは32KHzのサンプルレートでエンコードされます。この二つを聴き比べると明らかにlameのエンコードの方が音質が良いのがわかります。
(自分はこう評価しましたが、96Kbpsあたりだとなにをもって音質を良しとするかで人によって評価は分かれるかもしれません)
ffmpeg -i src.wav -c:a libmp3lame -b:a 64k dest.mp3
lame -b 64 src.wav dest.mp3
のようにさらに低ビットレート(64Kbps)ならその違いもよりはっきりすると思います。
cbr(固定ビットレート)で例を示しましたがabrやvbrでも同じです。
ffmpegでもエンコード時に明示的にリサンプルするとlameのオートリサンプルに近い音質が得られます。
ffmpeg -i src.wav -c:a libmp3lame -b:a 64k -ar 24000 dest.mp3
あるいは
ffmpeg -i src.wav -af aresample=24000 -c:a libmp3lame -b:a 64k dest.mp3
今はmp3プレイヤーも普通にGBオーダーの容量なので低ビットレートでエンコードする人は少ないかもしれませんが、低ビットレートを使う場合はこのあたりを注意しておくとより良い音質でエンコードできると思います。
ラジオ放送のエンコードは今も低ビットレートを活用している人が多いかも?
ちなみにlameのビットレートとカットオフ、自動リサンプリングのレートはこんな感じ
(ステレオ2ch、lame 3.99.5)
bitrate / lowpass cutoff / resample rate
32Kbps / 5.5KHz / 16KHz
48Kbps / 7.5KHz / 22.05KHz
64Kbps / 11KHz / 24KHz
96Kbps / 15.1KHz / 32KHz
128Kbps / 17.0KHz / リサンプル無し(44.1KHz 48kHz)
160Kbps / 17.5KHz / リサンプル無し(44.1KHz 48kHz)
192Kbps / 18.6KHz / リサンプル無し(44.1KHz 48kHz)
256Kbps / 19.7KHz / リサンプル無し(44.1KHz 48kHz)
320Kbps / 20.5KHz / リサンプル無し(44.1KHz 48kHz)
2016/02/02 追記:
上の記事で書いたlameで64Kbpsのmp3をチェックしているときに、ある周波数の不自然な音が頻繁に現れることに気が付きました。

lame -b 64 src.wav dest.mp3 でエンコードしたmp3を再生
周波数にするとだいたい7.3KHzあたり。
なぜかサンプルレート24KHzの時のみ顕著に現れます。視聴上もかなり耳障り。
理由はよくわかりませんが、この24KHzのサンプルレートで、エンコードのアルゴリズムがlameのオプションで言うと-q 3以下のときに起こるようです。大昔のlameはこんなこと無かったような気が・・・
lame なら
lame -b 64 -q 4 src.wav dest.mp3
ffmpegのコマンドなら
ffmpeg -i src.wav -c:a libmp3lame -compression_level 4 -b:a 64k -ar 24000 dest.mp3
のように4以上のアルゴリズムを指定するととりあえずこの問題は無くなるようです。
(数字が低いほど複雑なアルゴリズムが適用される。指定しない場合は3に設定。このあたりはlameのマニュアルを参照)
lameはギャップレスのエンコードに関してもバグなのか自分が悪いのか、ちょっとわからない怪しいところがあって、そのうちそのあたりもちゃんと検証してみたいと思います。
ffmpegはビルド時にlibmp3lameを組み込むことでmp3のエンコードが可能になります。
このlibmp3lameはlameのエンコード/デコード部分のライブラリでlameと性能は全く同じなんですが、実はffmpegでエンコードするのとlameを使ってエンコードするのは微妙に違います。
これはけっこう大事なことではあるのですが語られることが少ないような気もします。
mp3のエンコードはビットレートが低い場合それに応じたローパスフィルタがかけられるようになっています。情報量の多い高域をカットして全体の音質を保つのが目的。
たとえばlameでステレオ96Kbpsでエンコードする場合のフィルタのカットオフは15KHz。それ以上の周波数の音はばっさり切られます。
アプリケーション版のlameではデフォルトではこのカットオフ周波数に合わせて自動的にリサンプルされサンプルレートも変化します。前述の96Kbpsのエンコードの場合、サンプルレートも32KHzにリサンプルされます。15KHzのローパスフィルタでばっさり切られた音声を44.1KHzのサンプルレートで表現するのはビットの無駄使い。まずは最低限の情報に圧縮しようというわけです。
実はこれが音質維持に大きく効いてきます。
ffmpegの場合は-arオプションなどで明示的にサンプルレートを指定しない限りは入力と同じサンプルレートが適用されます。つまり上記のような96Kbpsの場合でも入力が44.1KHzのサンプルレートなら44.1KHzのサンプルレートとしてエンコードされます。
たとえばこの二つのエンコードを比較してみます。
(src.wavはステレオ2ch、44.1KHzのサンプルレート)
ffmpeg -i src.wav -c:a libmp3lame -b:a 96k dest.mp3
lame -b 96 src.wav dest.mp3
同じ96Kbpsのエンコードでもffmpegは44.1KHz、lameは32KHzのサンプルレートでエンコードされます。この二つを聴き比べると明らかにlameのエンコードの方が音質が良いのがわかります。
(自分はこう評価しましたが、96Kbpsあたりだとなにをもって音質を良しとするかで人によって評価は分かれるかもしれません)
ffmpeg -i src.wav -c:a libmp3lame -b:a 64k dest.mp3
lame -b 64 src.wav dest.mp3
のようにさらに低ビットレート(64Kbps)ならその違いもよりはっきりすると思います。
cbr(固定ビットレート)で例を示しましたがabrやvbrでも同じです。
ffmpegでもエンコード時に明示的にリサンプルするとlameのオートリサンプルに近い音質が得られます。
ffmpeg -i src.wav -c:a libmp3lame -b:a 64k -ar 24000 dest.mp3
あるいは
ffmpeg -i src.wav -af aresample=24000 -c:a libmp3lame -b:a 64k dest.mp3
今はmp3プレイヤーも普通にGBオーダーの容量なので低ビットレートでエンコードする人は少ないかもしれませんが、低ビットレートを使う場合はこのあたりを注意しておくとより良い音質でエンコードできると思います。
ラジオ放送のエンコードは今も低ビットレートを活用している人が多いかも?
ちなみにlameのビットレートとカットオフ、自動リサンプリングのレートはこんな感じ
(ステレオ2ch、lame 3.99.5)
bitrate / lowpass cutoff / resample rate
32Kbps / 5.5KHz / 16KHz
48Kbps / 7.5KHz / 22.05KHz
64Kbps / 11KHz / 24KHz
96Kbps / 15.1KHz / 32KHz
128Kbps / 17.0KHz / リサンプル無し(44.1KHz 48kHz)
160Kbps / 17.5KHz / リサンプル無し(44.1KHz 48kHz)
192Kbps / 18.6KHz / リサンプル無し(44.1KHz 48kHz)
256Kbps / 19.7KHz / リサンプル無し(44.1KHz 48kHz)
320Kbps / 20.5KHz / リサンプル無し(44.1KHz 48kHz)
2016/02/02 追記:
上の記事で書いたlameで64Kbpsのmp3をチェックしているときに、ある周波数の不自然な音が頻繁に現れることに気が付きました。
lame -b 64 src.wav dest.mp3 でエンコードしたmp3を再生
周波数にするとだいたい7.3KHzあたり。
なぜかサンプルレート24KHzの時のみ顕著に現れます。視聴上もかなり耳障り。
理由はよくわかりませんが、この24KHzのサンプルレートで、エンコードのアルゴリズムがlameのオプションで言うと-q 3以下のときに起こるようです。大昔のlameはこんなこと無かったような気が・・・
lame なら
lame -b 64 -q 4 src.wav dest.mp3
ffmpegのコマンドなら
ffmpeg -i src.wav -c:a libmp3lame -compression_level 4 -b:a 64k -ar 24000 dest.mp3
のように4以上のアルゴリズムを指定するととりあえずこの問題は無くなるようです。
(数字が低いほど複雑なアルゴリズムが適用される。指定しない場合は3に設定。このあたりはlameのマニュアルを参照)
lameはギャップレスのエンコードに関してもバグなのか自分が悪いのか、ちょっとわからない怪しいところがあって、そのうちそのあたりもちゃんと検証してみたいと思います。
スポンサーサイト