前回投稿は、音声ファイルの「秒単位のビットレート」をグラフ化するので分解能に関して難点がありました。 今回は、グラフの分解能を上げるためFFmpegの ashowinfo を使って「フレーム単位のビットレート」からグラフ化する方法を紹介します。
「フレーム単位のビットレート」でグラフ化した時の分解能は、サンプルレートやフォーマットで相違しますが「秒単位のビットレート」に比べて、分解能が約40倍以上に向上し、ビットレートの変動が高精細でグラフ化できます。
先ず、「フレーム単位」で描画したビットレート・グラフを示します。
下のグラフは、「ドボルザークのスラブ舞曲(Op46)」をmacOS用のXLDアプリで[目標最高品質値:127]設定のVBRモードで変換したAACファイルのビットレートグラフです。
青線グラフは、今回のashowinfo を使って「フレーム単位」で、赤線グラフは、前回の「秒単位」でビットレートをグラフ化しています。
ポイント
- フレーム単位・グラフ:
「フレーム単位のビットレート」でグラフの分解能が上がったため、VBRモードによるビットレートの変動が高精細で描画されています。 - 秒単位・グラフ:
「秒単位のビットレート」のグラフは、フレーム単位のビットレート変動の平均を示していると考えられます。
AAC(or MP3)ファイルのフレームについて
通常、音声ファイルは、ある程度のサンプル(サンプリング)数をまとめてフレームとして処理します。 このフレーム当りのサンプル数は音声フォーマットの固有の値になります。 MediaInfoで調べると、フレームレート(spf)で示されます。
次で説明する ashowinfo で調べたデータから算出したAACとMP3の音声ファイルのフレームあたりのサンプル数とフレーム時間(fs=48khz)を示します。 フレーム時間は、グラフ化した時の横軸 分解能になります。
フォーマット | フレーム当りの サンプル数 |
フレーム時間 fs=48khzの場合 |
AAC | 1024 | 21ms |
MP3 | 1152 | 24ms |
関係式
Time:音声ファイルの時間(sec)
N:総フレーム数
fs:サンプルレート(khz)
- AACのサンプル数:1024spfになる
- MP3のサンプル数:1152spfになる
- AAC(fs=48khz)の場合
サンプル数に1024を代入すると、フレーム時間は21msになる。 - MP3(fs=48khz)の場合
サンプル数に1152を代入すると、フレーム時間は24msになる。
FFmpegのashowinfoについて
ashowinfoは、FFmpegのフィルターの一つで、オーディオストリームの詳細な情報を表示するために使用されます。このフィルターを適用すると、音声データのフレーム順に、「フレーム番号」「秒単位の累積タイム」「累積バイト数」などの情報を取得できます。(CSVへの出力も可能)
"input_file"に音声ファイルを記述して、下のコマンドラインをターミナルから実行すると、フレーム順にデータが表示されます。
bash command
ffmpeg -i "input_file" -af "ashowinfo" -f null - 2>&1
なお、ashowinfoを使うには、FFmpeg CLIをインストールする必要があります。 FFmpegのインストールについては、ここの記事を参考にしてください。
フレーム毎の情報をCSV化する方法
下のコードは、 ashowinfo の情報をCSVファイルに保存する bash script です。 bash scriptのinput_fileにフルパスでターゲットの音声ファイルを記述し、ターミナルにペーストして実行すると、デスクトップにフレーム毎の情報がCSV化され保存されます。
1 2 3 4 5 |
{ echo "frame,pts_time,pos" #csvのヘッダー ffmpeg -i "input_file" -af "ashowinfo" -f null - 2>&1 | grep 'pts:' | awk '{print $4","$6","$7}' | sed 's/pts_time://;s/pos://' | sed '1,2d' } > "/Users/xxx/Desktop/bitrate_output.csv" |
bash scriptの$4、$6、$7は、夫々 frame(番号)、pts_time(秒単位の累積タイムスタンプ)、pos(フレームの累積バイト数)に対応し、夫々のフレームデータがcsvに格納されます。
フレーム毎のビットレートは別途、算出する必要があります。
例えばn:10フレームのビットレートを計算するには、n:9とn:10の差を計算しn:10フレームのデータサイズとフレーム時間を算出しビットレートを算出します。 具体的には以下に拠ります。
n:10のビットレート計算データサイズ=2119(n:10)-1523(n:9)=596バイト
時間=0.2133(n:10)-0.192(n:9)=0.0213秒
------------
ビットレート(n:10)=(596✕8÷0.0213)÷1000=224kbps
(596✕8はバイトをビットに変換)
「フレーム単位」でビットレートをグラフ化する方法
step.1 Numbersを開く
先ほどのbash scriptでCSV化したファイルをダブルクリックすると、Numbersが自動的に開きます。 今回はmacOSのNumbersを使っていますが、ExcelでもOKです。
step.3 数式のコピペ
- 数式を入れたD列の10行目のセルを右クリックしてコピーする。
- D列をクリックして全選択状態にしたら、ペーストします。 すると、D列全部に数式が貼り付けられます。
- D列の1行と2行が数式エラーになるので、デリートします。
- 最後にD列の1行を「kbps」と記述して完成です。
step.4 「フレーム単位」でビットレートをグラフ化
上のstep.3の内容を含めてグラフ化するまでの手順を記録した動画です。 下の動画を参照してグラフ化してください。
「フレーム単位」で描画したビットレート・グラフと音声Wave波形を重ね合わせてみました。
下のグラフは、「ドボルザークのスラブ舞曲(Op46)」をmacOS用のXLDアプリで[目標最高品質値:127]設定のVBRモードで変換したAACファイルを今回説明する方法で秒単位のビットレートをグラフ化(赤の折れ線グラフ)し、更にAudacityによる音声ファイルのWave波形を重ね合わせています。
XLDで変換したAAC(VBR-q127)ファイル:
カラヤン指揮・ドボルザークのスラブ舞曲(Op46-1)