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.

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.

I am only able to start recording in the background after an interruption (if I was already recording before the interruption started). Otherwise, it's blocked (I'm assuming for security/privacy reasons).

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

I totally agree but it is the solution currently suggested to us by Apple.


It is of very ugly and annoying for the user - to the point of unacceptable for most users I believe.


But now after our battery tests it also proves that this is a huge waste of battery life also likely unacceptable to most users.

And to record sound continiously just to trash it just feel like crazy.

Oh thanks for the response @nevos.


We dont want to record until the user activates our bluetooth accessory so this will not work for us unfortunately.

Guess we are back at square one and there is still no way forward for this

@k.alonso have you got any more info from Apple? I have not received a reply for almost a week now. Anyone else got any new info?

a variation of the same issue:


go to apple's voice memos app. start recording, switch to background

the red recording indication is shown - if you tap it - it brings you to the voice memos app.

now, switch to background and do anything that plays a sound.

e.g. go to settings > sounds and change ring volume or ring tone - that will play a sound.

the red recording indication is still shown but mic no longer records.

if you tap the red recording indicator no longer it brings you back to the voice memos app and if you go to the voice memos app you see that recording is actually stuck.

Does this work out?


I tried your method(callkit ),but nothing happen.

Hello,


@Apple: Is there any fix for the iOS 12.4 for this issue?

Still I'm facing same issue ios13.2, does any one found soplution ?

looks like a "cold case" bug

No :-(

AVAudioSessionErrorCodeCannotStartRecording when recording in the background with iOS 13
 
 
Q