148
votes

Now that iPhone 3.0 SDK is public, I think I can ask this question for those of you that have already been playing with the 3.0 SDK. I want to record audio in my application, but I want to use AVAudioRecorder and not the older way of recording like the example SpeakHere shows. There are not any examples of how to best do this in the iPhone Dev Center and only reference to the classes. I am a newbie at iPhone development, so I am looking for a simple sample to get me started.

13

13 Answers

207
votes

Actually, there are no examples at all. Here is my working code. Recording is triggered by the user pressing a button on the navBar. The recording uses cd quality (44100 samples), stereo (2 channels) linear pcm. Beware: if you want to use a different format, especially an encoded one, make sure you fully understand how to set the AVAudioRecorder settings (read carefully the audio types documentation), otherwise you will never be able to initialize it correctly. One more thing. In the code, I am not showing how to handle metering data, but you can figure it out easily. Finally, note that the AVAudioRecorder method deleteRecording as of this writing crashes your application. This is why I am removing the recorded file through the File Manager. When recording is done, I save the recorded audio as NSData in the currently edited object using KVC.

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]


- (void) startRecording{

UIBarButtonItem *stopButton = [[UIBarButtonItem alloc] initWithTitle:@"Stop" style:UIBarButtonItemStyleBordered  target:self action:@selector(stopRecording)];
self.navigationItem.rightBarButtonItem = stopButton;
[stopButton release];

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}

recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];



// Create a new dated file
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
recorderFilePath = [[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate] retain];

NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
    NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    UIAlertView *alert =
    [[UIAlertView alloc] initWithTitle: @"Warning"
                               message: [err localizedDescription]
                              delegate: nil
                     cancelButtonTitle:@"OK"
                     otherButtonTitles:nil];
    [alert show];
    [alert release];
    return;
}

//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;

BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
    UIAlertView *cantRecordAlert =
    [[UIAlertView alloc] initWithTitle: @"Warning"
                               message: @"Audio input hardware not available"
                              delegate: nil
                     cancelButtonTitle:@"OK"
                     otherButtonTitles:nil];
    [cantRecordAlert show];
    [cantRecordAlert release]; 
    return;
}

// start recording
[recorder recordForDuration:(NSTimeInterval) 10];

}

- (void) stopRecording{

[recorder stop];

NSURL *url = [NSURL fileURLWithPath: recorderFilePath];
NSError *err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(!audioData)
    NSLog(@"audio data: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
[editedObject setValue:[NSData dataWithContentsOfURL:url] forKey:editedFieldKey];   

//[recorder deleteRecording];


NSFileManager *fm = [NSFileManager defaultManager];

err = nil;
[fm removeItemAtPath:[url path] error:&err];
if(err)
    NSLog(@"File Manager: %@ %d %@", [err domain], [err code], [[err userInfo] description]);



UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithTitle:@"Record" style:UIBarButtonItemStyleBordered  target:self action:@selector(startRecording)];
self.navigationItem.rightBarButtonItem = startButton;
[startButton release];

}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{

NSLog (@"audioRecorderDidFinishRecording:successfully:");
// your actions here

}
85
votes

Although this is an answered question (and kind of old) i have decided to post my full working code for others that found it hard to find good working (out of the box) playing and recording example - including encoded, pcm, play via speaker, write to file here it is:

AudioPlayerViewController.h:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AudioPlayerViewController : UIViewController {
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
int recordEncoding;
enum
{
    ENC_AAC = 1,
    ENC_ALAC = 2,
    ENC_IMA4 = 3,
    ENC_ILBC = 4,
    ENC_ULAW = 5,
    ENC_PCM = 6,
} encodingTypes;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

AudioPlayerViewController.m:

#import "AudioPlayerViewController.h"

@implementation AudioPlayerViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    recordEncoding = ENC_AAC;
}

