使用AVPlayer播放视频并同时使用AVAudioRecorder录制声音

时间:2011-12-06 17:17:50

标签: iphone avaudioplayer avplayer recording simultaneous

我在谷歌搜索这个问题很多天了,但我找不到解决我的简单问题的方法。

我正在尝试录制声音时播放视频。没有视频,录制声音效果很好。视频在没有录制的情况下工作正常。

只要我将两者放在一起,录音就会抛出对声音没有反应且视频不再播放的值。 顺便说一下,这只发生在我的设备上(iPhone 4 / iOS5)。在模拟器中一切正常。

这是我的代码的简化版本,位于ViewController中。

// Audio Recorder

NSURL *nullUrl = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat:44100.0],                 AVSampleRateKey,
                          [NSNumber numberWithInt:kAudioFormatAppleLossless], AVFormatIDKey,
                          [NSNumber numberWithInt:1],                         AVNumberOfChannelsKey,
                          [NSNumber numberWithInt:AVAudioQualityMax],         AVEncoderAudioQualityKey,
                          nil];

NSError *recorderError;
_recorder = [[AVAudioRecorder alloc] initWithURL:nullUrl settings:settings error:&recorderError];

if (_recorder)
{
    [_recorder prepareToRecord];
    _recorder.meteringEnabled = YES;
    [_recorder record];

    _levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES];
}


// Video Player

NSURL *url = [[NSBundle mainBundle] URLForResource:@"Video"
                                      withExtension:@"mp4"
                                       subdirectory:nil];

_avPlayer = [[AVPlayer playerWithURL:url] retain];
_avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:_avPlayer] retain];

_avPlayerLayer.frame = self.view.layer.bounds;
[self.view.layer addSublayer:_avPlayerLayer];

[_avPlayer play];

录音机只输出一个在levelTimerCallback方法中读取的值。 该视频只播放一段视频。

我发现我必须为AVAudioSession设置一个类别。 如果我在应用程序启动后实现此代码,视频正在播放,但录制器仍会输出相同的值而不会对声音做出反应。

NSError *error = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
[audioSession setActive:YES error:&error];

我可以想象我可能需要对AudioSessionSetProperty

做些什么
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);    

UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);

但这并没有改变任何事情。 您是否了解我缺少的内容或如何正确设置AudioSession?

感谢您的每一个暗示!

干杯, 拉斐尔;)

1 个答案:

答案 0 :(得分:13)

我遇到了同样的问题(除了我使用AVPlayer播放音频而不是视频)。我建议您开始收听音频路由更改,并且当AVPlayer和AVAudioRecorder同时启动时,您将看到多次路由更改。

AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange,
                                audioRouteChangeListenerCallback,
                                self);

在回调中打印出类别和路线(kAudioSessionProperty_AudioRoute)。我可以让音频播放和录音同时工作的唯一方法是:

  1. 音频会话为AVAudioSessionCategoryPlayAndRecord,kAudioSessionProperty_OverrideCategoryMixWithOthers属性为true。

  2. 我在录制前启动了播放。调用AVAudioRecorder prepareToRecord后,在获得音频路径更改之前不要开始录制。即使你早先开始录音也不会失败,但音频路线的变化似乎会使录音失败。

  3. 我尝试了其他组合,但这是唯一一次有效的组合。