-->

AVAudioRecorder not saving recording

2019-06-08 05:09发布

问题:

I am making an iOS game. One of the things I need to do is to allow the user to make a quick little audio recording. This all works, but the recording is only temporarily saved. So when the user closes the app and reopens it, the recording should be able to play again, but it doesn't, it gets deleted when I close the app. I don't understand what I am doing wrong. Below is my code:

I setup the AVAudioRecorder in the ViewDidLoad method like this:

// Setup audio recorder to save file.
NSArray *pathComponents = [NSArray arrayWithObjects:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], @"MyAudioMemo.m4a", nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

// Setup audio session.
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];

audio_recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
audio_recorder.delegate = self;
audio_recorder.meteringEnabled = YES;
[audio_recorder prepareToRecord];

I have got the AVAudio delegate methods, too:

-(void)audio_playerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    NSLog(@"Did finish playing: %d", flag);
}

-(void)audio_playerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error {
    NSLog(@"Decode Error occurred");
}

-(void)audio_recorderDidFinishRecording:(AVAudioPlayer *)recorder successfully:(BOOL)flag {
    NSLog(@"Did finish recording: %d", flag);
}

-(void)audio_recorderEncodeErrorDidOccur:(AVAudioPlayer *)recorder error:(NSError *)error {
    NSLog(@"Encode Error occurred");
}

When I want to play, record or stop the audio, I have made the following IBActions which are linked to UIButtons:

-(IBAction)play_audio {

    NSLog(@"Play");

    if (!audio_recorder.recording){
        audio_player = [[AVAudioPlayer alloc] initWithContentsOfURL:audio_recorder.url error:nil];
        [audio_player setDelegate:self];
        [audio_player play];
    }
}

-(IBAction)record_voice {

    NSLog(@"Record");

    if (!audio_recorder.recording) {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setActive:YES error:nil];

        // Start recording.
        [audio_recorder record];
    }

    else {
        // Pause recording.
        [audio_recorder pause];
    }
}

-(IBAction)stop_audio {

    NSLog(@"Stop");

    [audio_recorder stop];

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setActive:NO error:nil];
}

If you try my code you will see that it works, but it only seems to save the audio file temporarily.

What am I doing wrong? I thought I had used all the correct AVAudioRecorder methods?

回答1:

To make a working recorder and save the recorded files, you need to:

  1. Create a new audio session
  2. Make sure microphone is connected/working
  3. Start recording
  4. Stop recording
  5. Save the recorded audio file
  6. Play the saved voice file

You're missing step 5 in your code, so the file that's just recorded is still available for you to play, but once you close the app, as it's not saved into an actual file somewhere in the app's directories, you lose it. You should add a method to save the recorded audio into a file so that you can access it any time later:

-(void) saveAudioFileNamed:(NSString *)filename {

destinationString = [[self documentsPath] stringByAppendingPathComponent:filename];
NSLog(@"%@", destinationString);
NSURL *destinationURL = [NSURL fileURLWithPath: destinationString];

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

NSError *error;

audio_recorder = [[AVAudioRecorder alloc] initWithURL:destinationURL settings:settings error:&error];
audio_recorder.delegate = self;
}

Unrelated to this problem, but a general thing to mention is that you must follow Apple's (Objective-C's) naming conventions when defining variables, etc. audio_recording in no way follows these guidelines. You could use something like audioRecording instead.



回答2:

Ok so thanks for @Neeku so much for answering my question, certainly something to take into account but its still not solving the problem. I was searching around and I found this example which works perfectly and more to the point shows me that I was approaching this entire functionality the wrong way. I think another one of my problems is that my app would delete the previously saved audio file in the ViewDidload method. And as well as that I don't think I have used the AVAudioSession instances correctly.

Anyway the example I found is very useful and solves my problem perfectly, you can find it here: Record audio and save permanently in iOS

Hope that helps anyone else who is having a similar problem to me.