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.

- 17,446
- 6
- 47
- 96

- 1,777
- 4
- 12
- 9
14 Answers
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
}

- 19,381
- 28
- 133
- 216

- 25,429
- 15
- 79
- 93
-
I think I am close to getting your code to work, but I am struggling with the delegate stuff. I am pretty new to Objective C and still have not gotten my head around the proper way to do the delegate for something like this. I have my delegate trying to implement NSObject
, but I don't think I am doing it right. Would it be too much trouble to post the delegate code also? Thanks. – Jim Zimmerman Jun 19 '09 at 01:21 -
I just finally got it working by adding this to my delegate class @protocol AVAudioRecorder @optional - (void)audioRecorderBeginInterruption:(AVAudioRecorder *)recorder; - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag; - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error; - (void)audioRecorderEndInterruption:(AVAudioRecorder *)recorder; It seems to work, but I don't know if this is best practice or not. Now I need to persist it to a local data store and play it back among other things. – Jim Zimmerman Jun 19 '09 at 01:54
-
Thats not right Jim. In your recorder controller header you would do something like... #import
@interface RecorderViewController : UIViewController – dizy Jun 19 '09 at 05:16{ -
Thanks. This is probably the only good piece of code on the internet for recording. However using this code gives me a mono playback when I play the recorded file. I have specified the number of channels as 2 in the record settings but don't get a stereo playback. Any ideas? – lostInTransit Oct 13 '09 at 15:54
-
8some questions: editedObject & editedFieldKey in stopRecording undefined. Can you give me some lights? – Raptor Sep 21 '10 at 02:58
-
@unforgiven hey have idea how to save playing sound in AVAudioPlayer ? not Surrounding || Mic-in sound. – AJPatel Mar 10 '12 at 07:15
-
with the help of this code how can i record .amr file format tell me please – Abhishek Apr 23 '12 at 11:15
-
@Massimo Cafaro , can we record current playing file in iphone. – Prince Kumar Sharma Feb 25 '13 at 11:13
-
I'm curious why you use `now = [NSDate dateWithTimeIntervalSinceNow:0]`, rather than just `now = [NSDate date]`. Are they not functionally the same? – Olie Jul 15 '13 at 21:34
-
1@Olie, they are functionally the same. I adapted my original code in which I was not using the current date, so I had already in my code a statement like recordingDate = [NSDate dateWithTimeIntervalSinceNow:lastEvent]. I just changed it to the one you saw in the code snippet, but, being lazy, I did not rewrite the statement ;-) – Massimo Cafaro Jul 16 '13 at 07:04
-
@Raptor editedObject is NSMutableDictionary & editedFieldKey is Key for that Dictionary Consider NSMutableDictionary=[editedObject setValue:[NSData dataWithContentsOfURL:url] forKey:@"editedFieldKey"]; Hope this will help you. – Vaibhav Limbani Mar 29 '14 at 05:18
-
@MassimoCafaro how i audio record when app is background ?. i have tested your code it is not working on background mode. – Yogendra Girase Jun 29 '17 at 10:17
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.

- 232,980
- 40
- 330
- 338

- 2,628
- 29
- 43
-
Hello, When I build and run the second code provided by ShayBC on iphone simulator, I don't get any results but in console it shows that it's working. Does the Iphone simulator use my laptop's speaker and microphone or is it mute and I have to build the app on device? – Jan 19 '11 at 00:31
-
1@Bataly the iphone simulator will play your sound files (mp3 / caf...) and can record through your laptop mic try looking into leopard System Preferences if there are problems, but the best way to test your app is to run it on a real iDevice, and its a good idea for all code you write since there are allot of apps being rejected from the app-store due to crash since they never been tested on a real iDevice, there are more features that are not supported by the simulator (bluetooth, camera, proper multitouch, accelerometer, IAP, GPS, it will have a better performance then the most iDevice...) – Shaybc Feb 19 '11 at 09:45
-
[recordSettings setObject:formatObject forKey: AVFormatIDKey]; This line won't let me use AVFormatIDKey as a key. What gives? If I set it to another value it works... – jspooner Apr 20 '11 at 02:28
-
@Shaybc : not working for me..am using the same code, only modified to include the 1st 10 seconds incase of recording.... any suggestions ? – Ahsan May 29 '11 at 20:09
-
I found that recordEncoding = ENC_AAC; in the viewDidLoad method is the cause of your issue. Try other format, other formats work for me, but not kAudioFormatMPEG4AAC. Not sure why though. – joe kirk Oct 04 '11 at 11:04
-
4Lastest findings, for kAudioFormatMPEG4AAC, we cannot set AVEncoderBitRateKey to 12800. Comment off the line and it will work. Will try to find out what should be the correct bit rate for AAC. – joe kirk Oct 04 '11 at 11:21
-
Ignore this comment, I am bookmarking your answer. Works great in iOS 5 with minor changes – William Entriken Mar 31 '12 at 04:00
-
Hmm. Isn´t there a memory leak at "NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] initWithCapacity:10];"? recordSettings doesn´t seem to be released anywhere? – Olof Aug 30 '12 at 09:55
-
11I don't think you can write to the bundle so I write to Documents like this: NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = paths[0]; NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", basePath]]; – marxy Jun 01 '13 at 06:49
-
This example code has a major mistake of writing audio file to the bundle resource URL. Check the correction provided by @marxy – CodeBrew Mar 02 '18 at 03:58
I have uploaded a sample project. You can take a look.
-
Just in case you don't find the download: Go to 'Downloads' in the upper right corner and then to 'DOWNLOAD PACKAGES' – Philipp Schlösser Oct 02 '11 at 15:10
-
-
@user523234: here is the download url - https://github.com/AvinashP/VoiceRecorder/downloads#download_128004 – rajt Dec 07 '11 at 09:27
-
2The sample code does not compile as noted in the Github issues 6 months ago. – Dewayne Nov 17 '12 at 03:26
-
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).

