IOS: не работает AVAudioSession
Я пытаюсь использовать AVAudioSession, но он бросает эту ошибку времени выполнения: [avas] AVAudioSessionPortImpl.mm:56:ValidateRequiredFields:Unknown selected data source for Port Speaker (type Speaker)
: [avas] AVAudioSessionPortImpl.mm:56:ValidateRequiredFields:Unknown selected data source for Port Speaker (type Speaker)
. Если это помогает, я пытаюсь просто записывать аудио и контролировать текущие децибелы. Я установил категорию в AVAudioSessionCategoryRecord
и режим AVAudioSessionModeMeasurement
. вот код:
class ViewController: UIViewController {
let captureSession = AVCaptureSession()
var recording = false;
var ready = false;
let audioSession = AVAudioSession.sharedInstance()
@IBOutlet public weak var dBLabel: UILabel!
func alert(title: String, message: String = "", handler: ((UIAlertAction) -> Swift.Void)? = nil) -> Void {
var usedMessage: String
if(message.characters.count < 1) {
usedMessage = title;
} else {
usedMessage = message;
}
let alert = UIAlertController(title: title, message: usedMessage, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Default action"), style: .default, handler: handler))
self.present(alert, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
func checkPermission()
{
switch AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeAudio)
{
case .authorized:
NSLog("Authorized for Microphone Use")
case .notDetermined:
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler: { granted in
self.checkPermission()
})
case .denied:
let alert = UIAlertController(title: "Denied Access to Microphone", message: "You denied access to the microphone, please enable access in settings", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Go to Settings", style: .default, handler: { _ in
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
})
}
}))
alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "Cancel"), style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
case .restricted:
alert(title: "Restricted",message: "You cannot enable the microphone, so you cannot use the app", handler: { _ in
NSLog("The \"OK\" alert occured.")
})
}
}
@IBAction func toggleRecord(_ sender: UIButton) {
if(!ready)
{return}
NSLog("Toggled Recording")
recording = !recording;
if(recording)
{
sender.setImage(UIImage(named: "MicIconHighlighted.png"), for: .normal)
sender.setImage(UIImage(named: "MicIconHighlightedSelected.png"), for: .highlighted)
//captureSession.startRunning()
do
{
try audioSession.setActive(true)
} catch {
NSLog("Activating AudioSession Failed")
}
} else {
sender.setImage(UIImage(named: "MicIcon.png"), for: .normal)
sender.setImage(UIImage(named: "MicIconSelected.png"), for: .highlighted)
//captureSession.stopRunning()
do
{
try audioSession.setActive(false)
} catch {
NSLog("Deactivating AudioSession Failed")
}
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
checkPermission()
do
{
try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
} catch {
NSLog("Setting category on AudioSession failed")
}
do
{
try audioSession.setMode(AVAudioSessionModeMeasurement)
} catch {
NSLog("Setting mode on AudioSession failed")
}
do
{
try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
} catch {
NSLog("Failed Setting Audio Output Data Source")
}
//NSLog("debug info: \(audioSession.outputDataSources!.count)");
/*captureSession.beginConfiguration()
let audioDeviceInput: AVCaptureDeviceInput
let audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)
if(audioDevice != nil && (audioDevice?.isConnected)!) {
NSLog("Audio Device Name: \(audioDevice!.localizedName)")
} else {
NSLog("AVCapture Device default audio device failed or device not connected")
}
do {
audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice)
} catch {
alert(title: "Failed to create Capture Device",message: "Failed to create Capture Device", handler: nil)
return
}
if(captureSession.canAddInput(audioDeviceInput))
{
captureSession.addInput(audioDeviceInput)
} else {
alert(title: "Failed to Add Input",message: "Failed to add Audio Input Device", handler: nil)
}
let audioOutput = AVCaptureAudioDataOutput()
var audioRecorder = AVAudioRecorder()
audioRecorder.
var audioQueue = DispatchQueue(label: "audioqueue", attributes: .concurrent)
audioOutput.setSampleBufferDelegate(AudioOutputSampleBufferDelegate(vc: self), queue: audioQueue)
NSLog("Current Queue: \(audioOutput.sampleBufferCallbackQueue.description)")
if(captureSession.canAddOutput(audioOutput))
{
captureSession.addOutput(audioOutput)
captureSession.commitConfiguration()
} else {
alert(title: "Failed to Add Output",message: "Failed to add Audio Output Device", handler: nil)
}*/
ready = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Ответы
Ответ 1
AVAudioSession имеет некоторые изменения в Swift 4.2
под viewDidAppear(), попробуйте следующее:
// Prepare Audio Session
self.audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: .measurement, options: .defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
Он работал для меня, когда я преобразовал язык в Swift 4.2 в Xcode 10. Вы можете сделать это, перейдя к...
Изменить, преобразовать, в текущий быстрый синтаксис...
Ответ 2
Я считаю, что более старые версии поддерживаемого программного обеспечения потребуют больше работы, связанной с сетью. Попробуйте установить все узлы - в этом случае все динамики в одной беспроводной сети. То есть, убедитесь, что все динамики подключены к одному и тому же беспроводному SSID. Перезапустите приложение, альта!
Ответ 3
Вставьте в viewWillAppear() AVAudioSession имеет некоторые изменения, исправленный синтаксис для Swift 5.0 Объявите var recordingSession: AVAudioSession!
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .spokenAudio, options: .defaultToSpeaker)
try recordingSession.setActive(true, options: .notifyOthersOnDeactivation)
recordingSession.requestRecordPermission() { [unowned self] allowed in
DispatchQueue.main.async {
if allowed {
self.loadRecorder()
} else {
// failed to record!
}
}
}
} catch {
// failed to record!
}'
Ответ 4
Я также врезался в это - здесь мое решение - ошибка все еще показывает, но по крайней мере это работает плавно.
https://medium.com/ar-tips-and-tricks/how-to-capture-and-preview-microphone-audio-during-a-multi-route-audiosession-64aff28af021