AVAudioRecorder record AAC/m4a

一曲冷凌霜 提交于 2019-11-30 02:09:31

The iOS SDK is apparently stupid. Setting the format ID key to kAudioFormatMPEG4AAC is not enough for it to actually encode the file; in QuickTime it will play but in its properties you'll just see AAC and no further details. Changing the output file extension to m4a should help do the trick and make it apply the right encoding.

Scott Miller

For hardware-accelerated encoders, only one session can be active at any given time. This means that, for AAC, it will work in the simulator (where a software encoder is used) but might fail on the device (where a hardware encoder is used) unless your app activates the AVAudioSession.

I also was attempting to use AVAudioRecorder to record audio in an AAC encoded format preferably in a .m4a file. I had a beast of a time doing this. I was quickly able to get the code to record to AAC inside of a core audio file (.caf), but I couldn't get AVAudioRecorder to properly format a .m4a. I was just about to rewrite the recording code in my application using the lower level Audio Units API but instead I put that on the back burner and added in the code to handle the shared audio session. Once that was set up, I went back and tried to save as an .m4a and it just worked.

Here is some example code:

NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSURL *tmpFileUrl = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:@"tmp.m4a"]];
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                        [NSNumber numberWithFloat:16000.0], AVSampleRateKey,
                        [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                        nil];
NSError *error = nil;
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:tmpFileUrl settings:recordSettings error:&error];
[recorder prepareToRecord];

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
[session setActive:YES error:nil];

[recorder record];

Then to end the recording I used:

[recorder stop];
AVAudioSession *session = [AVAudioSession sharedInstance];
int flags = AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation;
[session setActive:NO withFlags:flags error:nil];

Then the file at 'tmpFileUrl' can be used as you please.

The hints about AVAudioSession are very helpful!

Since setActive:withFlags:error: has become deprecated in iOS 6.0 the code for stopping audio session should be adjusted to:

AVAudioSession *session = [AVAudioSession sharedInstance];
int flags = AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation;
[session setActive:NO withOptions:flags error:nil];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!