AVAudioRecorder stops working when writing to /dev/null on iPhone 5s with iOS 7

StackOverflow https://stackoverflow.com/questions/19417954

  •  01-07-2022
  •  | 
  •  

Pergunta

I have an app that monitors the background audio level without recording to a file. I use the trick of writing to /dev/null to accomplish this.

This code has worked on the iPhone 3GS with iOS 6, iPhone 4 with iOS 6 and iOS 7, and in the simulator with iOS 7 and iPhone Retina (4-inch 64-bit).

When I try it on a real iPhone 5s, however, the recorder seems to capture audio for a moment, and then silently dies.

This is the code:

    // Inititalize the audio

NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat: 44100.0],                 AVSampleRateKey,
                          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
                          [NSNumber numberWithInt: 1],                         AVNumberOfChannelsKey,
                          [NSNumber numberWithInt: AVAudioQualityMax],         AVEncoderAudioQualityKey,
                          nil];


NSError *error;

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

if (recorder) {
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;
    [recorder record];
    levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
    //        peakLevelTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector: @selector(peakLevelTimerCallback:) userInfo: nil repeats: YES];
} else {
    NSLog(@"There was an error setting up the recorder.");        
    NSLog([error description]);
}

Any ideas what might be going on?

Could anyone suggest a workaround? Writing to a real file works, but I don't want to fill up any space on the device just to monitor audio. Is there a way to write to a small file buffer that just evaporates into thin air? Implement my own /dev/null, effectively?

Foi útil?

Solução

I had the same issue when testing one of my apps for iOS 7.

I got around the absence of /dev/null by creating an initial file that I then deleted a number of seconds after the recording started. The recording still continued to work for my application and there was no data file being stored.

- (void)startRecording
{
  // New recording path.
  NSString *recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"], @"cache"];
  NSURL *url = [NSURL fileURLWithPath:recorderFilePath];

  AVAudioRecorder recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];

  if([recorder prepareToRecord])
  {
    [recorder record];
    NSTimer deleteFileTimer = [NSTimer scheduledTimerWithTimeInterval:15 target:self selector:@selector(removeRecordingFile) userInfo:nil repeats:NO];
  }
}

- (void)removeRecordingFile
{
  // Remove the data file from the recording.
  NSString *recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"], @"cache"];
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSError *error = nil;

  BOOL success = [fileManager removeItemAtPath:recorderFilePath error:&error];

  if(success) 
  {
      NSLog(@"Deleted recording file");
  }
  else
  {
      NSLog(@"Could not delete file -:%@ ",[error localizedDescription]);
  }
}

Outras dicas

You need to change:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];

to:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:NULL];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top