10

我的iPhone应用程序使用“AVAudioRecorder”进行录音。它还使用“UIImagePickerController”记录电影和“MPMoviePlayerController”播放电影。AVAudioRecorder不会记录IF电影以前录制和播放

一切工作正常,直到我做三件事成一排:

  1. 录制电影中使用的UIImagePickerController
  2. 播放使用的MPMoviePlayerController
  3. 尝试拨打语音使用记录AVAudioRecorder
  4. 录制的动画

当我在步骤3中调用AVAudioRecorder的“记录”方法时,它返回NO指示失败,但没有提示为什么(来自Appl e!)AVAudioRecorder的audioRecorderEncodeErrorDidOccur委托方法永远不会被调用,并且在设置录像机时我不会收到其他错误。

我的第一个猜测是电影录制/播放正在修改“AVAudioSession”的共享实例,使得它阻止了录音机的工作。但是,我手动将AVAudioSession的category属性设置为“AVAudioSessionCategoryRecord”,并且在尝试录制之前使音频会话处于活动状态。

这里是我创造的记录方法:

- (void)createAudioRecorder 
{ 
NSError *error = nil; 
AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
[audioSession setCategory:AVAudioSessionCategoryRecord error:&error]; 
if (error) 
    ... 
[audioSession setActive:YES error:&error]; 
if (error) 
    ... 

NSMutableDictionary *settings = [[NSMutableDictionary alloc] init]; 

// General Audio Format Settings 
[settings setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey]; 
[settings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[settings setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; 

// Encoder Settings 
[settings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey]; 
[settings setValue:[NSNumber numberWithInt:96] forKey:AVEncoderBitRateKey]; 
[settings setValue:[NSNumber numberWithInt:16] forKey:AVEncoderBitDepthHintKey]; 

// Write the audio to a temporary file 
NSURL *tempURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"Recording.m4a"]]; 

audioRecorder = [[AVAudioRecorder alloc] initWithURL:tempURL settings:settings error:&error]; 
if (error) 
    ... 

audioRecorder.delegate = self; 
if ([audioRecorder prepareToRecord] == NO) 
    NSLog(@"Recorder fails to prepare!"); 

[settings release]; 
} 

,这里是我的方法开始录音:

- (void)startRecording 
{ 
if (!audioRecorder) 
    [self createAudioRecorder]; 

NSError *error = nil; 
[[AVAudioSession sharedInstance] setActive:YES error:&error]; 
if (error) 
    ... 

BOOL recording = [audioRecorder record]; 
if (!recording) 
    NSLog(@"Recording won't start!"); 
} 

有没有人碰到这个问题?

回答

14

我遇到了同样的问题。之前我固定的问题,我录制/播放代码是这样的:

开始录制功能

- (BOOL) startRecording { 
@try { 
    NSDictionary *recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys: 
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey, [NSNumber numberWithFloat: 44100.0], AVSampleRateKey, [NSNumber numberWithInt: 1], AVNumberOfChannelsKey, [NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey, nil]; 

     NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
     NSString *soundFilePath = [documentsPath stringByAppendingPathComponent:@"recording.caf"]; 

     if(audioRecorder != nil) { 
      [audioRecorder stop]; 
      [audioRecorder release]; 
      audioRecorder = nil; 
     } 

     NSError *err = nil; 
     audioRecorder = [[AVAudioRecorder alloc] initWithURL:soundFileURL settings:recordSetting error:&err]; 
     [soundFileURL release]; 
     [recordSetting release]; 
     if(!audioRecorder || err){ 
      NSLog(@"recorder initWithURL: %@ %d %@", [err domain], [err code], [[err userInfo] description]); 
      return NO; 
     } 

     [audioRecorder peakPowerForChannel:8]; 
     [audioRecorder updateMeters]; 
     audioRecorder.meteringEnabled = YES; 
     [audioRecorder record]; 
    } 
    @catch (NSException * e) { 
     return NO; 
    } 

    recording = YES; 
    return YES; 
} 

停止录制功能

- (BOOL) stopRecording { 
    @try { 
     [audioRecorder stop]; 
     [audioRecorder release]; 
     audioRecorder = nil; 

     recording = NO; 
    } 
    @catch (NSException * e) { 
     return NO; 
    } 

    return YES; 
} 

开始播放功能

- (BOOL) startPlaying { 
    @try { 
     NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
     NSString *soundFilePath = [documentsPath stringByAppendingPathComponent:@"recording.caf"];  NSURL * soundFileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath]; 
     NSError *err = nil; 

     if (audioPlayer) { 
      [audioPlayer release]; 
      audioPlayer = nil; 
     } 

     audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error: &err]; 
     [soundFileURL release]; 
     if (!audioPlayer || err) { 
      NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]); 
      return NO; 
     } 

     [audioPlayer prepareToPlay]; 
     [audioPlayer setDelegate: self]; 
     [audioPlayer play]; 

     playing = YES; 
    } 
    @catch (NSException * e) { 
     return NO; 
    } 

    return YES; 
} 

