Swift:AVAudioSession アプリのバックグラウンドで音楽を再生する

SQN で音楽の再生をしながらゲームをプレイしたいとの要望があったので、バージョン 1.2 で実装を行いました。
今回はそのときのコードの一部を抜粋し、アプリのバックグラウンドで音楽を再生する方法を説明したいと思います。

アプリのバックグラウンドで音楽を再生する

まず、アプリから Apple の MusicApp で音楽が再生されているかどうかを MPMusicPlaybackState を使用し判定します。

let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer()
let playbackState: MPMusicPlaybackState = musicPlayer.playbackState

if playbackState == MPMusicPlaybackState.Playing {
    println("Music is playing")
} else {
    println("Music is not playing")
}

上記のコードを効果音を再生する関数内で判定します。効果音の再生には AVAudioPlayer を使用します。

func soundPlay(fileName: String, type: String) {
    println("func soundPlay")
        
    let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer()
    let playbackState: MPMusicPlaybackState = musicPlayer.playbackState
    if playbackState == MPMusicPlaybackState.Playing {
        println("Music is playing")
        
    } else {
        println("Music is not playing")
        
        let sound_data = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(fileName, ofType: type)!)
        audioPlayer = AVAudioPlayer(contentsOfURL: sound_data, error: nil)
        audioPlayer.play()
    }
}

音楽を再生中に mp3 や wav 等の効果音を再生すると、音楽がストップした後、効果音が再生されてしまいます。
soudPlay を使用することで、音楽が再生中であれば soundPlay 内の判定で音楽はストップしなくなりますが、その場合効果音は再生されません。

音楽を再生しながら効果音を再生(多重再生)したい場合は次項で説明したいと思います。

音楽を再生しながらアプリの効果音を再生する

多重再生したい場合は音声ファイルが caf 形式でなければいけません。以下は bgm.mp3 を bgm.caf へ変換する方法です。

mp3 を caf に変換する

ターミナルから mp3 等の音声データがある階層まで移動し、以下のコマンドを実行すれば caf ファイルが作成されます。

/usr/bin/afconvert -f caff -d ima4 bgm.mp3 bgm.caf

AVAudioSession

AVAudioSession クラスを使用することで音楽の再生をコントロールすることが可能です。

デフォルトでは setCategory が AVAudioSessionCategorySoloAmbient となっているため、オーディオ再生中にアプリを起動するとオーディオが停止してしまいます。

ViewController の viewDidLoad 等に以下のコードを記述します。

let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
audioSession.setCategory(AVAudioSessionCategoryAmbient, error: nil)
audioSession.setActive(true, error: nil)

AVAudioSession のカテゴリ一覧

AVAudioSessionCategoryAmbient 以外にも以下のような指定が可能です。

// 別アプリでオーディオ再生中にアプリを起動しても停止しない
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil) 

// 別アプリでオーディオ再生中にアプリを起動するとオーディオが停止(デフォルト設定)
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient, error: nil) 

// 音楽再生用のアプリで利用
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil) 

// 入力のみ。録音用に利用
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryRecord, error: nil) 

// チャット用にマイク入力と音声出力を行うときに利用
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil) 

// 再生や録音ではなくオフラインオーディオ処理を行う際に利用
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAudioProcessing, error: nil) 

// USBオーディオインターフェースやHDMI等、外部出力を接続時にヘッドホンへ別系統の音を出力
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryMultiRoute, error: nil)

まとめ

最後に SystemSoundID と AVAudioPlayer の違いをまとめておきます。

 SystemSoundIDAVAudioPlayer
FrameworkAudioToolboxAVFoundation
対応フォーマット30秒以下の AIFF, CAF, WAVAIFF, CAF, MP3, AAC, M4A, MP4, WAV
音量調節ネットワーク通信時に音量調節不可設定可能
ループ不可可能
動作軽い立ち上がり時に若干遅延が発生する

この記事がみなさんのお役に立ちましたら、下記「Share it」よりブックマークやSNSで共有していただければ幸いです。

siro:chro 無料ゲーム SQN をリリースしました

img_sqn_00

sirochro 初の無料ゲームアプリ SQN をリリースしました。
記事:SQN: iOS 無料ゲームアプリ SQN - Sequential Numbers をリリース
ちょっとした時間に楽しめる完全無料のゲームなっていますので、是非ダウンロードして遊んでみてください。

↓SQN のダウンロードはこちらから

Related Contents

Pickup Contents