iPhone, record sounds from speaker and microphone simultaneously - ios

I'm trying to record sounds from a speaker and microphone simultaneously in iPhone. I used AVAudioRecorder and AVAudioSession to do this, but it doesn't work: the only sound recorded is from the microphone.
I've already read articles about this on stackoverflow, like Record AVAudioPlayer output using AVAudioRecorder and similar questions and answers.
Are there any good references or classes to implement this? Thanks in advance!

if we want to use both of them at a time we need to set AVAudioSession's Category to AVAudioSessionCategoryAmbient.
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
} catch let error as NSError {
print(error)
}
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch let error as NSError {
print(error)
}

Related

AVAudioSession setCategory return alway error

I'm developing music application that simply play song from app. now i'm connecting bluetooth speaker to play. so i'm setting AVAudioSession category, but it will always return error.
Code :
func setupSessionForPlaying() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: [.allowBluetooth])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
I'm calling this function in didFinishLaunchingWithOptions in AppDelegate.
But if i change setCategory to audioSession.setCategory(AVAudioSessionCategoryPlayback) its working fine.
Does anyone know what's wrong with this code?
Thanks
According to docs
https://developer.apple.com/documentation/avfoundation/avaudiosession/categoryoptions/1616518-allowbluetooth
You can set this option only if the audio session category is playAndRecord or record.
with allowBluetooth you can not use AVAudioSessionCategoryPlayback
Hope it is helpful
You cannot mix all categories with all options. As is mentioned here you may only use .allowBluetooth with the categories playAndRecord or record. So I suggest you to try
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord,
with: [.allowBluetooth,
.allowBluetoothA2DP])
instead.
Although the answer above is the correct one in this particular case (due to the .allowBluetooth option), there is another possible reason for the 'what' error to appear:
The AVAudioSession could be currently playing or recording the moment setCategory is called. Make sure that the session is stopped before you set the category.
Building on #Geru's answer
I got this error when using any combination of .allowAirPlay, .allowBluetoothA2DP, and .allowBluetooth with the AVAudioSessionCategoryPlayback category.
Setting category to AVAudioSessionCategoryPlayback failed. The operation couldn’t be completed. (OSStatus error -50.)
This works, though:
do {
try audioSession.setCategory(.playback, mode: .default)
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed. \(error.localizedDescription)")
}

AVFoundation adding audio input mutes audio playback

I have an app that records audio and video using AVFoundation. I want any audio playback from other apps (or the system) to continue while recording audio in my app, but when adding the input to the session an already playing audio from another app gets magically muted.
The corresponding code looks like this:
// set up audio device
if(m_audioenabled) {
print("Audio enabled")
if self.m_audioDevice != nil {
do {
let audioinput = try AVCaptureDeviceInput(device: self.m_audioDevice!)
if self.m_session.canAddInput(audioinput) {
self.m_session.addInput(audioinput)
}
} catch _ {
print("failed adding audio capture device as input to capture session")
}
}
m_audioDataOutput = AVCaptureAudioDataOutput()
m_audioDataOutput?.setSampleBufferDelegate(self, queue: self.m_captureSessionQueueAudio)
if self.m_session.canAddOutput(m_audioDataOutput!){
self.m_session.addOutput(m_audioDataOutput!)
}
}
If I comment out the call to canAddInput(...) the audio keeps playing, when I call it, audio playback gets muted.
How can I disable that behavior ?
Please note the migrating to another Audio-API is not an option.
Sounds like your AVAudioSession is non-mixable (the default, I think). Try activating a mixable audio session before you set up the AVCaptureSession:
let session = AVAudioSession.sharedInstance()
try! session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: [.mixWithOthers])
try! session.setActive(true)

iOS switch between playing sounds in background and not playing

I am working on music app and it has feature of switching between playing/not playing music when app minimized.
How can I do it?
I use that code to enable playing in backgound, but how can I disable it?
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
} catch let error as NSError {
print(error.localizedDescription)
}

