Pause/Resume Audio Session on interruption

This commit is contained in:
Marc Rousavy 2021-03-26 16:10:12 +01:00
parent 8066f3fb53
commit 56c67f25c7

View File

@ -49,12 +49,19 @@ final class CameraView: UIView {
selector: #selector(sessionRuntimeError), selector: #selector(sessionRuntimeError),
name: .AVCaptureSessionRuntimeError, name: .AVCaptureSessionRuntimeError,
object: captureSession) object: captureSession)
NotificationCenter.default.addObserver(self,
selector: #selector(audioSessionInterrupted),
name: AVAudioSession.interruptionNotification,
object: AVAudioSession.sharedInstance)
} }
deinit { deinit {
NotificationCenter.default.removeObserver(self, NotificationCenter.default.removeObserver(self,
name: .AVCaptureSessionRuntimeError, name: .AVCaptureSessionRuntimeError,
object: captureSession) object: captureSession)
NotificationCenter.default.removeObserver(self,
name: AVAudioSession.interruptionNotification,
object: AVAudioSession.sharedInstance)
} }
@available(*, unavailable) @available(*, unavailable)
@ -99,7 +106,7 @@ final class CameraView: UIView {
ReactLogger.log(level: .info, message: "Starting Session...") ReactLogger.log(level: .info, message: "Starting Session...")
self.configureAudioSession() self.configureAudioSession()
self.captureSession.startRunning() self.captureSession.startRunning()
ReactLogger.log(level: .info, message: "Starting Session!") ReactLogger.log(level: .info, message: "Started Session!")
} else { } else {
ReactLogger.log(level: .info, message: "Stopping Session...") ReactLogger.log(level: .info, message: "Stopping Session...")
self.captureSession.stopRunning() self.captureSession.stopRunning()
@ -205,6 +212,33 @@ final class CameraView: UIView {
} }
invokeOnError(.unknown(message: error.description), cause: error as NSError) invokeOnError(.unknown(message: error.description), cause: error as NSError)
} }
@objc
func audioSessionInterrupted(notification: Notification) {
ReactLogger.log(level: .error, message: "The Audio Session was interrupted!")
guard let userInfo = notification.userInfo,
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
switch type {
case .began:
// TODO: Should we also disable the camera here? I think it will throw a runtime error
// disable audio session
try? AVAudioSession.sharedInstance().setActive(false)
break
case .ended:
guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
// restart audio session because interruption is over
configureAudioSession()
} else {
ReactLogger.log(level: .error, message: "Cannot resume interrupted Audio Session!")
}
break
}
}
internal final func setTorchMode(_ torchMode: String) { internal final func setTorchMode(_ torchMode: String) {
guard let device = videoDeviceInput?.device else { guard let device = videoDeviceInput?.device else {
@ -293,6 +327,7 @@ final class CameraView: UIView {
// allow background music playback // allow background music playback
try audioSession.setCategory(AVAudioSession.Category.playAndRecord, options: [.mixWithOthers, .allowBluetoothA2DP, .defaultToSpeaker]) try audioSession.setCategory(AVAudioSession.Category.playAndRecord, options: [.mixWithOthers, .allowBluetoothA2DP, .defaultToSpeaker])
} }
// TODO: Use https://developer.apple.com/documentation/avfaudio/avaudiosession/3726094-setprefersnointerruptionsfromsys
audioSession.trySetAllowHaptics(true) audioSession.trySetAllowHaptics(true)
// activate current audio session because camera is active // activate current audio session because camera is active
try audioSession.setActive(true) try audioSession.setActive(true)