Media Player のFrameworkを使ってAppleMusic連携のアプリを作りたい。
しかしこんなんドキュメント見ても分からんだろっていう落とし穴があったりするので、いろいろ試してわかった知見を書く。
曲固有のID
単一の曲を表すMPMediaItemにはいろいろとプロパティがあるが、曲を区別するためのIDは次の二つがある。似ているようで役割が違う。
persistentID
自分のライブラリ内の固有のID(と思われる)
このIDがあれば、MPMediaItemは取得できる。
次のように、MPMediaPropertyPredicate
,MPMediaQuery
を使ってpersistentIDからMPMediaItemを取得する。
MPMediaItemPropertyPersistentID
というプロパティを使って絞り込もう。
private func findMPMediaItem(persistentIDString: String) -> MPMediaItem? {
let predicate = MPMediaPropertyPredicate(value: persistentIDString, forProperty: MPMediaItemPropertyPersistentID)
let songQuery = MPMediaQuery()
songQuery.addFilterPredicate(predicate)
if let items = songQuery.items {
return items.first
} else {
return nil
}
}
playbackStoreID
こちらはApple MusicやiTunes全体で固有のID(と思われる)
iTuneSearchAPIを例にすると、このようにAPIを叩けば曲の情報が取得できる。
$ curl "https://itunes.apple.com/lookup?id=1513201190" | jq
また、Apple Music APIでも曲の情報を取得できるが、こちらはtokenが必要だったりするので省略する。
ただしこのIDからMPMediaItemは取得できない!!😩
↑わたしが調べる限り2020年8月時点では不可能っぽい。使えるようになったら教えてほしい。🙏
MPMediaItemPropertyPlaybackStoreID
といういかにも使えそうなプロパティはあるのだが、使うと次のようなエラーで怒られるぞ。stackoverflowにある通り、現状は取得する手段がない。
"MPMediaPropertyPredicate cannot filter using the playbackStoreID property"
曲を再生したい場合は?
persistentIDを使う場合
曲を再生する時はMPMusicPlayerControllerのこれをつかう
open func setQueue(with itemCollection: MPMediaItemCollection)
次のようにMPMediaItemからMPMediaItemCollectionを作って、セットすれば再生できる
//itemsは↑みたいな方法で取得しとく
let mediaItemCollection = MPMediaItemCollection(items: items)
let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
musicPlayer.setQueue(with: mediaItemCollection)
playbackStoreIDを使う場合
こちらの場合、MPMediaItemは取得できない
しかし曲の再生はできる。
MPMusicPlayerControllerのこれをつかう
open func setQueue(with storeIDs: [String])
次のように書けばok
let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
musicPlayer.setQueue(with: ["1513201190"])
まとめ
persistentID
は自分のライブラリ固有のIDで、MPMediaItemを取得できる。
playbackStoreID
はApple MusicやiTunes全体で固有のIDで、API利用して曲の情報を取得できる。
Apple Music APIを使ったアプリを作りたい時はplaybackStoreID
を使うと良さそう。
Swiftでネイティブアプリを作りたい時は、persistentID
とplaybackStoreID
どう使うか考えると良さそう。