问题描述
我指的是以下链接:- OBJC AVSpeechUtterance writeUtterance how? 为我的问题的答案。但是上面的链接可以正常工作仅从AVSpeechSynthesizer写入一个音频文件。如果我需要将多个原始pcm音频文件写入数据库,该怎么办。
我面临的问题是缓冲区回调被多次调用。因此,我无法弄清文件是否已写完,并且可以开始写入另一个文件。 下面是我的代码库:-
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:@"test 123"];
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"];
[utterance setVoice:voice];
__block AVAudioFile *output = nil;
[synthesizer writeUtterance:utterance
toBufferCallback:^(AVAudioBuffer * _Nonnull buffer) {
AVAudioPCMBuffer *pcmBuffer = (AVAudioPCMBuffer*)buffer;
if (!pcmBuffer) {
NSLog(@"Error");
return;
}
if (pcmBuffer.frameLength != 0) {
//append buffer to file
if (output == nil) {
output = [[AVAudioFile alloc] initForWriting:[NSURL fileURLWithPath:@"test.caf"]
settings:pcmBuffer.format.settings
commonFormat:AVAudioPCMFormatInt16
interleaved:NO error:nil];
}
[output writeFromBuffer:pcmBuffer error:nil];
}
}];
解决方法
啊。终于明白了。这是 AVAudioPCMBuffer 类的 frameLength 属性,它帮助我确定了音频流是否已完全写入。 利用此属性,并通过在合成器块外部声明一个新的var来跟踪写入文件的总frameLength。您可以参考以下代码:-
__block long currentFrameLength = 0;
[synthesizer writeUtterance:utterance
toBufferCallback:^(AVAudioBuffer * _Nonnull buffer) {
if(currentFrameLength == 0) {
{ // This check signifies that previous file is completely written
}
currentFrameLength = currentFrameLength + pcmBuffer.frameLength;