iOSでAVAudio周りがbluetooth機器から再生されない

Swift2での設定方法
リファレンスだけだと若干厳しい







現象


bluetoothヘッドセットをiOSと接続
AVAudioPlayer.play()で音声再生してみるとヘッドセットからでなくiOS端末本体から再生されてしまう
その他の音声再生全般がiOS本体から再生される
youtubeとかは普通に再生する


AVAudio周りの設定方法


結論から言うと正しく設定すればいいんだけど情報が少なくてなかなか厳しかった

var audioPlayer: AVAudioPlayer!

/** 初期化処理 */
private func initialize() {
 
 // 音声データの読み込み
     do {
         // サウンドデータの読み込み
         let audioPath = NSURL(
          fileURLWithPath: NSBundle.mainBundle().pathForResource("se", ofType: "wav")!)
         // AVAudioPlayerを作成。もし何かの事情で作成できなかったらエラーがthrowされる
         audioPlayer = try AVAudioPlayer(contentsOfURL: errorAudioPath)
         
         // イベントを通知したいUIViewControllerをdelegateに登録
         // delegateの登録するならAVAudioPlayerDelegateプロトコルの継承が必要
         audioPlayer.delegate = self
         
     }
     catch let error as NSError {
         print("AVAudioPlayer error:" + error.description)
     }
    
    // オーディオ割り込みが発生した時にaudioSessionInterruptionNotificationメソッドを呼び出す
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: #selector(audioSessionInterruptionNotification(_:)),
        name: AVAudioSessionInterruptionNotification,
        object: nil)
    
    // オーディオ周りの認証要求
    AVAudioSession.sharedInstance().requestRecordPermission {_ in
        print("permission 要求")
        
        do {
            
            // bluetooth機器として設定
            try AVAudioSession.sharedInstance().setCategory(
             AVAudioSessionCategoryPlayAndRecord, 
             withOptions:AVAudioSessionCategoryOptions.AllowBluetooth )
            
            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.None)
            
            try AVAudioSession.sharedInstance().setActive(true)
            
        } catch let error as NSError {
            Common.writeDeviceLog(error.description)
        }
        
    }
}


/** オーディオ周りの割り込み */
func audioSessionInterruptionNotification(notification: NSNotification?)  {
    switch notification?.userInfo![AVAudioSessionInterruptionTypeKey] as! UInt {
    case AVAudioSessionInterruptionType.Began.rawValue:
        print("割り込み")
        break
    default:
        print("audioSessionInterruptionNotification")
        break
        
    }
}

/// 音声再生
func playSound() {
    audioPlayer.prepareToPlay()
    audioPlayer.play()
}

/// 音声再生が完了した時に呼ばれる
/// デリゲートメソッド AVAudioPlayerDelegate
func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
    
}



setCategoryのカテゴリ一覧


/*  Use this category for background sounds such as rain, car engine noise, etc.  
 Mixes with other music. */
public let AVAudioSessionCategoryAmbient: String

/*  Use this category for background sounds.  Other music will stop playing. */
public let AVAudioSessionCategorySoloAmbient: String

/* Use this category for music tracks.*/
public let AVAudioSessionCategoryPlayback: String

/*  Use this category when recording audio. */
public let AVAudioSessionCategoryRecord: String

/*  Use this category when recording and playing back audio. */
public let AVAudioSessionCategoryPlayAndRecord: String

/*  Use this category when using a hardware codec or signal processor while
 not playing or recording audio. */
public let AVAudioSessionCategoryAudioProcessing: String


setCategoryのオプション一覧


/* MixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord,
         AVAudioSessionCategoryPlayback, and  AVAudioSessionCategoryMultiRoute */
    public static var MixWithOthers: AVAudioSessionCategoryOptions { get }

    /* DuckOthers is only valid with AVAudioSessionCategoryPlayAndRecord,
         AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
    public static var DuckOthers: AVAudioSessionCategoryOptions { get }

    /* AllowBluetooth is only valid with AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord */
    public static var AllowBluetooth: AVAudioSessionCategoryOptions { get }

    /* DefaultToSpeaker is only valid with AVAudioSessionCategoryPlayAndRecord */
    public static var DefaultToSpeaker: AVAudioSessionCategoryOptions { get }

    /* InterruptSpokenAudioAndMixWithOthers is only valid with AVAudioSessionCategoryPlayAndRecord, AVAudioSessionCategoryPlayback, and AVAudioSessionCategoryMultiRoute */
    @available(iOS 9.0, *)
    public static var InterruptSpokenAudioAndMixWithOthers: AVAudioSessionCategoryOptions { get }

オプションによっては設定できるカテゴリに制限があります


2016年10月6日木曜日