ios - AVSpeechSynthesizer writeUtterance。如何查找是否将完整的话语写入文件?
问题描述
我指的是以下链接: - OBJC AVSpeechUtterance writeUtterance 怎么样? 回答我的问题。但是上面的链接工作得很好,只需要从 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 来跟踪写入文件的总帧长度。您可以参考以下代码:-
__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;
推荐阅读
- java - 在 Gatling 工具中发出 RecordedSimulation 时出错
- entity-framework - 具有索引重载的 EF Core 3.0 选择投影(又名 .Select((entity, index) => new {})失败
- javascript - onended() 在 Safari 或 iOS 上不会触发
- c# - Serilog 范围级别过滤
- jpa - 使用 Quarkus 注入实体监听器
- mysql - 如何确定 utf8 数据编码错误并在 MySql 中更正?
- python - cx-freeze PermissionError: [Errno 13] 权限被拒绝
- acumatica - Acumatica - 需要帮助通过自定义操作更新项目报价屏幕 PM304500 中的活动
- ios - 如何在 Swift 5 的 CoreData 中获取 ObjectID 并搜索特定的 ObjectID?
- python - 检查用户输入的字符串是否在字典中,如果它返回值