動画再生中にイヤホンの抜き差しが発生した時に検知する必要があったので
Extensionを作成しました。
検知に利用するのは**「AVAudioSession」と「Notification」**です。
NotificationでAVAudioSessionの値の監視を行います。
また、今回はRxのExtensionとして実装しましたが、普通にNotificationの実装をすればRxを使わなくても実装可能です。
ソースコード
Rx+AVAudioSession.swift
import Foundation
import RxSwift
import AVFoundation
extension Reactive {
// イヤホン(Bluetooth含む)の抜き差しをチェック
var isConnectedHeadPhone: Observable<Bool> {
AVAudioSession.sharedInstance()
return NotificationCenter.default.rx.notification(.AVAudioSessionRouteChange,
object: nil)
.map { didChage in
guard let desc = didChage.userInfo?[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription
else { return false }
let outputs = desc.outputs
for component in outputs {
if component.portType == AVAudioSessionPortHeadphones ||
component.portType == AVAudioSessionPortBluetoothA2DP ||
component.portType == AVAudioSessionPortBluetoothLE ||
component.portType == AVAudioSessionPortBluetoothHFP {
// イヤホン(Bluetooth含む)が抜かれた
return false
}
}
// イヤホン(Bluetooth含む)が差された
return true
}
}
}
Usage
ViewController.swift
import UIKit
import RxSwift
final class ViewController: UIViewController {
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
rx.isConnectedHeadPhone
.subscribe { isConnected in
guard let isConnected = isConnected.element else { return }
if isConnected {
// イヤホン(Bluetooth含む)が差された時の処理
} else {
// イヤホン(Bluetooth含む)が差された時の処理
}
}
.disposed(by: disposeBag)
}
}
Rxを使わない時は
Rxを使わない場合はこんな感じでいけると思います。
ViewController.swift
import UIKit
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
AVAudioSession.sharedInstance()
NotificationCenter.default.addObserver(self,
selector: #selector(self.didAudioSessionRouteChanged(_:)),
name: .AVAudioSessionRouteChange, object: nil)
}
@objc
private func didAudioSessionRouteChanged(_ notification: Notification) {
guard let desc = notification.userInfo?[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription
else { return }
let outputs = desc.outputs
for component in outputs {
if component.portType == AVAudioSessionPortHeadphones ||
component.portType == AVAudioSessionPortBluetoothA2DP ||
component.portType == AVAudioSessionPortBluetoothLE ||
component.portType == AVAudioSessionPortBluetoothHFP {
// イヤホン(Bluetooth含む)が差された時の処理
return
}
}
// イヤホン(Bluetooth含む)が差された時の処理
}
}
まとめ
イヤホン(Bluetooth)の抜き差しの判定が思っていたよりも簡単にできましたね。
これまで動画関連は深く踏み込んで触っていなかったので、いろいろ触ってみようと思います。
以上です。