AVfoundation无法在iOS 5中录制音频
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVfoundation无法在iOS 5中录制音频相关的知识,希望对你有一定的参考价值。
我在尝试构建一个简单的录音功能时遇到了一些重大麻烦,我不知道为什么。我已经按照一些代码(从这里和其他地方)来构建一个非常简单的录音机和播放,但没有任何作用。我已经采用了适用于ios 4.3的示例代码,并且当我单独运行它时工作正常,但是只要我将它带到iOS 5并使用ARC,就没有任何反应。该应用程序运行,但没有录制音频......任何想法都会很棒!谢谢...附上我所有的代码。这是来自此处示例的代码。
record_audio_testViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
@interface record_audio_testViewController : UIViewController <AVAudioRecorderDelegate> {
IBOutlet UIButton * btnStart;
IBOutlet UIButton * btnPlay;
IBOutlet UIActivityIndicatorView * actSpinner;
BOOL toggle;
//Variables setup for access in the class:
NSURL * recordedTmpFile;
AVAudioRecorder * recorder;
NSError *__autoreleasing * error;
AVAudioSession * audioSession;
}
@property (nonatomic,retain)IBOutlet UIActivityIndicatorView * actSpinner;
@property (nonatomic,retain)IBOutlet UIButton * btnStart;
@property (nonatomic,retain)IBOutlet UIButton * btnPlay;
@property (nonatomic,strong) AVAudioSession * audioSession;
@property (nonatomic,strong) AVAudioRecorder * recorder;
- (IBAction) start_button_pressed;
- (IBAction) play_button_pressed;
@end
record_audio_testViewController.m
#import "record_audio_testViewController.h"
@implementation record_audio_testViewController
@synthesize actSpinner, btnStart, btnPlay, audioSession, recorder;
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//Start the toggle in true mode.
toggle = YES;
btnPlay.hidden = YES;
//Instanciate an instance of the AVAudioSession object.
audioSession = [AVAudioSession sharedInstance];
//Setup the audioSession for playback and record.
//We could just use record and then switch it to playback leter, but
//since we are going to do both lets set it up once.
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: error];
//Activate the session
[audioSession setActive:YES error: error];
NSLog(@"%@",error);
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (IBAction) start_button_pressed{
if(toggle)
{
toggle = NO;
[actSpinner startAnimating];
[btnStart setTitle:@"Stop Recording" forState: UIControlStateNormal ];
btnPlay.enabled = toggle;
btnPlay.hidden = !toggle;
//Begin the recording session.
//Error handling removed. Please add to your own code.
//Setup the dictionary object with all the recording settings that this
//Recording sessoin will use
//Its not clear to me which of these are required and which are the bare minimum.
//This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/
NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
//Now that we have our settings we are going to instanciate an instance of our recorder instance.
//Generate a temp file for use by the recording.
//This sample was one I found online and seems to be a good choice for making a tmp file that
//will not overwrite an existing one.
//I know this is a mess of collapsed things into 1 call. I can break it out if need be.
recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"caf"]]];
NSLog(@"Using File called: %@",recordedTmpFile);
//Setup the recorder to use this file and record to it.
NSLog(@"%@",error);
recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:error];
NSLog(@"%@",error);
//Use the recorder to start the recording.
//Im not sure why we set the delegate to self yet.
//Found this in antother example, but Im fuzzy on this still.
[recorder setDelegate:self];
//We call this to start the recording process and initialize
//the subsstems so that when we actually say "record" it starts right away.
[recorder prepareToRecord];
//Start the actual Recording
[recorder record];
//There is an optional method for doing the recording for a limited time see
//[recorder recordForDuration:(NSTimeInterval) 10]
}
else
{
toggle = YES;
[actSpinner stopAnimating];
[btnStart setTitle:@"Start Recording" forState:UIControlStateNormal ];
btnPlay.enabled = toggle;
btnPlay.hidden = !toggle;
NSLog(@"Using File called: %@",recordedTmpFile);
//Stop the recorder.
[recorder stop];
}
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
-(IBAction) play_button_pressed{
//The play button was pressed...
//Setup the AVAudioPlayer to play the file that we just recorded.
AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:error];
[avPlayer prepareToPlay];
[avPlayer play];
NSLog(@"%@",error);
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
//Clean up the temp file.
NSFileManager * fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[recordedTmpFile path] error:error];
//Call the dealloc on the remaining objects.
}
@end
viewController.h
#import <UIKit/UIKit.h>
#import "record_audio_testViewController.h"
@interface ViewController : UIViewController{
record_audio_testViewController *audioControl;
}
@end
viewController.m
#import "ViewController.h"
#import "record_audio_testViewController.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
audioControl = [[record_audio_testViewController alloc] init];
[self.view addSubview:audioControl.view];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end
(1)这可能与你的问题无关,但我很惊讶这甚至编译:
NSError *__autoreleasing * error; // ivar
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: error];
那是无法谈论的。 error
应该是一个局部变量,你应该拿它的地址,你没有业务标记为自动释放:
NSError *error;
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
(2)除非你像VoIP应用程序一样,否则不要使用PlayAndRecord。如果您要执行的操作是录制,则您的音频会话策略应为“录制”,并且仅在您实际录制时。
我很抱歉,如果这些都没有解决问题,但它们可能是你应该首先解决的问题。
以上是关于AVfoundation无法在iOS 5中录制音频的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在不使用 AVFoundation 框架的情况下在 iOS 中录制音频?
Swift IOS 使用 AVFoundation 录制视频和音频
Objective-C:在 iOS 上使用 AVFoundation 录制视频时静音/取消静音
xcode:如何在使用 AVFoundation 录制音频后保存音频文件