AVAudioPlayer and AVAudioRecorder: Delegate Method

2019-05-09 08:49发布

问题:

My delegate methods audioRecorderDidFinishRecording and audioPlayerDidFinishPlaying are not being called. Those methods should trigger a 'stopanimation` method that stops an animation after recording is finished.

I have placed a call call to the stopanimation method at the end of audioPlayerDidFinishPlaying.

Here is the relevant code where the delegate is assigned:

   VoiceEditor.h

    @interface VoiceEditor : UIViewController <UITextFieldDelegate, AVAudioRecorderDelegate, AVAudioPlayerDelegate>{    
}

VoiceEditor.m

- (void)record{
    recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:pathString] settings:recordSettings error:nil];
    [recorder setDelegate:self];
    [recorder record];
    recording = YES;        
    [pauseButton setImage:[UIImage imageNamed:@"stop.png"] forState:UIControlStateNormal];
    [pauseButton setEnabled:YES];
    [playButton setEnabled:NO];
    [recordButton setEnabled:NO];  
    [self beginAnimation];
}

- (void)play{              
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:pathString] error:nil];
    double seconds=[player duration];
    NSLog(@"%f",seconds);
    [player setDelegate:self];
    [player play];
    playing = YES;              
    [recordButton setEnabled:NO];
    [pauseButton setEnabled:YES];
    [playButton setEnabled:NO];     
    [self beginAnimation];
}

回答1:

Your code setting the delegate looks fine.

Are you assuming that the delegate methods are not called only because the animation does not stop or have you tried to log/breakpoint the methods directly? If you haven't tested directly do so before working on the assumption that they aren't.

If you have confirmed they are not being called the, most likely, your animation is tying up the self object such that it cannot respond to the AV delegate methods.

Comment out the animation and just put a log in the AV delegate methods to see if they are called.



回答2:

Try to pass the error parameter to be sure your recorder object is being created properly.

NSError *err=nil;
recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:pathString] settings:recordSettings error:&err];
if(!recorder){
    NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
}


回答3:

Check the current AVAudioSession category. If the category is not set to AVAudioSessionRecord or AVAudioSessionPlayAndRecord, the recorder won't work and none of its delegate methods will be called. The AVAudioSession category can be changed with the setCategory:error: method. For example:

NSError *sessionCategoryError = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL success = [audioSession setCategory: AVAudioSessionCategoryPlayAndRecord
                                   error: &sessionCategoryError];