radikoのflvから取り出したAACはなぜiTunesで読めないのか?
- http://radiko.jp/ は既存のラジオ放送をWebで同時配信(サイマル放送)してくれている。
- その番組をradikoroを使って録音すると、20100905220904.flvのようなフラッシュビデオ形式のファイルとして保存される。
- 保存されたファイルは、大体1時間番組で20MBくらいのサイズ。
- flvではiTunes・iPodが再生してくれないので、radikoroの録音設定でmp3に変換するようにしている。
- ところが、変換後のmp3は50MBくらいのサイズになってしまう。およそ2.5倍に膨れ上がっているのだ。
- 今時のハードディスクは、テラバイトが標準になりつつあるので大した問題はない。でも、気分が良くない。
- 調べてみるとradikoの音声は、HE-AAC 48kbpsのステレオ品質*1らしい。(着うたフルと同等レベル)
- 上記のHE-AACは、flvというコンテナ*2に収められて、配信されているのだ。
- そしてHE-AACは、flvの中からそっくりそのまま取り出すことができるらしい。
- 早速ffmpegコマンドを利用して取り出してみた。
ffmpeg -i 20100905220904.flv -acodec copy 20100905220904.m4a
- 呆気なく.flvが.m4aに変換されてしまった。
- 実際には取り出しているだけなので、変換ではない。
- 出てきた.m4aは.flvと遜色なく、劣化は全くないはず。
- すんなりこれで解決かと思いきや、問題はそんなに簡単ではなかった。
- 取り出された20100905220904.m4aを再生しようとしてみるが...
- iTunes・QuickTime Player・Quicklook等のQuickTime系ソフトウェアでは再生できなかったのだ。
- 一方、VLC・MPlayerではちゃんと再生できた。
- 考えてみれば、flvの時からQuickTime系では再生できなかった。
- Perianをインストールしているので、基本的にflvは再生できるはずなのに。
- HE-AACはQuickTime系では再生できないエンコード形式なのだろうか?いや、そんなことはない。
- iTunesの読み込み設定...でカスタムを見ると、「High Efficiencyエンコーディング(HE)を使用」を設定できるようになっている。
プロファイル
- ではなぜ再生できないのか?原因はAACのプロファイルの違いにあった。
- AACには、LC(Low Complexity)、MAIN、SSR(Scalable Sampling Rate)の3種類のプロファイルがあるそうだ。
種類
つまり、AACには3つのプロファイルがある。
- MAIN
- エンコード処理を厳密に実行する。(圧縮率は良いが高負荷)
- LC(Low Complexity)
- エンコード処理を簡略化して実行する。(低負荷)
さらに、上記AACに以下の技術を適用してエンコードしている場合がある。
さらに、さらに、上記HE-AACに以下の技術を適用してエンコードしている場合がある。
- iTunesが再生できるのは、LC(Low Complexity)プロファイルなHE-AACのみ。(HE-AAC v2はNG)
- HE-AACなどの技術は、低ビットレートな環境で高品質を狙ったもの。
- 最高品質を狙うのであれば、AAC最高の320Kbpsに設定するのがベスト。(但し、ファイルサイズはでかくなる)
- ファイルサイズは、ビットレート・サンプルレートに比例する。(例:ビットレートが48Kから96Kになれば、ファイルサイズも2倍になる)
さらに、さらに、さらに...
- 槻ノ木隆の「BBっとWORDS」(感謝です!)
AACもまた奥が深い...。
変換(MAINプロファイルHE-AAC → LCプロファイルHE-AAC)
- メインプロファイルからLC(Low Complexity)プロファイルのAACにするには、再エンコードするしかなさそう。
- 素人目には同じAACなのだから、劣化なしのプロファイル変換を期待してしまうのだが、それは無理なようだ。
ffmpeg -i 20100905220904.flv -ab 48k 20100905220904_ffmpeg_48k.m4a
- 変換された20100905220904_ffmpeg_48k.m4aを聴いてみると、何だか少しこもった感じの音。(高音域がなくなってしまったような印象)
- しかも、ファイルサイズは増えて381KB→512KB。ファイルサイズからビットレートを予測すると64Kbpsでエンコードされている模様。
- ffmpegが出力する情報を見ても64Kbps前後でエンコードされているようだ。
- 調べてみると、MacPortでインストールしたffmpegにHE-AACエンコードの機能はない様子。
- 通常のAACのビットレートは64〜320kbpsが有効範囲。
- おそらく、48Kbpsを指定しても、ffmpegが有効範囲最低の64Kbpsに補正してしまうのだ。
- そこで、一旦劣化なしのaiffに変換してみた。
ffmpeg -i 20100905220904.flv 20100905220904.aiff
AppleScriptで変換
- 毎回ターミナルでffmpegを実行して、iTunesに読み込ませて、右クリックしてAACバージョンを作成では、いかにも面倒。
- お決まりのAppleScriptで、一連の作業を処理するようにしてみた。
property ffmpeg_path : "/opt/local/bin/ffmpeg"
property tmp_path : "/tmp/_flv_to_itunes/"
try
do shell script "mkdir " & tmp_path
end try
tell application "Finder"
set select_list to selection
end tell
repeat with f in select_list
set file_path to (f as text)'s POSIX path
set file_name to do shell script "n=" & file_path's quoted form & ";echo \"${n##*/}\""
set fn_no_ext to do shell script "n=" & file_name's quoted form & ";echo \"${n%.*}\""
set aiff_path to tmp_path & fn_no_ext & ".aiff"
set convert_path to POSIX file aiff_path
do shell script ffmpeg_path & " -y -i " & file_path's quoted form & " " & aiff_path's quoted form
tell application "iTunes" to convert convert_path
do shell script "rm " & aiff_path's quoted form
end repeat
afconvertでHE-AAC変換
- 上記までのAACバージョンの作成は、iTunes >> 環境設定... >> 一般 >> 読み込み設定... に依存する。
- もし設定がMP3 エンコーダになっていると、MP3バージョンが作成されてしまうのだ。
- iTunesの設定に依存せず、HE-AACにエンコードする方法はないものかと調べていると...
- 灯台下暗し...。OSX標準でインストールされるafconvertコマンドを見つけた!
- そういえば先日、afplayコマンドにお世話になったばかりだった。
- ちなみにもう一つ、afで始まるafinfoコマンドもあった。afplay・afconvert・afinfoは、afファミリーなコマンドなのであった。
afconvert -f m4af -d aac -b 128000 20100905220904.aiff
- 入力ファイル名だけ指定して、出力ファイル名を省略すると、入力ファイル名の拡張子だけ変更したファイルになる。
- オプション指定できるデータフォーマットはafconvert -hfで確認できる。
$ afconvert -hf Audio file and data formats: '3gpp' = 3GP Audio (.3gp) data_formats: 'aac ' 'samr' '3gp2' = 3GPP-2 Audio (.3g2) data_formats: 'aac ' 'samr' 'adts' = AAC ADTS (.aac, .adts) data_formats: 'aac ' 'aach' 'ac-3' = AC3 (.ac3) data_formats: 'ac-3' 'AIFC' = AIFC (.aifc, .aiff, .aif) data_formats: I8 BEI16 BEI24 BEI32 BEF32 BEF64 UI8 'ulaw' 'alaw' 'MAC3' 'MAC6' 'ima4' 'QDMC' 'QDM2' 'Qclp' 'agsm' 'AIFF' = AIFF (.aiff, .aif) data_formats: I8 BEI16 BEI24 BEI32 'amrf' = AMR (.amr) data_formats: 'samr' 'caff' = Apple CAF (.caf) data_formats: '.mp1' '.mp2' '.mp3' 'QDM2' 'QDMC' 'Qclp' 'Qclq' 'aac ' 'aach' 'aacl' 'alac' 'alaw' 'dvi8' 'ilbc' 'ima4' I8 BEI16 BEI24 BEI32 BEF32 BEF64 LEI16 LEI24 LEI32 LEF32 LEF64 'ms\x00\x02' 'ms\x00\x11' 'ms\x001' 'samr' 'ulaw' 'm4af' = Apple MPEG-4 Audio (.m4a) data_formats: 'aac ' 'aach' 'aacl' 'alac' 'MPG1' = MPEG Layer 1 (.mp1, .mpeg, .mpa) data_formats: '.mp1' 'MPG2' = MPEG Layer 2 (.mp2, .mpeg, .mpa) data_formats: '.mp2' 'MPG3' = MPEG Layer 3 (.mp3, .mpeg, .mpa) data_formats: '.mp3' 'mp4f' = MPEG-4 Audio (.mp4) data_formats: 'aac ' 'aach' 'aacl' 'NeXT' = NeXT/Sun (.snd, .au) data_formats: I8 BEI16 BEI24 BEI32 BEF32 BEF64 'ulaw' 'Sd2f' = Sound Designer II (.sd2) data_formats: I8 BEI16 BEI24 BEI32 'WAVE' = WAVE (.wav) data_formats: UI8 LEI16 LEI24 LEI32 LEF32 LEF64 'ulaw' 'alaw'
- 目指すフォーマットは「 'm4af' = Apple MPEG-4 Audio (.m4a)」と思われる。(拡張子が.m4aなので)
- そのデータフォーマットには'aac ' 'aach' 'aacl' 'alac' の4つが指定できるようになっている。
- aacはiTunes標準のAACだと思うが、その他のフォーマットが略語で自分にはチンプンカンプン。
$ afconvert -f m4af -d aac -b 128000 20100905220904.aiff $ afconvert -f m4af -d aach -b 128000 20100905220904.aiff Error: Couldn't set audio converter property ('!dat') $ afconvert -f m4af -d aach -b 48000 20100905220904.aiff $ afconvert -f m4af -d aacl -b 48000 20100905220904.aiff Error: Couldn't set audio converter property ('!dat') $ afconvert -f m4af -d aacl -b 128000 20100905220904.aiff $ afconvert -f m4af -d alac -b 128000 20100905220904.aiff Error: Couldn't set audio converter property ('who?') $ afconvert -f m4af -d alac -b 48000 20100905220904.aiff Error: Couldn't set audio converter property ('who?') $ afconvert -f m4af -d alac 20100905220904.aiff
- 出来上がったファイルをFinderの情報を見るで確認してみると...
- aach
- aacl
- alac
なるほど!
- 目指すデータフォーマットはaachだ!(HE-AAC)
- MPEG4 Low Delay AAC = エンコード時間を大幅に短縮して、双方向通信で違和感なく会話できる。(上記で「種類」見出しの さらに、さらに、さらにで調べたもの)
- Apple Lossless = 劣化なしの可逆圧縮だけど、aiffの半分くらいになる。これもAAC派生の技術だったとは...。iTunesではApple Losslessエンコーダとして独立している。
afconvert -f m4af -d aach -b 48000 20100905220904.aiff
- アップルスクリプトにまとめてみた。
property ffmpeg_path : "/opt/local/bin/ffmpeg"
property afconvert_path : "/usr/bin/afconvert"
property tmp_path : "/tmp/_flv_to_itunes/"
try
do shell script "mkdir " & tmp_path
end try
tell application "Finder"
set select_list to selection
end tell
repeat with f in select_list
set file_path to (f as text)'s POSIX path
set file_name to do shell script "n=" & file_path's quoted form & ";echo \"${n##*/}\""
set fn_no_ext to do shell script "n=" & file_name's quoted form & ";echo \"${n%.*}\""
set aiff_path to tmp_path & fn_no_ext & ".aiff"
set m4a_path to tmp_path & fn_no_ext & ".m4a"
set convert_path to POSIX file m4a_path
do shell script ffmpeg_path & " -y -i " & file_path's quoted form & " " & aiff_path's quoted form
do shell script afconvert_path & " -f m4af -d aach -b 48000 " & aiff_path's quoted form & " " & m4a_path's quoted form
tell application "iTunes" to add convert_path
do shell script "rm " & aiff_path's quoted form
do shell script "rm " & m4a_path's quoted form
end repeat