2012年7月11日水曜日

iPod LibraryからのAVAudioPlayerによる再生

かなりハマって調べたのでここにまとめておく。

まず、iPhone/iPodでの音楽ファイルは、アプリケーションのリソースとして持ち込むか、iPodのライブラリにある物が扱える。
が、iPodのライブラリ内の曲は基本的に「AVPlayer」か「MediaPlayer」でしか再生出来ない。
しかし、これらのコンポーネントは非常に自由度が低いので、AVAudioPlayerなどで再生したくなったわけだ。

まず、iPodライブラリからMPMediaItemとして取得した音楽ファイルを、AVAudioPlayerで開こうとしても容赦なくエラーでぬるぽとなる。(実際にはinitに対してnilを返してくる)
これを無理矢理開くには、一旦iPodライブラリからファイルをエクスポートし、ローカルのリソースとして扱わなければならない。
このあたりの経緯は以下のwebpageにて解説されている。感謝。

iPodライブラリからのファイル書き出し その1
http://objective-audio.jp/2010/08/ipod.html
iPodライブラリからのファイル書き出し その2
http://objective-audio.jp/2010/08/ipod-1.html
ついでに参考:http://unlimapps.com/?p=41

簡単にまとめておくと、"AVAssetExportSession"を使ってiPodLibraryからファイルをexportする事になる。
しかし、素直にpresetNameを"AVAssetExportPresetAppleM4A"にした場合、mp3がexportできない。
なので、AVAssetTrackを取り出し、そこからAudioStreamBasicDescriptionを取得して、その中のファイルタイプを利用する。
presetNameはAVAssetExportPresetPassthroughを使用する。


書き出すあたりまでは上記でサンプルソースまであるので難なく行ける・・・と思ったがそうはいかない。
二つ目の記事で書かれているように、このコードはiOS5.1以降ではうまく動かない。
(記事にはiOS4.2以降では動かないかも?とある)

というわけで探しまくった結果、以下の記事を発見。


get error code -11843 while exporting mp3 file in ipod library since iOS 5.1
http://stackoverflow.com/questions/9653241/get-error-code-11843-while-exporting-mp3-file-in-ipod-library-since-ios-5-1


まさに、5.0までは動いていたのに5.1ではダメになった。ナンデ?という話。
この人は自力でworkaroundを見つけ出してくれていた。ワザマエ!


つまり、AVAssetExportSessionに設定するoutputURLの拡張子として、mp3の場合は"mov"にしなければ失敗する、ということ。

おそらくAVAssetExportSessionの内部実装でエラーのチェックが強化されたのだろう。
outputFileTypeとして"com.apple.quicktime-movie"を設定している以上、拡張子はmovで無ければならないという拡張子原理主義者がAppleに入社したとかそんな感じではないだろうか。めんどくせぇ。爆発四散するべき。

というわけで、上記の情報を元にファイルを書き出し、拡張子をmovからmp3に変えたファイルをAVAudioPlayerに食わせたところ、無事に再生できました。
なおiOSは5.1.1です。