提问人:p_dip 提问时间:1/30/2023 更新时间:1/30/2023 访问量:316
Swift - 录制视频时如何处理音频会话中断
Swift - How to handle audio session interruptions while recording video
问:
我正在尝试修复我的 iOS 应用程序的行为。应用程序中有一个相机插件,允许用户录制视频和拍照。录制视频时,如果发生来电或闹钟声等中断,相机会发热并且不会保存视频。我想处理这种情况,中断视频并保存它或在继续录制时删除音频。 但是,在中断开始并识别事件后,有关已录制视频的变量将被重新初始化,从而导致应用程序不保存任何内容。
任何帮助将不胜感激。
†
var captureSession: AVCaptureSession?
public func fileOutput(\_: AVCaptureFileOutput, didStartRecordingTo \_: URL, from \_: \[AVCaptureConnection\]) {
NotificationCenter.default.addObserver(self, selector: #selector(sessionInterruptionBegin), name: .AVCaptureSessionWasInterrupted, object: captureSession)
NotificationCenter.default.addObserver(self, selector: #selector(sessionInterruptionEnd),name: .AVCaptureSessionInterruptionEnded, object: captureSession)
NotificationCenter.default.addObserver(self, selector: #selector(audioSessionInterrupted), name: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance)
print("STO PASSANDO DA AVCaptureFileOutputRecordingDelegate")
captureSession?.beginConfiguration()
if flashMode != .off {
_updateIlluminationMode(flashMode)
}
captureSession?.commitConfiguration() //at this point captureSession starts collecting data about the video
}
extension CameraManager {
@objc func sessionInterruptionBegin(notification: Notification) {
print("Capture Session Interruption begin Notification!")
guard let reasonNumber = notification.userInfo?\ [AVCaptureSessionInterruptionReasonKey\] as? NSNumber else {
return
}
let reason = AVCaptureSession.InterruptionReason(rawValue: reasonNumber.intValue)
switch reason {
case .audioDeviceInUseByAnotherClient:
removeAudioInput()
default:
break
}
}
func addAudioInput() throws {
if audioDeviceInput != nil {
return
}
removeAudioInput()
print("Adding audio input...")
captureSession?.beginConfiguration()
guard let audioDevice = AVCaptureDevice.default(for: .audio) else {
throw NSError()
}
audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice)
guard captureSession!.canAddInput(audioDeviceInput!) else {
throw NSError()
}
captureSession?.addInput(audioDeviceInput!)
captureSession?.automaticallyConfiguresApplicationAudioSession = false
captureSession?.commitConfiguration()
}
func removeAudioInput() {
//when the code reaches this point audioDeviceInput is reinitialized so the audio session is not removed from the recording
//captureSession is not filled with the data about the video recorded
guard let audioInput = audioDeviceInput else {
return
}
captureSession?.beginConfiguration()
captureSession?.removeInput(audioInput)
audioDeviceInput = nil
captureSession?.commitConfiguration()
}
@objc func sessionInterruptionEnd(notification: Notification) {
print("Capture Session Interruption end Notification!")
guard let reasonNumber = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? NSNumber else {
return
}
let reason = AVCaptureSession.InterruptionReason(rawValue: reasonNumber.intValue)
switch reason {
case .audioDeviceInUseByAnotherClient:
// add audio again because we removed it when we received the interruption.
configureAudioSession()
default:
// don't do anything, iOS will automatically resume session
break
}
}
@objc func audioSessionInterrupted(notification: Notification) {
print("Audio Session Interruption Notification!")
guard let userInfo = notification.userInfo,
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
switch type {
case .began:
print("The Audio Session was interrupted!")
removeAudioInput()
case .ended:
print("The Audio Session interruption has ended.")
guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
print("Resuming interrupted Audio Session...")
// restart audio session because interruption is over
configureAudioSession()
} else {
print("Cannot resume interrupted Audio Session!")
}
@unknown default: ()
}
}
func configureAudioSession() {
let start = DispatchTime.now()
do {
try self.addAudioInput()
let audioSession = AVAudioSession.sharedInstance()
if audioSession.category != .playAndRecord {
// allow background music playback
try audioSession.setCategory(AVAudioSession.Category.playAndRecord, options: [.mixWithOthers, .allowBluetoothA2DP, .defaultToSpeaker])
}
// activate current audio session because camera is active
try audioSession.setActive(true)
} catch let error as NSError {
switch error.code {
case 561_017_449:
print(error.description)
default:
print(error.description)
}
self.removeAudioInput()
}
let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
print("Configured Audio session in \(Double(nanoTime) / 1_000_000)ms!")
}
}
答: 暂无答案
评论