停止播放功能

- (BOOL) stopPlaying { 
    @try { 
     [audioPlayer stop]; 
     [audioPlayer release]; 
     audioPlayer = nil; 

     playing = NO; 
    } 
    @catch (NSException * e) { 
     return NO; 
    } 

    return YES; 
} 

我固定的记录问题打了拍摄的视频后,代码如下:

- (BOOL) startRecording { 
    @try { 
     AVAudioSession *session = [AVAudioSession sharedInstance]; 
     [session setCategory:AVAudioSessionCategoryRecord error:nil]; 

     // rest of the recording code is the same . 
} 

- (BOOL) stopRecording { 
    @try { 
     AVAudioSession *session = [AVAudioSession sharedInstance]; 
     [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 

    // rest of the code is the same 
} 

- (BOOL) startPlaying { 
    @try { 
     AVAudioSession *session = [AVAudioSession sharedInstance]; 
     [session setCategory:AVAudioSessionCategoryPlayback error:nil]; 

    // rest of the code is the same. 
} 

- (BOOL) stopPlaying { 
    // There is no change in this function 
} 
+0

谢谢,我遇到了同样的问题,无法弄清楚发生错误的时间! – 2011-08-27 16:51:55

+0

谢谢,它有帮助。 – 2013-02-14 07:02:27

0

我在MonoTouch的同样的问题,并调整Monotouch的答案为rmomins

改变

avrecorder.Record(); 

NSError error; 
var avsession = AVAudioSession.SharedInstance(); 
avsession.SetCategory(AVAudioSession.CategoryRecord,out error); 

avrecorder.Record(); 

就像一个魅力。

1

我一直有同样的问题。我使用AVPlayer播放作品(以前使用过AVAudioRecord的录音)。但是,我发现一旦使用AVPlayer,我就无法再使用AVAudioRecorder。经过一番搜索之后,我发现只要AVPlayer在内存中实例化并且至少播放过一次(这通常是在实例化后立即执行的),AVAudioRecorder将不会记录。但是,一旦AVPlayer被解除分配,AVAudioRecorder就可以再次自由记录。看起来,AVPlayer坚持AVAudioRecorder需要的某种连接,并且它是贪婪的......它不会放过它,直到你从它的冷死手中撬出它。

这是我找到的解决方案。有些人声称,实例化AVPlayer需要花费太多时间来继续分解和设置备份。但是,这不是事实。实例化AVPlayer实际上非常简单。所以也是实例化AVPlayerItem。什么不是琐碎正在加载AVAsset(或它的任何子类)。你真的只想这样做一次。他们关键是使用这个序列:

  1. 最多可以装入AVAsset(例如,如果你从文件加载,直接使用AVURLAsset或将其添加到AVMutableComposition和使用),并保持对它的引用。在完成之前不要放过它。加载它是需要所有的时间。
  2. 一旦您准备好玩了:使用您的资产实例化AVPlayerItem,然后使用AVPlayerItem实例化AVPlayer并播放它。不要保留对AVPlayerItem的引用,AVPlayer将保留引用,并且无论如何您都不能在其他播放器中重复使用它。
  3. 一旦完成打,立即销毁 AVPlayer ......松开,设置它的变种为零,无论你需要做的。 **
  4. 现在您可以录制。 AVPlayer不存在,所以AVAudioRecorder可以自由地做它的事情。
  5. 当您准备再次播放时,使用您已经加载的资产重新实例化AVPlayerItem & AVPlayer。再次,这是微不足道的。该资产已经被加载,所以不应该有延迟。

**请注意,销毁AVPlayer可能不仅仅是释放它并将其var设置为零。最有可能的是,您还添加了定期时间观察员来跟踪播放进度。当你这样做时,你会收到一个你应该坚持的不透明物体。如果您不从播放器中删除此项目并释放它/将其设置为零,AVPlayer将不会释放。看起来,Apple创建了一个有意的保留周期,您必须手动中止。你破坏AVPlayer所以,如果你需要(例如):

[_player removeTimeObserver:_playerObserver]; 
[_playerObserver release]; //Only if you're not using ARC 
_playerObserver = nil; 

作为一个侧面说明,你也可能已设置了NSNotifications(我用一个来确定当玩家完成游戏)......不忘记删除这些。

2

有同样的问题。我的解决方案是在开始录制会话之前停止播放电影。我的代码与rmomin的代码类似。

0

我有同样的问题来记录和播放。为了解决这个问题,我记得在“记录”和“播放”功能中的AVAudioSession。

这可能有助于在设备上而不是在模拟器上出现此问题的人!

0

我得到了同样的问题。最后我发现ARC已经发布了我的录音机。因此,您必须在.h文件中声明刻录机,即AVAudioRecord *recorder;。将其他东西放在.m将正常工作。