GetWild退勤的なセンサーアプリを簡単に作れるフレームワークを作ったのでiPhoneに歯痛を心配されたり色々する
で得た知見シリーズ
(PDF)iPodライブラリアクセスプログラミングガイド
https://developer.apple.com/jp/documentation/iPodLibraryAccess_Guide.pdf
(PDF)Core Audioの概要
https://developer.apple.com/jp/documentation/CoreAudioOverview.pdf
基本的にはこれが出発地点になるドキュメント。
MPMediaQuery
端末のライブラリからMPMediaItem(アルバムや曲や動画)を検索するためのクエリークラス。MPMediaPropertyPredicateで条件を表現して絞り込む。MPMediaPredicateComparisonはEqualTo|Containes
internal func search(containsWord: String) -> [MPMediaItemCollection] {
let query = MPMediaQuery.albumsQuery()
let predicate = MPMediaPropertyPredicate(value: containsWord, forProperty: MPMediaItemPropertyTitle, comparisonType: MPMediaPredicateComparison.Contains)
query.addFilterPredicate(predicate)
return query.collections!
}
ドキュメントにも書いてあるが、ライブラリアクセスにはこのMediaQueryを使うか、MediaPickerを使う事になる。MediaPickerで用が足りるのであればMediaPickerの方がクラウド上にあるか否か、DRMといった面倒を見ずに済むので楽。UIImagePickerControllerと立ち位置が似てる。MPMediaItem.persistentID(MPMediaEntityPersistentID)はUint64なので結構大きい。意識しておかないとハマる事はあるかもしれない。
後述するがiCloud上にあるMPMediaItemやDRMで保護された曲はそのままだと再生出来ないため、要件によってはMPMediaItemPropertyIsCloudItem(iOS6.0以降)とMPMediaItemPropertyHasProtectedAsset(iOS9.2以降)で、フィルタリングして検索する必要がある。また、その曲がiCloud上にあるか否かについてはMPMediaItem.cloudItem(iOS8.0以降)、DRMについてはMPMediaItem.protectedAsset(iOS9.2以降)で取得する事が出来る。
AVAudioPlayer
MPMediaItemを再生する。Linked Frameworks and LibrariesにMediaPlayer.frameworkを追加しimportしておく必要がある。
internal func play(item: MPMediaItem) {
let url: NSURL = item.valueForProperty(MPMediaItemPropertyAssetURL) as! NSURL
do {
self.audio = try AVAudioPlayer(contentsOfURL: url, fileTypeHint: nil)
self.audio?.delegate = self
self.audio!.play()
} catch {
print(error)
}
}
playを維持するためにはAVAudioPlayerのインスタンスをplay()実行後も保持しておく必要がある。playの終了を検知したい場合はdelegateにAVAudioPlayerDelegateを設定しておく必要がある。
またDRMで保護された曲やiCloud上の曲の場合は
item.valueForProperty(MPMediaItemPropertyAssetURL)
の時点で不思議なNullの力によって死ぬことになる。
MPMusicPlayerControllerで用が足りるのであればMPMusicPlayerControllerの方が部品が最初から揃っているし楽。