-(IBAction) startRecording
{
NSLog(@"startRecording");
[audioRecorder release];
audioRecorder = nil;

// Init audio with record capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];

NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] initWithCapacity:10];
if(recordEncoding == ENC_PCM)
{
    [recordSettings setObject:[NSNumber numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];   
}
else
{
    NSNumber *formatObject;

    switch (recordEncoding) {
        case (ENC_AAC): 
            formatObject = [NSNumber numberWithInt: kAudioFormatMPEG4AAC];
            break;
        case (ENC_ALAC):
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleLossless];
            break;
        case (ENC_IMA4):
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleIMA4];
            break;
        case (ENC_ILBC):
            formatObject = [NSNumber numberWithInt: kAudioFormatiLBC];
            break;
        case (ENC_ULAW):
            formatObject = [NSNumber numberWithInt: kAudioFormatULaw];
            break;
        default:
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleIMA4];
    }

    [recordSettings setObject:formatObject forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithInt: AVAudioQualityHigh] forKey: AVEncoderAudioQualityKey];
}

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];


NSError *error = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];

if ([audioRecorder prepareToRecord] == YES){
    [audioRecorder record];
}else {
    int errorCode = CFSwapInt32HostToBig ([error code]); 
    NSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode); 

}
NSLog(@"recording");
}

-(IBAction) stopRecording
{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording
{
NSLog(@"playRecording");
// Init audio with playback capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying
{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
}

- (void)dealloc
{
[audioPlayer release];
[audioRecorder release];
[super dealloc];
}

@end

Hope this will help some of you guys.

14
votes

I have uploaded a sample project. You can take a look.

VoiceRecorder

11
votes

Its really helpful. The only problem i had was the size of sound file created after recording. I needed to reduce the file size so i did some changes in settings.

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];

File size reduced from 360kb to just 25kb (2 seconds recording).

8
votes

I've been trying to get this code to work for the last 2 hours and though it showed no error on the simulator, there was one on the device.

Turns out, at least in my case that the error came from directory used (bundle) :

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];

It was not writable or something like this... There was no error except the fact that prepareToRecord failed...

I therefore replaced it by :

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", recDir]]

It now Works like a Charm.

Hope this helps others.

6
votes

Great Thanks to @Massimo Cafaro and Shaybc I was able achieve below tasks

in iOS 8 :

Record audio & Save

Play Saved Recording

1.Add "AVFoundation.framework" to your project

in .h file

2.Add below import statement 'AVFoundation/AVFoundation.h'.

3.Define "AVAudioRecorderDelegate"

4.Create a layout with Record, Play buttons and their action methids

5.Define Recorder and Player etc.

Here is the complete example code which may help you.

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController <AVAudioRecorderDelegate>

@property(nonatomic,strong) AVAudioRecorder *recorder;
@property(nonatomic,strong) NSMutableDictionary *recorderSettings;
@property(nonatomic,strong) NSString *recorderFilePath;
@property(nonatomic,strong) AVAudioPlayer *audioPlayer;
@property(nonatomic,strong) NSString *audioFileName;

- (IBAction)startRecording:(id)sender;
- (IBAction)stopRecording:(id)sender;

- (IBAction)startPlaying:(id)sender;
- (IBAction)stopPlaying:(id)sender;

@end

Then do the job in

ViewController.m

#import "ViewController.h"

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]

@interface ViewController ()
@end

@implementation ViewController

@synthesize recorder,recorderSettings,recorderFilePath;
@synthesize audioPlayer,audioFileName;


