为了同时进行可用的播放和录制,我们使用这些方法设置 AVAudioSession
类别:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];
通过这样做,输出音频端口从线路输出扬声器切换到内置扬声器 . 在循环录制窗口中,我们需要同时从线路输出扬声器和麦克风录音进行播放 . 要在设置 AVAudioSession
类别后从线路输出扬声器播放声音,我们使用一种方法来设置输出音频端口:
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error: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
After execution overrideOutputAudioPort the recording feature stops working on iPhone 6S and higher. 我们以这种方式进行录制:
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
或录音过程,以便我们可以使用麦克风录制音频并使用线路扬声器播放音频?
附:使用 AVAudioRecorder
进行录制可以正常使用这些设置 .