iPhone SDK:调用[AVPlayer播放]后AVAudioRecorder不会录制

时间:2011-03-17 21:14:59

标签: iphone avaudiorecorder avplayer

我有一个使用AVPlayer的视图控制器。此视图控制器可以加载模态视图控制器,用户可以使用AVAudioRecorder录制音频。

这是发生的事情:

如果用户使用[AVPLayer播放]在第一个控制器中播放合成,AVAudioRecorder将不会在模态视图控制器中录制。没有错误,但AVAudioRecorder返回的当前时间是0.0;

如果用户解除模态对话框并重新加载它。 AVAudioRecorder工作正常。

这可以一遍又一遍地重复 AVAudioRecorder在[AVPlayer播放]调用

之后第一次调用时不起作用

我已经和它斗争了好几天,只是重新组织了与AVPlayer和AVAudioRecorder相关的代码,它仍然表现得很奇怪。

非常感谢任何帮助或指针

提前致谢

让 - 皮埃尔

7 个答案:

答案 0 :(得分:9)

我也遇到了同样的问题,这是我找到的解决方案。

录制时,请在AVAudioRecord初始化后写下此行代码:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:NULL];

然后调用record方法。

答案 1 :(得分:3)

您如何设置AVAudioSession的类别,即播放或录制?尝试像

这样的东西
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

答案 2 :(得分: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 ...释放它,将其var设置为nil,无论你需要做什么。 **
  4. 现在你可以录制了。 AVPlayer不存在,因此AVAudioRecorder可以随心所欲。
  5. 当您准备再次播放时,使用您已加载的资产重新实例化AVPlayerItem& AVPlayer。同样,这是微不足道的。资产已经加载,所以不应该有延迟。
  6. **请注意,销毁AVPlayer可能需要的不仅仅是释放它并将其var设置为nil。最有可能的是,您还添加了一个定期时间观察器来跟踪播放进度。执行此操作时,您将收到一个您应该保留的不透明对象。如果您没有从播放器中删除此项并将其释放/设置为nil,则AVPlayer将不会取消激活。 Apple似乎创建了一个有意保留的循环,您必须手动中断。所以在你破坏AVPlayer之前你需要(例子):

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

    作为附注,您可能还设置了NSNotifications(我用一个确定播放器何时完成播放)...不要忘记删除它们。

答案 3 :(得分:1)

如果您需要同时使用AVPlayer和AVAudioRecorder,请执行以下操作:

  1. 将音频类别设置为“播放和录制”(如上所述或使用基于C的音频会话功能)
  2. “record”方法必须在调用“play”方法后调用一些延迟。 (我设定0.5秒)
  3. 如果您不提供此功能,将开始播放,但不会开始录制。

答案 4 :(得分:0)

不应该是[AVAudioRecorder record];而不是play

答案 5 :(得分:0)

我遇到了同样的问题:AVAudioRecorder没有开始录制。 我的例子有点不同:我有一个基于tabbar的应用程序,在不同的视图中有几个AVAudioPlayers。为了举例,假设第一个加载的视图有3个AVAudioPlayers,而第二个视图有一个AVAudioPlayer和一个AVAudioRecorder。它们都是在viewDidLoad方法中启动的。

录像机未在第二个视图中工作。当我按下录制按钮时,视图略微抖动,录制没有开始。 奇怪的是,模拟器运行良好,并没有表现出相同的症状......(任何人都知道为什么?)

经过一些研究和阅读这个帖子后,我意识到我没有将第一个视图中的玩家设置为nil,所以我猜他们仍然在内存中阻止录音机启动。一旦我在viewDidDisappear方法中将它们设置为nil,它再次正常工作。

这是帮助我的原因:

-(void)viewDidDisappear:(BOOL)animated {
    firstPlayer = nil;
    secondPlayer = nil;
    thirdPlayer = nil;
}

ViewDidUnload没有帮助因为View,因此在切换视图时没有卸载类本身的变量。

希望这对其他人也有用。

答案 6 :(得分:0)

@Aaron Hayman的解释是准确的,但对我来说解决方案非常简单。只需实现播放器委托的didFinishPlaying方法并在那里释放播放器。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    self.playerWord = nil;
}