1

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.

enter image description here

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!

Kerberos
  • 4,036
  • 3
  • 36
  • 55
nahung89
  • 7,745
  • 3
  • 38
  • 40
  • Take note that CADisplayLink is more adapted to UI proceccing and synchronised with the MainRunLoop. NSTimer might result in performance issues. – touti Jan 10 '23 at 14:26

1 Answers1

1

You have to set the category of your AVAudioSession like this

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&sessionError];

So that it will record the audio when the device is locked.

As the doc says

To continue recording audio when your app transitions to the background (for example, when the screen locks), add the audio value to the UIBackgroundModes key in your information property list file.

Also check this link

AVAudioRecorder doesn't record while screen is locked

Community
  • 1
  • 1
Rajat
  • 10,977
  • 3
  • 38
  • 55
  • I'm afraid that it does not change anything. `AVAudioSessionCategoryRecord` and `AVAudioSessionCategoryPlayAndRecord` have the same result, as I tell above – nahung89 Sep 10 '15 at 11:34
  • I dont understand why it will not work, as docs says it will work while screen is lock. – Rajat Sep 10 '15 at 11:42
  • You're right. The recorder still works under device-locking. The problem comes from CADisplayLink, which I use to monitor the recorder. I'll update on my question. Thank a lot! – nahung89 Sep 10 '15 at 14:23
  • I think it will be better if you post a new question, then it will be on top and most of the user can see it.(Just a suggestion) – Rajat Sep 10 '15 at 14:26
  • Ah, actually I found the issue and fixed it. So I think it might better if updating on my question instead of create a new one. – nahung89 Sep 10 '15 at 14:27
  • No problem. Go for it, – Rajat Sep 10 '15 at 14:28