如何使用 AVAudioRecorder 在 iPhone 上录制音频?

既然 iPhone 3.0 SDK 已经公开了,我想我可以问问那些已经使用过3.0 SDK 的人。我想在我的应用程序中录制音频,但我想使用 AVAudioRecorder,而不是像示例 SpeakHere显示的旧的录制方式。在 iPhoneDev Center 中没有任何示例说明如何最好地完成这项工作,而且只能引用这些类。我是一个新手在 iPhone 开发,所以我正在寻找一个简单的样本让我开始。

156844 次浏览

事实上,根本没有例子。 这是我的工作代码。录音是由用户按下导航栏上的一个按钮触发的。 记录采用 cd 质量(44100个样品) ,立体声(2通道)线性 pcm。注意: 如果你想使用不同的格式,尤其是编码格式,请确保你完全了解如何设置 AVAudioRecorder 设置(仔细阅读音频类型文档) ,否则你将永远无法正确初始化它。还有一件事。在代码中,我没有展示如何处理测量数据,但是您可以很容易地找到它。 最后,请注意,AVAudioRecorder 方法 delete teRecoring 在编写本文时使应用程序崩溃。这就是为什么我通过文件管理器删除记录的文件。录制完成后,我使用 KVC 将录制的音频作为 NSData 保存在当前编辑的对象中。

#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


}

好吧,所以我得到的答案帮助我在正确的方向,我非常感激。它帮助我弄清楚如何在 iPhone 上实际录音,但我想我也应该包括一些有用的代码,我从 iPhone 参考图书馆:

音像科技

我使用了这段代码,并相当容易地将其添加到 avTouch 示例中。有了上面的代码示例和来自参考库的示例,我就能够很好地使用它。

在下面的链接中,你可以找到关于使用 AVAudioRecord 录音的有用信息。在这个链接的第一部分“使用音频”有一个锚名为“录制与 AVAudioRecorder 类。”这就引出了这个例子。

音视频概念多媒体

真的很有帮助。我唯一的问题是录音后创建的声音文件的大小。我需要减少文件大小,所以我做了一些设置的变化。

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];

文件大小从360kb 减少到25kb (2秒记录)。

虽然这是一个回答的问题(有点老) ,我已经决定张贴我的全部工作代码,其他人发现它很难找到好的工作(盒子外)播放和录音示例-包括编码,pcm,播放通过扬声器,写到这里的文件:

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

希望这个对你们有帮助。

在过去的两个小时里,我一直在尝试让这段代码工作,尽管在模拟器上没有显示错误,但是在设备上有一个错误。

结果是,至少在我的案例中,错误来自 used 目录(bundle) :

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

它不是可写的或类似的东西... 没有错误,除了 prepareToRecord 失败..。

因此,我将其替换为:

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

现在就像魔法一样。

希望这能帮到其他人。

我已经上传了一个样本项目。你可以看看。

录音机

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;
}
}

开始

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];
}

别说了

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;

在音频设置下的波形格式

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];

参考文献: Http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html

非常感谢 @ Massimo Cafaro和《强大》 Shaybc 我能完成以下任务

在 iOS8中:

录音及储存

播放保存的录音

1. 在项目中添加“ AVFoundation.Framework”

在.h 文件中

2. 添加以下导入语句‘ AVFoundation/AVFoundation.h’。

3. 定义“ AVAudioRecorderGenerate”

4. 创建一个包含“录制”、“播放”按钮及其操作方法的布局

5、定义录音机和播放器等。

下面是完整的示例代码,可能对您有所帮助。

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

那就把活干完

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

-(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: 在“ inf.plist”下添加麦克风使用权限 = = >

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

第二步:

  1. 将记录音频文件保存到本地文档目录中

  2. 播放/停止录音

  3. 获取保存音频文件的持续时间

这是源代码。请看一下并使用它。

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

这些答案都在 Objective-C 中,这是 斯威夫特中的答案。这里唯一没有包含的是 pList麦克风许可,它是允许记录所必需的。

这些步骤在17条评论中列出

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)
}
}