Using Spotify/background music with camera open

I have an app that needs to have:
Background music playing while using the app (eg. spotify)
Background music playing while watching movie from AVPlayer
Stop the music when recording a video
Like Snapchat, the camera-viewcontroller is part of a "swipeview" and therefore always on.
However, when opening and closing the app, the music makes a short "crack" noise/sound that ruins the music.
I recorded it here:
https://soundcloud.com/morten-stulen/hacky-sound-ios
(3 occurrences)
I use these settings for changing the AVAudiosession in the appdelegate didFinishLaunchingWithOptions:
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord,withOptions:
[AVAudioSessionCategoryOptions.MixWithOthers,
AVAudioSessionCategoryOptions.DefaultToSpeaker])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("error")
}
I use the LLSimpleCamera control for video recording and I've set the session there to:
_session.automaticallyConfiguresApplicationAudioSession = NO;
It seems others have the same problem with other camera libraries as well:
https://github.com/rFlex/SCRecorder/issues/127
https://github.com/rFlex/SCRecorder/issues/224
This guy removed the audioDeviceInput, but I kinda need that for recording video.
https://github.com/omergul123/LLSimpleCamera/issues/48
I also tried with Apple's code "AvCam", and I still have the same issue. How does Snapchat do this?!
Any help would be greatly appreciated, and I'll gladly provide more info or code!
I do something similar to what you're wanting, but without the camera aspect, but I think this will do what you want. My app allows background audio that will mix with non-fullscreen video/audio. When the user plays an audio file or a full screen video file, I stop the background audio completely.
The reason I do SoloAmbient then Playback is because I allow my audio to be played in the background when the device is locked. Going SoloAmbient will stop all background music playing and then switching to Playback lets my audio play in the app as well as in the background.
This is why you see a call to a method that sets the lock screen information in the Unload method. In this case, it is nulling it out so that there is no lock screen info.
In AppDelegate.swift
//MARK: Audio Session Mixing
func allowBackgroundAudio()
{
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .MixWithOthers)
} catch {
NSLog("AVAudioSession SetCategory - Playback:MixWithOthers failed")
}
}
func preventBackgroundAudio()
{
do {
//Ask for Solo Ambient to prevent any background audio playing, then change to normal Playback so we can play while locked
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
NSLog("AVAudioSession SetCategory - SoloAmbient failed")
}
}
When I want to stop background audio, for example when playing an audio track that should be alone, I do the following:
In MyAudioPlayer.swift
func playUrl(url: NSURL?, backgroundImageUrl: NSURL?, title: String, subtitle: String)
{
ForgeHelper.appDelegate().preventBackgroundAudio()
if _mediaPlayer == nil {
self._mediaPlayer = MediaPlayer()
_mediaPlayer!.delegate = self
}
//... Code removed for brevity
}
And when I'm done with my media playing, I do this:
private func unloadMediaPlayer()
{
if _mediaPlayer != nil {
_mediaPlayer!.unload()
self._mediaPlayer = nil
}
_controlView.updateForProgress(0, duration: 0, animate: false)
ForgeHelper.appDelegate().allowBackgroundAudio()
setLockScreenInfo()
}
Hope this helps you out!

AVAudioEngine stops device's background audio

I am using an AVAudioEngine object, that has many AVAudioPlayerNodes attached to it. The audio all works fine, except it stops any audio that the iPhone is playing in the background (i. e. from iTunes or another music app).
When my app is opened, it stops any other background audio. Is there a way to allow background audio to continue to play? Even when my app is using AVAudioPlayerNodes to play audio itself?
Music App has it's own audioSession, that makes audio engine stops, i had that problem too, please restart after music app.
func stepB_startEngine(){
if engine.running == false {
do { try engine.start() }
catch let error {
print(error)
}
}
}
setup audioSettion also:
func setUpAudioSession(){
do {
try AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch let error {
print(error)
}
}

Resources