- 3,175
- 3
- 30
- 36

- 433
- 6
- 16
-
can you post the rest of your code as well? cause i think i am missing somethong. I tried changing many settings but am unable to reduce the file size.. – Swapnil Luktuke May 21 '11 at 18:05
-
1I have uploaded a sample project. You can take a look. https://github.com/AvinashP/VoiceRecorder – Avinash Sep 09 '11 at 05:52
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.

- 81
- 1
- 2
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
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:
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.

- 4,875
- 4
- 32
- 50

- 1,777
- 4
- 12
- 9
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,337
- 33
- 43
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

- 81
- 4
-
Thanks bro, this is ur code in Swift : `let recordSettings:[String:AnyObject] = [ AVFormatIDKey:Int(kAudioFormatLinearPCM), AVLinearPCMIsFloatKey:false, AVLinearPCMIsBigEndianKey:0, AVLinearPCMIsNonInterleaved:false, AVSampleRateKey:44100.0, AVNumberOfChannelsKey:2, AVEncoderBitRateKey:12800, AVLinearPCMBitDepthKey:16, AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue] ` – Husam Oct 12 '15 at 11:26
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.
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;

- 4,026
- 39
- 44
-(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];
}

- 1,688
- 14
- 28
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:
Save record audio file into Local Document Directory
Play/Stop recording
- 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

- 2,225
- 2
- 24
- 36
-
Don't use `-[NSUserDefaults synchronize]`. From [Apple's documentation](https://developer.apple.com/documentation/foundation/nsuserdefaults/1414005-synchronize?language=objc) _"this method is unnecessary and shouldn't be used."_ – Ashley Mills Oct 11 '18 at 14:28
-
Thanks man! This answer needs to be higher up since recent iOS versions require that privacy info in the info.plist file. Also, FYI to any other iOS newbies who stumble across this: You can open "Info.plist" and then just right-click the background near the bottom of the file, hit "Add row", and paste in "NSMicrophoneUsageDescription" – Debug Arnaut Dec 28 '20 at 22:08
These answers are all in Objective-C, here is an answer in Swift. The only thing not included here are the pList Microphone Permissions that are necessary to allow recording.
The steps are laid out in 17 comments
class ViewController: UIViewController {
var arrOfRecordingUrls: [URL]() // 0. this is for the recordings once you stop recording in step 15. What you do with the recordings afterwards is up to to you.
var micRecorder: AVAudioRecorder? // 1. AVAudioRecorder instance that you will initialize every time you start to record in step 6
override func viewDidLoad() {
super.viewDidLoad()
// 2. set the AudioSession - you should make sure that the user has accepted the microphone permissions in your info.pList sometime before this
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: .defaultToSpeaker)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error.debugDescription)
}
}
// 3. recordButton - if the micRecorder is nil start a recording, if not then a recording is currently taking place so stop it
@IBAction func recordButtonTapped(_ sender: Any) {
if micRecorder == nil {
startMicRecording()
} else {
stopMicRecording()
}
}
// *** if the pList Mic Permissions aren't granted then this won't work ***
func startMicRecording() {
// 4. create audioSettings
let myAudioSettings: [String:Any] = [AVFormatIDKey: kAudioFormatMPEG4AAC,
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100.0,
AVEncoderBitRateKey: 64000,
AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue
]
// 5. create a file/url which will be where the recording is stored
let dirPath = "\(NSTemporaryDirectory())_Recordings_\(UUID().uuidString).m4a"
let fileURL = URL(fileURLWithPath: dirPath)
do {
// 6. initialize the micRecorder with the audio settings from step 4. and the file/url from step 5
micRecorder = try AVAudioRecorder(url: fileURL, settings: myAudioSettings)
micRecorder?.prepareToRecord() // 7. prepare the micRecorder
micRecorder?.delegate = self // 8. set the delegate so that you can access the recording file/url from step 5 once you are done
micRecorder?.isMeteringEnabled = true // optional
micRecorder?.record() // 9. call .record() to start recording
} catch {
print(error.localizedDescription)
}
}
func stopMicRecording() {
micRecorder?.stop() // 10. call .stop() to stop the recording. At this point the delegate methods from step 12/13/17 will be where the recording output (file/url from step 5) will end up
micRecorder = nil // 11. set the micRecorder to nil
}
}
// 12. set the AVAudioRecorderDelegate which is the .delegate = self from step 8
extension ViewController: AVAudioRecorderDelegate {
// your recording should end up here
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
// 13. if the recording was successful this flag will be true
if flag {
// 14. the file/url from step 5 which is the recording
let successfullyRecordedURL = recorder.url
// 15. add the file/url to the array from step 0.
arrOfRecordingUrls.append(successfullyRecordedURL)
} else {
// 16. the flag was false something went wrong with the recording ???
}
}
// 17. if an error occurs while encoding it will be reported to the delegate
func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
guard let error = error else { return }
print(error.localizedDescription)
}
}

- 17,576
- 18
- 108
- 256