YouTubeへの動画投稿時、PCM音声を含む動画ファイルを作成すれば公開までに必要以上にエンコード&デコードを繰り返すことによる劣化を回避できる…かもしれません。今回はFFmpegを使用してH.264/FLAC (48kHz/24bit)で圧縮したファイルを作成する方法をご紹介致します
2019/1/11追記: 続編のエントリはこちら
はじめに
YouTubeは、アップロードされたファイルの音声トラックをシステム側で再エンコードすることが知られています。
また同社は、アップロードするファイルの音声にAAC/mp3といった非可逆圧縮形式の使用をガイドラインで推奨しています。
これに従うと、音声の(あるいは映像も)劣化をともなう非可逆圧縮が、ファイル作成時とアップロード後の2度に渡り、繰り返し行われることになります。
そこで、この2度の圧縮のうちせめて一方は回避できればと、48kHz/24bit PCMのまま動画ファイルをアップロードする方法を考えてみました。
なお、本稿の手順によりファイル作成からYouTubeにアップロードしての視聴までは確認できておりますが、その結果がYouTubeが推奨するコーデックを使用した場合よりも音質面で優位であるかどうかの判断は皆様に委ねたいと思います。
前準備
ソースとなる動画ファイルと音声ファイルの多重化(mux)にはFFmpegを使用しますので、コマンドラインがある程度使えることが前提になります。
音声ファイルの作成時は以下にご注意ください。
- 音声はあらかじめ映像に同期させておきます。
※試した限りでは、たとえば「歌みた」動画のような作品なら、元の動画の音声トラックを参照し、ファイル冒頭からイントロ(あるいはアタックの明確な箇所)までの時間がだいたい同一であることを確認できればOKと思われます。 - 尺は映像より短くしておくと事故を回避できるように思われます。
- 音声ファイルは48kHz/24bitで書き出します。
下記サイトよりFFmpegを入手します。
手順
1.FFmpegでストリームの番号を確認する
FFmpegで動画ファイルと音声ファイルを多重化する前に、それぞれのストリームIDを確認します。
ffprobe -i source_video.mp4
<出力結果>
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280×720 [SAR 1:1 DAR 16:9], 9891 kb/s, 30 fps, 30 tbr, 30k tbn, 60 tbc (default)
Metadata:
creation_time : 2019-01-07T05:27:46.000000Z
handler_name : ?Mainconcept Video Media Handler
encoder : AVC Coding
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
Metadata:
creation_time : 2019-01-07T05:27:46.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
上記中、Stream #0:[n] の部分より、ストリームID 0がVideo、ストリームID 1がAudioであることがわかりました。今回は前者の映像より使用し、音声は使用しません。
次に同様にWAVファイル中の音声のストリームIDを調べます。(通常のWAVファイルであれば大抵0番ですので、調べる必要はあまりありませんが…)
ffprobe -i source_audio.wav
<出力結果>
Duration: 00:05:01.65, bitrate: 2304 kb/s
Stream #0:0: Audio: pcm_s24le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s32 (24 bit), 2304 kb/s
こちらはストリームID 0番にsigned 24bit (little endian)のPCM音声が含まれていることが確認できました。
2. 映像と音声を多重化する
各ファイルのうち使用するソースのストリームIDがわかったところで、次にこれらを取り出し、多重化してひとつのファイルにまとめます。
ffmpeg -i source_video.mp4 -i source_audio.wav -vcodec copy -acodec flac -map 0:0 -map 1:0 -strict -2 out_video.mp4
- [source_video.mp4]には元となる動画ファイルを、[source_audio.wav]には、音声ファイルを、それぞれ指定します。
- -vcodec copyは、映像をトランスコードせずに多重化するオプションです。
- -acodec flac は、音声をFLAC形式で可逆圧縮を行うコマンドです。
- -map 0:0 (ひとつ目のmap)オプションは、ソースとして列挙したファイルのうちひとつ目(この場合は動画ファイル)より、ストリームID 0番を使用する指示です。先にffprobeコマンドで調べた結果、映像のストリームIDが0でない場合は適宜変更してください。
- -map 1:0(ふたつ目のmap)オプションは、2番目に上げたソースファイルより最初のストリームIDを使用する指示です。
- -strict -2 オプションは、執筆時点ではまだ試験的な機能とされているmp4ファイルへのFLAC多重化を強制的に実行するために必要になります。
- 最後の[out_video.mp4]には、出力ファイル名を任意に設定します。
追記:出力時の拡張子を.movに変更することで、32fの音声ファイルも多重化できることがわかりました。その場合のコマンドは以下のようになります。
ffmpeg -i source_video.mp4 -i source_audio.wav -vcodec copy -acodec copy -map 0:0 -map 1:0 out_video.mov
以上でファイルのできあがりです。
muxにより音声は変化しないのか?
作成した動画から音声トラックのみを抽出し、WaveCompareを使って元のWAVファイルと比較してみました。
ffmpeg -i out_video.mp4 -acodec pcm_s24le flac2pcm.wav
実は上記コマンドで出力したママのファイルではWave Compareでは認識できなかったため、一旦iZotope RXに読み込んで保存しなおしたファイルを比較に使用しましたが、それでもなお元のファイルと内容が一致しました。
おまけ
FFmpegでは、下記コマンドをを使用して動画ファイルのラウドネス(Integrated)も測定できます。
ffmpeg -nostats -i out_video.mp4 -filter_complex ebur128 -f null -
詳しくはFFmpeg本家ドキュメントをご覧ください。
YouTubeへ作品をアップロードする前に、規定レベルから大きくはずれていないかどうか最終チェックを行ってもよいかもしれません。