为了同时进行可用的播放和录制,我们使用这些方法设置AVAudioSession
类别:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];
通过这样做,输出音频端口从线路输出扬声器切换到内置扬声器。在循环录制窗口中,我们需要同时从线路输出扬声器和麦克风录音进行播放。要在设置AVAudioSession
类别后从线路输出扬声器播放声音,我们使用一种设置输出音频端口的方法:
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker错误:nil];
我们尝试使用AVAudio Engine安排录制和播放。
AVAudioEngine
连接的结构:
// input->inputMixer->mainEqualizer ->tap
// 0 0 |0
// |
// |
// |0 0 0
// recordPlayerNode→recordMixer→meteringMixer→|
// 0 1 0 0 |
// |->mainMixer->out
// |
// volumePlayer→|
// 0 1
执行overrideOutputAudioPort后,录制功能在iPhone 6S及更高版本上停止工作。我们以这种方式执行录制:
if(self.isHeadsetPluggedIn)
{
volumePlayer.volume = 1;
}
else
{
volumePlayer.volume = 0.000001;
}
[volumePlayer play];
[mainEqualizer installTapOnBus:0 bufferSize:0 format:tempAudioFile.processingFormat block:^(AVAudioPCMBuffer *buf, AVAudioTime *when)
{
if(self.isRecord)
{
[volumePlayer scheduleBuffer:buf completionHandler:nil];
recordedFrameCount += buf.frameLength;
if (self.isLimitedRecord && recordedFrameCount >= [AVAudioSession sharedInstance].sampleRate * 90)
{
self.isRecord = false;
[self.delegate showAlert:RecTimeLimit];
}
NSError *error;
[tempAudioFile writeFromBuffer:buf error:&error];
if(error)
{
NSLog(@"Allert while write to file: %@",error.localizedDescription);
}
[self updateMetersForMicro];
}
else
{
[mainEqualizer removeTapOnBus:0];
[self.delegate recordDidFinish];
callbackBlock(recordUrl);
[mainEngine stop];
}
}];
在调查期间,我们发现了一个有趣的事实 - 如果
volumePlayer.volume = 1;
当未连接耳机时,来自微型耳机的缓冲器开始填充并且声音继续记录,但是在扬声器中出现非常响亮的声音重复的效果。否则,PCMBuffer
将填充零。
问题是:我们如何设置AVAudioSession
或录制过程,以便我们可以使用麦克风录制音频并使用线路扬声器播放音频?
P.S。使用AVAudioRecorder
进行录制可以正常使用这些设置。