I am trying to use AVAudioSession, but it is throwing this runtime error:
[avas] AVAudioSessionPortImpl.mm:56:ValidateRequiredFields:Unknown selected data source for Port Speaker (type Speaker)
. If it helps I am trying to just record audio, and monitor the current decibels. I set the category to AVAudioSessionCategoryRecord
, and the mode to AVAudioSessionModeMeasurement
.
here is the code:
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.
}
}
AVAudioSession has some changes in Swift 4.2
under viewDidAppear(), try this:
// Prepare Audio Session
self.audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: .measurement, options: .defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
It worked for me when I converted the language to Swift 4.2 in Xcode 10 You can do that by going to...
Edit, Convert, To Current Swift Syntax...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With