[iOS 10.3] MPMusicPlayerApplicationController を使用してプレイヤーの再生キューを編集する

2017.03.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんばんは。モバイルアプリサービス部の平屋です。

以下の前回の記事に引き続き、iOS 10.3 の Media Player framework の新機能を紹介していきます。

[iOS 10.3] MPMusicPlayerController の append および prepend メソッドについて

本記事では、iOS 10.3 で Media Player framework に新規追加されたクラスを扱います。

検証環境

  • macOS Sierra 10.12.3(16D32)
  • Xcode Version 8.3 beta 4 (8W143q)
  • iPhone 7 iOS 10.3 beta 5 (14E5269a)

iOS 10.3 で Media Player framework に新規追加されたクラス

iOS 10.3 で Media Player framework に以下の 3 つのクラスが新規追加されました

  • MPMusicPlayerApplicationController
  • MPMusicPlayerControllerMutableQueue
  • MPMusicPlayerControllerQueue

MPMusicPlayerApplicationController

こちらの記事で紹介した MPMusicPlayerController のサブクラスです。MPMusicPlayerController と同様に、曲の再生/停止などの機能を利用できます。

MPMusicPlayerApplicationController で定義されているメソッドは以下の 1 つだけです。プレイヤーの再生キューへ曲を追加したり、再生キュー内の曲を削除したりすることができます。

func performQueueTransaction(_ queueTransaction: @escaping (MPMusicPlayerControllerMutableQueue) -> Void, 
                            completionHandler: @escaping (MPMusicPlayerControllerQueue, Error?) -> Void)

動作を確認してみたところ、MPMusicPlayerApplicationController はアプリ専用のプレイヤーのようです。(名前の通り)

基本的な動作は、MPMusicPlayerController の applicationMusicPlayer() メソッドで返される MPMusicPlayerController インスタンスと同様だと思います。

MPMusicPlayerApplicationController のプレイヤー機能はアプリがフォアグラウンドにある場合のみ動作し、アプリがバックグラウンドに移行すると再生が止まります。また、iOS 標準のミュージックアプリで再生中のキューを操作することもできません。

MPMusicPlayerControllerQueue と MPMusicPlayerControllerMutableQueue

この 2 つのクラスはプレイヤーの再生キューを表すクラスです。

MPMusicPlayerApplicationController の performQueueTransaction(_:completionHandler:) メソッドのブロックの引数として渡されます。

MPMusicPlayerControllerMutableQueue は MPMusicPlayerControllerQueue のサブクラスで、insert(_:after:) および removeItem(_:) メソッドを使用して再生キューを編集できます。

再生キューに曲を追加する

performQueueTransaction(_:completionHandler:) メソッドを使用して再生キューに曲を追加する例を紹介します。

1 つめのブロックで再生キューを編集する処理を行います。 2 つめのブロックで編集結果を取得できます。

曲を追加するには MPMusicPlayerControllerMutableQueue の insert(_:after:) メソッドを使用します。

このメソッドの 1 つ目の引数には Descriptor オブジェクトを指定しますが、MPMediaItemCollection から作成した Descriptor を指定すると期待通りに動きませんでした。(iOS 10.3 beta 5 で確認。こちらの記事で紹介した append/prepend メソッドと同様。)

MPMediaQuery から作成した Descriptor を指定すると期待通りに動きました。

let musicPlayerApplicationController = MPMusicPlayerController.applicationQueuePlayer()

// ...

func insertQueue(mediaItemCollection: MPMediaItemCollection) {
    musicPlayerApplicationController.performQueueTransaction({ mutableQueue in
        // 1 つめのブロックで再生キューを編集する

        // Descriptor を作成
        let predicate = MPMediaPropertyPredicate(value: mediaItemCollection.representativeItem!.persistentID,
                                                 forProperty: MPMediaItemPropertyPersistentID)
        let query = MPMediaQuery(filterPredicates: [predicate])
        let descriptor = MPMusicPlayerMediaItemQueueDescriptor(query: query)

        // insert する
        mutableQueue.insert(descriptor,
                            after: mutableQueue.items.last) // insert 位置を指定

    }, completionHandler: {queue, error in
        // 2 つめのブロックで編集結果を取得できる
        print("queue.items.count:", queue.items.count)
    })
}

再生キュー内の曲を削除する

再生キュー内の曲を削除する場合も、performQueueTransaction(_:completionHandler:) メソッドを使用します。

曲を追加するには MPMusicPlayerControllerMutableQueue の removeItem(_:) メソッドを使用します。

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        musicPlayerApplicationController.performQueueTransaction({ mutableQueue in
            // 1 つめのブロックで再生キューを編集する
            mutableQueue.removeItem(self.mediaItems[indexPath.row])
        }, completionHandler: {queue, error in
            // 2 つめのブロックで編集結果を取得できる
            self.mediaItems = queue.items
            tableView.deleteRows(at: [indexPath], with: .fade)
        })
    }
}

さいごに

本記事では、iOS 10.3 で Media Player framework に新規追加されたクラスを紹介しました。

MPMusicPlayerApplicationController のプレイヤー機能は、アプリがフォアグラウンドにある場合のみ動作するので、用途はかなり限られる気がします。

個人的にシステムミュージックプレイヤー (iOS 端末全体で共有されるプレイヤー) の再生キューを取得する機能がほしいかなと思いました!

今回紹介したサンプルのソースコードは以下のリポジトリで公開してますので参考にしてみてください。

参考資料