[iOS][Swift]AVAudioPlayerを使う(複数の曲をあつかう)

AVAudioPlayerを使う例として
[iOS][Swift]ミュージックライブラリにアクセスして音楽を再生する(AVAudioPlayer使用) | nackpan Blog
[iOS][Swift]AVAudioPlayerを使う(再生速度の変更、複数のプレイヤー) | nackpan Blog
という記事を書きました。

今回は、AVAudioPlayerで複数のアイテムを扱います。
複数のアイテムを選択したのち、順次再生されるようにしたいと思います。


サンプルプロジェクトを作りました
(プロジェクト一式はGitHubにあります nackpan/AVAudioPlayerDemo3
ss2015-09-23 16 18 32

「選曲」ボタンで、複数の曲を選択し再生を開始します。
「再生・一時停止」ボタンで、再生と一時停止を切り替えます。
「<<」ボタンで前の曲に移ります。
「>>」ボタンで次の曲に移ります。
Message Labelに現在の曲情報が表示されます。

iOSシミュレータでは動作しないので、実機を用いてください。

プレイヤークラスの作成

前回までのサンプルでは、ViewController.swiftに全部書いていました。
しかし、ViewController.swiftになにもかも書いていくと、どこが何の役割なのかがわかりづらくなってしまいます。
なので、プレイヤークラスを別に作成しました。
今回のサンプルでは、SimplePlayerクラスと名付けました。

複数のアイテムを扱う

プレイヤーが、MPMediaItemの配列をもち、currentIndexで現在のindexを示すこととします。
アイテム末尾到達、「>>」ボタンタップ、「<<」ボタンタップがおこなわれると、currentIndexを変更します。
別のアイテムになるたびにプレイヤーに新アイテムをセットします。

/// プレイヤーにitemをセットして更新
func updatePlayer() {
    let item = mediaItems[currentIndex]
    // MPMediaItemのassetURLからプレイヤーを作成する
    if let url: NSURL = item.assetURL {
        do {
            // itemのassetURLからプレイヤーを作成する
            audioPlayer = try AVAudioPlayer(contentsOfURL: url)
            
            // audioPlayerのdelegate先をselfに設定
            // (アイテム末尾に到達したときに呼ばれるaudioPlayerDidFinishPlaying()を受ける)
            audioPlayer?.delegate = self
            
        } catch  {
            // エラー発生してプレイヤー作成失敗
            audioPlayer = nil
            
            // 「再生中」ではない
            nowPlaying = false
            
            // 戻る
            return
            
        }
        
    } else {
        
        audioPlayer = nil

        // 「再生中」ではない
        nowPlaying = false
    }
}
urlがnilのアイテムもアイテム配列に含めている

今回のサンプルでは、mediaItemsにurlがnilのMPMediaItemも含めています。
その場合のアイテム再生時には、「urlがnilなので再生できない」旨のメッセージを表示して、そこで再生を停止しています。
(実際のアプリでは、事前にチェックしてurlがnilのものを取り除いておく、あるいは再生中にnilのものがあれば飛ばすなどの処理のほうがよさそうですが…)

アイテム末尾到達を知る

AVAudioPlayerDelegateのaudioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) メソッドで知ることができます。

プレイヤーをAVAudioPlayerDelegateプロトコルに準拠させます

class SimplePlayer: NSObject, AVAudioPlayerDelegate {

アイテム末尾に到達した際にaudioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool)が呼ばれるので、そこで必要な処理を行います。
このサンプルでは、
・範囲内であればindexを進めて次の曲の再生に移る
・すべてのアイテムの再生が終わったならそこで再生を終えて、indexを0に戻して最初のアイテム情報を表示する
処理を行っています。

    /// アイテム末尾に到達したときに呼ばれる
    func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
        
        
        // 最後の曲の場合は終了。そうでないなら次の曲へ
        if currentIndex >= mediaItems.count - 1{
            
            // 終了
            
            // indexを0に戻す
            currentIndex = 0
            
            // 新たなitemでプレイヤー作成
            updatePlayer()
            
            // ポーズする
            pause()
            
            
            return
            
        } else {
            
            // 次の曲へ。
            nextItem()
            
            
        }
    }

サンプルプロジェクトのGitHub
nackpan/AVAudioPlayerDemo3

関連

[iOS][Swift]ミュージックライブラリにアクセスして音楽を再生する(MPMusicPlayerController使用) | nackpan Blog
[iOS][Swift]MPMediaQueryを使って曲を絞り込む | nackpan Blog
[iOS][Swift]ミュージックライブラリにアクセスして音楽を再生する(AVAudioPlayer使用) | nackpan Blog
[iOS][Swift]AVAudioPlayerを使う(再生速度の変更、複数のプレイヤー) | nackpan Blog

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください