EDIT: Using CADislayLink
to monitor the AVAudioRecorder
meters is not a good idea if app run in background. It stops triggering if device sleeps (in my case is locking the device). The solution for that is using NSTimer
instead. Here is the code which cause my issue
- (void)startUpdatingMeter {
// Using `CADisplayLink` here is not a good choice. It stops triggering if lock the device
self.meterUpdateDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAudioRecorderMeters)];
[self.meterUpdateDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
Solution: using NSTimer instead
// Set timeInterval as frame refresh interval
self.timerMonitor = [NSTimer timerWithTimeInterval:1.f/60.f target:self selector:@selector(handleAudioRecorderMeters:) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:self.timerMonitor forMode:NSDefaultRunLoopMode];
The code below is working perfect with AVAudioRecorder
, no matter we're using AVAudioSessionCategoryRecord
or AVAudioSessionCategoryPlayAndRecord
.
ORIGINAL QUESTION: So far I'm creating an application that records sound, even it's in background mode. It's quite like iTalk.
Everything is nearly perfect, my app can record while is foreground / background (by registering background mode - link), but it pauses/stops if device is locked (by user or by self-device).
I tried iTalk and it works fine in that case. I also get a hint from iTalk: it has music control on lock screen, while my app does not have.
Here is my code to config AVAudioSession
and AVAudioRecorder
- (void)configurateAudioSession {
NSError *error = nil;
// Return success after set category
BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];
// Return success after set active
success = [[AVAudioSession sharedInstance] setActive:YES error:&error];
// Return success after set mode
success = [[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error];
}
- (void)configAudioRecorder {
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex:0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
// Create audio recorder
NSURL *url = [NSURL fileURLWithPath:pathToSave];
NSDictionary *settings = @{ AVSampleRateKey: @44100.0,
AVFormatIDKey: @(kAudioFormatAppleLossless),
AVNumberOfChannelsKey: @1,
AVEncoderAudioQualityKey:@(AVAudioQualityMax), };
NSError *error = nil;
self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (error) {
NSLog(@"Error on create audio: %@", error);
}
else {
[self.audioRecorder prepareToRecord];
self.audioRecorder.meteringEnabled = YES;
[self.audioRecorder record];
}
}
I would be very grateful if you could provide me with any information. Thank guy!