AVAudioSessionErrorCodeCannotStartRecording when recording in the background with iOS 13

Hello.


I am working on adding support for iOS 13. Previously the app has been able to record audio for transmition while in the background when the user presses an external button, such as one from a wired headset. This is important as many users such as first responders are currently able to talk by pressing a button, rather than pulling the phone out of a pocket, unlocking it, launching the app etc.


I can't find any sort of recording in the background permission to put in the info plist. Are there any special categories or options needed in the Audio Session to permit this on iOS 13? Failing that, is there a way to launch the app when the user presses the button ( wired or bluetooth le) so the recording can start?


How does the Messages App allow recording on the notification? Inter-App Audio?


Thanks.

Hi,
I am having the same problem, Our app is on the app store now and I hope this is resolved soon.

Just tested with the 13.1 beta, and still get the error.

+1 ;-(

Same also for me ios 13.1 beta ... still unable to start recording from background

do you have any suggestion that can help us ?


tnx in advance

We use audio units for recording. It's a lot of code and I cannot share it. Project has audio background mode capability. I have used iPadOS 13.1 beta (I hope that iOS 13.1 beta is the same). If the application (on iOS 12.4) is in the background and something interrupts the app during recording (alarm, phone call) then it cannot resume recording (AudioOutputUnitStart failed with error AVAudioSessionErrorCodeCannotStartRecording). When I tested it on iPadOS 13.1 beta then it worked. I didn't try with AVAudioRecorder.

DTS response on Aug 27, 2019,due to overriding privacy considerations,apps will not in general be allowed to start recording while in the background,Engineering has made some decisions about what will happen in the short term.😟

I don’t get this error anymore on iOS 13.1 beta 1 - seems to be resolved.

Could you tell me which API do you use? AVFoundation or AudioToolBox? Which device do you use? Iphone or iPad?

I'm using AVAudioEngine on an iPhone.

Actually, I spoke too soon. This issue seems to be resolved only after interruptions, but it still exists when changing audio route. So for example, if you connect bluetooth headphones while the app is backgrounded, the audio recording will stop and will fail to recover.

Please file a bug report about this behavior.

Hi, 3ZS


Here is files for you, 3ZS

BackgroundStartRecording.mov : video for using this project

AugRecorder.zip : Xcode Project


https://www.dropbox.com/sh/5rrrs9jeqzgo9tu/AABCqe31KqJhhsS4EVuMLnBla?dl=0


# Run This Project on Any iPhone with iOS 12.4 or iOS 13 beta for iOS 13.1 beta


## Execute Summary

when .inactive : AVAudioRecorder.record() got true

when .background : AVAudioRecorder.record() got false

on SettingsViewController.swift L26~30


## prepare

1. Play Music For create Player and begin Background Mode Audio

- play button : Recorder Tab - bottom left

2. Record(PH) for create recorder

- record(PH) button : Recorder Tab - middle right

3. pause player and recorder

- recorder pause button : middle left

- player pause button : bottom left

4. Setup RemoteCommand for recording

- turn on using RemoteCommand switch

- Setting Tab - using RemoteCommand switch


## try Recording when .inactive

1. show Control Center - swipe TopRight Edge down on iPhone X

2. touch 'prev track' button

- got: true - recorder.record() result


## try Recording when .background

1. exit Application - swipe Bottom Edge up on iPhone X

- now home screen

2. show Control Center - swipe TopRight Edge down on iPhone X

- now show control center 'AugRecorder' with active prevTrack button

3. touch 'prev track' button

- got: false - recorder.record() result


---------- Debug Console Logs ----------

## prepare

2019-09-02 13:50:55 +0000 set audio session: soloAmbient ( , , ) ==> playback ( , , ) in 0.0005

2019-09-02 13:51:02 +0000 set audio session: playback ( , , ) ==> playback ( , , ) in 0.0003

2019-09-02 13:51:04 +0000 set audio session: playback ( , , ) ==> playback ( , , ) in 0.0006

2019-09-02 13:51:07 +0000 set audio session: playback ( , , ) ==> playAndRecord ( HFP, SPKR, A2DP) in 0.2391

recorder.record() true

## try Recording when .inactive

recorder() ==> true

## try Recording when .background

recorder() ==> false

nevos, thank you. your answer was help.

my app was convert from audio unit to AVAudioEngine and no error yet.

AVAudioSessionErrorCodeCannotStartRecording - iOS 12.4 - 13.1~


Is not possibile to start Recording when device is in Background.



If I start a Recording in foreground no problem appears, if I switch in background during the recording no problem yet.



But if the recording time is terminated and new recording is schedule immediately after (~ 1 /2 Seconds ) and device is in background the Recording don’t start.



With this in log:

-CMSUtilities- CMSUtility_IsAllowedToStartRecording: CMSession: Client <private> with PID *** is in the background and doesn't have the entitlement to start recording in the background.

I resolved this problem with CallKit.

When CallKit is actived, try open mic.

How????


Can u explain well how it's work?

I use AudioQueue for recording. Recording restart in background after interrupt does not work on iOS 13.0 beta, but works fine on lastest iOS 13.1 beta, looks like issue is fixed by Apple.

does it work for you after "route changes" (e.g. when you connect disconnect headphones / airpods)?

Yes, it also works fine.

I launch app -> plug headphones -> talk to Siri (audio session interrupt began and ended) -> app continues to record -> unplug headphones -> talk to Siri -> app continues to record

Tested on iOS 13.1 beta 2

Yes I saw it as well 😟

@julop, @nevos, @TatianaMrl: are you really starting recording in the background? Do you have any specific background modes enabled that you can share or are you not using AudioQueueStart?


Here is some of my code and we still get return status AVAudioSessionErrorCodeCannotStartRecording is we start recording in background.

We are starting recording using a Bluetooth 4.0 accessory and I am cursious if this could be the problem for us.


We have done some battery measurements to keep recording enabled at all times and just drop the data until we need to process it. This has a great impact on battery life. On our particular test devices it had this effect:

Apple iPhone 6S Plus. Battery life went from 62h to 41h which is a decrease of 34% (https://www.dropbox.com/s/uyy3rwzzlzzf478/I3%20-%20Apple%20iPhone%206S%20Plus%20%28Apple%20iPhone8%2C2%29%20iOS%2012.4.1.jpg?dl=0)
Apple iPhone 7. Battery life went from 28h to 14h which is a decrease of 50% (https://www.dropbox.com/s/wt9wwmaezru6mtj/I5%20-%20Apple%20iPhone%207%20%28Apple%20iPhone9%2C3%29%20iOS%2013.1.jpg?dl=0)
Apple iPhone 6S. Battery life went from 33h to 27h which is a decrease of 18% (https://www.dropbox.com/s/vuaqgthvnsfh4tf/I6%20-%20Apple%20iPhone%206S%20%28Apple%20iPhone8%2C1%29%20iOS%2013.1.jpg?dl=0)



Here is the method we use to start the recording


- (void)startRecording {
    aqData.mDataFormat.mFormatID         = kAudioFormatMPEG4AAC;
    aqData.mDataFormat.mSampleRate       = 22050.0;
    aqData.mDataFormat.mChannelsPerFrame = 1;
    aqData.mDataFormat.mBitsPerChannel   = 0;
    aqData.mDataFormat.mBytesPerPacket   = 0;
    aqData.mDataFormat.mBytesPerFrame    = 0;
    aqData.mDataFormat.mFramesPerPacket  = 1024;
    aqData.mDataFormat.mFormatFlags      = kMPEG4Object_AAC_Main;
    AudioFileTypeID fileType             = kAudioFileAAC_ADTSType;
    aqData.bufferByteSize = 16384;


    UInt32 defaultToSpeaker = TRUE;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(defaultToSpeaker), &defaultToSpeaker);

    OSStatus status = AudioQueueNewInput(&aqData.mDataFormat, HandleInputBuffer, &aqData, NULL, kCFRunLoopCommonModes, 0, &aqData.mQueue);
    UInt32 dataFormatSize = sizeof (aqData.mDataFormat);

    status = AudioQueueGetProperty(aqData.mQueue, kAudioQueueProperty_StreamDescription, &aqData.mDataFormat, &dataFormatSize);
    status = AudioFileInitializeWithCallbacks(&aqData, nil, BufferFilled, nil, nil, fileType, &aqData.mDataFormat, 0, &aqData.mAudioFile);

    for (int i = 0; i < kNumberBuffers; ++i) {
        status = AudioQueueAllocateBuffer (aqData.mQueue, aqData.bufferByteSize, &aqData.mBuffers[i]);
        status = AudioQueueEnqueueBuffer (aqData.mQueue, aqData.mBuffers[i], 0, NULL);
    }

    aqData.mCurrentPacket = 0;                     
    aqData.mIsRunning = true;                      

    status = AudioQueueStart(aqData.mQueue, NULL);
}

I am finding the same issue happens on route change as well. There are two issues AFAIK:

1. Restarting the audio recording after a route change (while the app is backgrounded), for example tearing down and restarting an AVAudioEngine graph returns the same error described in this ticket. Therefore, it looks like Apple fixed it only for post-interruption.

2. Connecting/disconnecting a Bluetooth device (e.g. Airpods) while the app is backgrounded fails, even you don't attempt to restart the audio graph. In this case it fails without any error in the logs.


Last tested on iOS 13.1 beta 2.

I opened a new ticket to track the Bluetooth issue: https://forums.developer.apple.com/thread/122621

> We have done some battery measurements to keep recording enabled at all times and just drop the data until we need to process it.


not an answer to your specific question but this looks like a "crime"


> This has a great impact on battery life.


for that very reason. plus your users might be rightfully suspicious and unhappy seeing the red / green recording indication of recording when no recording should take place.


btw, if you go to "Settings > Developer > Reset Media Services" it will probably stop your background recording anyway, getting you back to square one (and this is not the only time when system can reset media services from my understanding).


i recon the easiest way for apple to fix this issue is to keep the old behaviour for apps that are linked with the old versions of Xcode and introduce some opt-in (e.g. a new entitlement) for new behaviour when new Xcode is used.

AVAudioSessionErrorCodeCannotStartRecording when recording in the background with iOS 13
 
 
Q