#pragma mark - View Controller Life cycle methods
- (void)viewDidLoad
{
    [super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


#pragma mark - Audio Recording
- (IBAction)startRecording:(id)sender
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *err = nil;
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
    if(err)
    {
        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        return;
    }
    [audioSession setActive:YES error:&err];
    err = nil;
    if(err)
    {
        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        return;
    }
    
    recorderSettings = [[NSMutableDictionary alloc] init];
    [recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
    [recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    
    // Create a new audio file
    audioFileName = @"recordingTestFile";
    recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName] ;
    
    NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
    err = nil;
    recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&err];
    if(!recorder){
        NSLog(@"recorder: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        UIAlertView *alert =
        [[UIAlertView alloc] initWithTitle: @"Warning" message: [err localizedDescription] delegate: nil
                         cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    //prepare to record
    [recorder setDelegate:self];
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;
    
    BOOL audioHWAvailable = audioSession.inputIsAvailable;
    if (! audioHWAvailable) {
        UIAlertView *cantRecordAlert =
        [[UIAlertView alloc] initWithTitle: @"Warning"message: @"Audio input hardware not available"
                                  delegate: nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [cantRecordAlert show];
        return;
    }
    
    // start recording
    [recorder recordForDuration:(NSTimeInterval) 60];//Maximum recording time : 60 seconds default
    NSLog(@"Recroding Started");
}

- (IBAction)stopRecording:(id)sender
{
    [recorder stop];
    NSLog(@"Recording Stopped");
}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{
    NSLog (@"audioRecorderDidFinishRecording:successfully:");
}


#pragma mark - Audio Playing
- (IBAction)startPlaying:(id)sender
{
    NSLog(@"playRecording");
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName]];
    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    audioPlayer.numberOfLoops = 0;
    [audioPlayer play];
    NSLog(@"playing");
}
- (IBAction)stopPlaying:(id)sender
{
    [audioPlayer stop];
    NSLog(@"stopped");
}

@end

enter image description here

2
votes
This is from Multimedia programming guide...

- (IBAction) recordOrStop: (id) sender {
if (recording) {
    [soundRecorder stop];
    recording = NO;
    self.soundRecorder = nil;
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateNormal];
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateHighlighted];
    [[AVAudioSession sharedInstance] setActive: NO error:nil];
} 
else {
    [[AVAudioSession sharedInstance]
     setCategory: AVAudioSessionCategoryRecord
     error: nil];
    NSDictionary *recordSettings =
    [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
     [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
     [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
     [NSNumber numberWithInt: AVAudioQualityMax],
     AVEncoderAudioQualityKey,
     nil];
    AVAudioRecorder *newRecorder =
    [[AVAudioRecorder alloc] initWithURL: soundFileURL
                                settings: recordSettings
                                   error: nil];
    [recordSettings release];
    self.soundRecorder = newRecorder;
    [newRecorder release];
    soundRecorder.delegate = self;
    [soundRecorder prepareToRecord];
    [soundRecorder record];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateNormal];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateHighlighted];
    recording = YES;
}
}
2
votes

In the following link you can find useful info about recording with AVAudioRecording. In this link in the first part "USing Audio" there is an anchor named “Recording with the AVAudioRecorder Class.” that leads you to the example.

AudioVideo Conceptual MultimediaPG

2
votes

Ok so the answer I got helped me in the right direction and I am very thankful. It helped me figure out how to actually record on the iPhone, but I thought I would also include some helpful code I got from the iPhone Reference Library:

AudioandVideoTechnologies

I used this code and added it to the avTouch example fairly easily. With the above code sample and the sample from the reference library, I was able to get this to work pretty good.

2
votes

for wav format below audio setting

NSDictionary *audioSetting = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithFloat:44100.0],AVSampleRateKey,
                              [NSNumber numberWithInt:2],AVNumberOfChannelsKey,
                              [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                              [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey, 
                              [NSNumber numberWithBool:0], AVLinearPCMIsBigEndianKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                              [NSData data], AVChannelLayoutKey, nil];

ref: http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html

0
votes

START

NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

NSError *error = nil;
NSString *filename = [NSString stringWithFormat:@"%@.caf",FILENAME];
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:filename];
NSURL *soundFileURL = [NSURL fileURLWithPath:path];


NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium],AVEncoderAudioQualityKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium], AVSampleRateConverterAudioQualityKey,
                                [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                [NSNumber numberWithFloat:22050.0],AVSampleRateKey,
                                nil];

AVAudioRecorder *audioRecorder = [[AVAudioRecorder alloc]
                 initWithURL:soundFileURL
                 settings:recordSettings
                 error:&error];


if (!error && [audioRecorder prepareToRecord])
{
    [audioRecorder record];
}

STOP

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;
0
votes
-(void)viewDidLoad {
 // Setup audio session
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

    // Define the recorder setting
    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];

    // Initiate and prepare the recorder
    recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
    recorder.delegate = self;
    recorder.meteringEnabled = YES;
    [recorder prepareToRecord];

}    

- (IBAction)btnRecordDidClicked:(UIButton *)sender {
        if (player1.playing) {
            [player1 stop];
        }

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

            // Start recording
            [recorder record];
            [_recordTapped setTitle:@"Pause" forState:UIControlStateNormal];

        } else {

            // Pause recording
            [recorder pause];
            [_recordTapped setTitle:@"Record" forState:UIControlStateNormal];
        }

        [_stopTapped setEnabled:YES];
        [_playTapped setEnabled:NO];

    }

    - (IBAction)btnPlayDidClicked:(UIButton *)sender {
        if (!recorder.recording){
            player1 = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
            [player1 setDelegate:self];
            [player1 play];
        }
    }

    - (IBAction)btnStopDidClicked:(UIButton *)sender {
        [recorder stop];
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setActive:NO error:nil];
    }

    - (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
        [_recordTapped setTitle:@"play" forState:UIControlStateNormal];

        [_stopTapped setEnabled:NO];
        [_playTapped setEnabled:YES];

    }
