AVAudioRecorder 和 AVAudioPlayer
Posted
技术标签:
【中文标题】AVAudioRecorder 和 AVAudioPlayer【英文标题】:AVAudioRecorder and AVAudioPlayer 【发布时间】:2012-05-15 17:35:27 【问题描述】:现在是第三天,我仍然无法播放。我一直在关注一些关于 AVAudioPlayer/AVAudioRecorder 的教程。使用 NSFileManager 看起来像是创建了一个文件,但播放时没有骰子。
RecorderViewController.m
// RecorderViewController.m
// AudioTest
//
#import "RecorderViewController.h"
#import <Foundation/Foundation.h>
@interface RecorderViewController ()
@end
@implementation RecorderViewController
@synthesize userIsRecording, filePath, activityView, recordButton, playButton, recorder;
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
return self;
*/
+ (CGRect)makeCGRectWithCenter:(CGPoint)center width:(float)width height:(float)height
return CGRectMake(center.x-width/2, center.y-height/2, width, height);
#pragma mark - Preparation
- (void)loadView
// RECORD BUTTON
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.recordButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.recordButton.frame = [[self class] makeCGRectWithCenter:CGPointMake(self.view.frame.size.width/2, 100) width:150 height:50];
[self.recordButton setTitle:@"Record" forState:UIControlStateNormal];
[self.recordButton addTarget:self action:@selector(recordPressed) forControlEvents:UIControlEventTouchUpInside];
// PLAY BUTTON
self.playButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.playButton.frame = [[self class] makeCGRectWithCenter:CGPointMake(self.view.frame.size.width/2, 200) width:150 height:50];
[self.playButton setTitle:@"Play" forState:UIControlStateNormal];
[self.playButton addTarget:self action:@selector(playPressed) forControlEvents:UIControlEventTouchUpInside];
// RETURN BUTTON
UIButton *returnButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
returnButton.frame = [[self class] makeCGRectWithCenter:CGPointMake(self.view.frame.size.width/2, 300) width:150 height:50];
[returnButton setTitle:@"Return" forState:UIControlStateNormal];
[returnButton addTarget:self action:@selector(dismissPressed:) forControlEvents:UIControlEventTouchUpInside];
// ACTIVITY
self.activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityView.frame = [[self class] makeCGRectWithCenter:CGPointMake(self.view.frame.size.width/2, 50) width:100 height:100];
[self.view addSubview:self.recordButton];
[self.view addSubview:self.playButton];
[self.view addSubview:returnButton];
[self.view addSubview:self.activityView];
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(@"View did load");
filePath = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"temp2.caf"]];
// Setup Audiosession
AVAudioSession *avSession = [AVAudioSession sharedInstance];
[avSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];
[avSession setActive:YES error: NULL];
self.playButton.hidden = YES;
#pragma mark - Button Actions
- (void)dismissPressed:(id)sender
if ([sender isKindOfClass:[UIButton class]])
NSLog(@"Button class dismissed self");
else
NSLog(@"Sender is:%@", [sender class]);
[self dismissModalViewControllerAnimated:YES];
- (void)stopPressed
NSLog(@"Stop Pressed");
[self.recordButton setTitle:@"Record" forState:UIControlStateNormal];
self.userIsRecording = NO;
self.playButton.hidden = NO;
self.playButton.enabled = YES;
[self.activityView stopAnimating];
//
- (void)recordPressed
if (self.userIsRecording)
[self stopPressed];
else
self.userIsRecording = YES;
self.playButton.enabled = NO;
self.playButton.hidden = YES;
[self.recordButton setTitle:@"Stop" forState:UIControlStateNormal];
[self.activityView startAnimating];
NSDictionary *recorderSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithInt:AVAudioQualityMin], AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16], AVEncoderBitRateKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithFloat:8000.0], AVSampleRateKey,
[NSNumber numberWithInt:8], AVLinearPCMBitDepthKey, nil];
// Clean temp file
NSFileManager * fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[self.filePath path] error:NULL];
// Record
NSError *error = [NSError alloc];
self.recorder = [[AVAudioRecorder alloc] initWithURL:self.filePath settings:recorderSettings error:&error];
[recorder setDelegate:self];
[recorder prepareToRecord];
if (![recorder record])
NSLog(@"Recorder FAIL %@", error );
else
NSLog(@"Recording at %@", [self.filePath absoluteString]);
- (void)playPressed
NSFileManager * fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:[self.filePath path]])
NSLog(@"File exists at:%@", [self.filePath path]);
NSDictionary *attr = [fm attributesOfItemAtPath:[self.filePath path] error:NULL];
NSLog(@"File attrs:%@", [attr description]);
else
NSLog(@"ERROR: No file exists at:%@", [self.filePath path]);
NSError *error = [[NSError alloc] init];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:[[NSData alloc] initWithContentsOfURL:self.filePath] error: &error];
[player setDelegate:self];
if (error)
NSLog(@"Player initialization Error: %@", error);
if (!player)
NSLog(@"Player is null!");
[player prepareToPlay];
if (![player play])
NSLog(@"Play Error: %@", error);
#pragma mark - Lifecycle
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
NSLog(@"View did unload");
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return (interfaceOrientation == UIInterfaceOrientationPortrait);
@end
【问题讨论】:
我在您的- (void)playPressed
中看到您调用[player prepareToPlay]
,但我实际上并没有看到您告诉它播放。 prepareToPlay 只是让它准备好了。也许我在您的代码中遗漏了它,或者您没有发布所有内容。只是我的快速观察。
有点隐藏在逻辑中:if (![player play]) NSLog(@"Play Error: %@", error);
对不起,我对编程还是有点陌生,但是 if 语句不是说“如果玩家没有玩,则显示此错误消息”吗?在[player prepareToPlay]
之后,你仍然需要在里面说[player play];
。
如果您是编程新手,请尝试示例代码SpeakHere 并根据您的需要进行修改。
您是否已将 AVFoundation 框架添加到您的项目并导入到您的 .h 文件中? #import <AVFoundation/AVFoundation.h>
【参考方案1】:
[player prepareToPlay];
if (![player play])
NSLog(@"Play Error: %@", error);
“准备播放”后立即播放文件。缓冲区可能在那一刻还没有准备好。做这个测试。将AVAudioPlayer *player
声明为全局。从- (void)playPressed
中删除if (![player play])...
。现在创建一个将在其他按钮按下时调用的新方法。按播放按钮,等待几秒钟,然后按另一个按钮。
【讨论】:
以上是关于AVAudioRecorder 和 AVAudioPlayer的主要内容,如果未能解决你的问题,请参考以下文章