0
votes

As per the above answers, I made some changes and I got the correct output.

Step 1: Under "inf.plist" add the Microphone usage permissions ==>

  <key>NSMicrophoneUsageDescription</key>
  <string>${PRODUCT_NAME} Microphone Usage</string>

Step 2:

  1. Save record audio file into Local Document Directory

  2. Play/Stop recording

  3. Get the Duration of Saved audio file

Here is the source code. Please have a look at once and use it.

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController{
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

ViewController.m

#import "ViewController.h"
@interface ViewController () <AVAudioRecorderDelegate, AVAudioPlayerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

-(IBAction) startRecording{
// Setup audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err)
{
    NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
    return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err)
{
    NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
    return;
}
AVAudioSessionRecordPermission permissionStatus = [audioSession recordPermission];
switch (permissionStatus) {
    case AVAudioSessionRecordPermissionUndetermined:{
        [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
            // CALL YOUR METHOD HERE - as this assumes being called only once from user interacting with permission alert!
            if (granted) {
                // Microphone enabled code
                NSLog(@"Mic permission granted.  Call method for granted stuff.");
                [self startRecordingAudioSound];
            }
            else {
                // Microphone disabled code
                NSLog(@"Mic permission indeterminate. Call method for indeterminate stuff.");
                //        UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
            }
        }];
        break;
    }
    case AVAudioSessionRecordPermissionDenied:
        // direct to settings...
        NSLog(@"Mic permission denied. Call method for denied stuff.");

        break;
    case AVAudioSessionRecordPermissionGranted:
        // mic access ok...
        NSLog(@"Mic permission granted.  Call method for granted stuff.");
        [self startRecordingAudioSound];
        break;
    default:
        // this should not happen.. maybe throw an exception.
        break;
}
}

#pragma mark - Audio Recording
- (BOOL)startRecordingAudioSound{
NSError *error = nil;
NSMutableDictionary *recorderSettings = [[NSMutableDictionary alloc] init];
[recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
[recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

// Create a new audio file
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
NSLog(@"the path is %@",pathToSave);

// File URL
NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];

//Save recording path to preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setURL:url forKey:@"Test1"];
[prefs synchronize];

audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&error];
if (!audioRecorder)
{
    NSLog(@"Error establishing recorder: %@", error.localizedFailureReason);
    return NO;
}

// Initialize degate, metering, etc.
audioRecorder.delegate = self;
audioRecorder.meteringEnabled = YES;
//self.title = @"0:00";

if (![audioRecorder prepareToRecord])
{
    NSLog(@"Error: Prepare to record failed");
    //[self say:@"Error while preparing recording"];
    return NO;
}

if (![audioRecorder record])
{
    NSLog(@"Error: Record failed");
    //  [self say:@"Error while attempting to record audio"];
    return NO;
}
NSLog(@"Recroding Started");
return YES;
}

#pragma mark - AVAudioRecorderDelegate
- (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
NSLog (@"audioRecorderDidFinishRecording:successfully:");
}

#pragma mark - AVAudioPlayerDelegate
- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog (@"audioPlayerDidFinishPlaying:successfully:");
}

- (NSString *) dateString {
// return a formatted string for a file name
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"ddMMMYY_hhmmssa";
return [[formatter stringFromDate:[NSDate date]]stringByAppendingString:@".aif"];
}

-(IBAction) stopRecording{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording{
//Load recording path from preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSURL *temporaryRecFile = [prefs URLForKey:@"Test1"];

//Get Duration of Audio File
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:temporaryRecFile options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
NSLog(@"Duration Of Audio: %f", audioDurationSeconds);

audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
audioPlayer.delegate = self;
[audioPlayer setNumberOfLoops:0];
audioPlayer.volume = 1;
[audioPlayer prepareToPlay];
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
 }

 @end