You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AVAudioSession录音:为何获取的字节数超出预期?

问题

我按如下方式配置录音会话:

NSString *audioFilePath = [NSTemporaryDirectory() stringByAppendingString:@"temp.bin"];
_audioFileURL = [NSURL fileURLWithPath:audioFilePath];

NSDictionary *recordSettings = @{
        AVFormatIDKey: @(kAudioFormatLinearPCM),
        AVLinearPCMIsBigEndianKey: @NO,
        AVLinearPCMIsFloatKey: @NO,
        AVEncoderAudioQualityKey: @(AVAudioQualityHigh),
        AVEncoderBitRateKey: @128000,
        AVLinearPCMBitDepthKey: @32,
        AVNumberOfChannelsKey: @2,
        AVSampleRateKey: @44100.0f
    };

根据配置,预期2秒录音的字节数应为:

bytes = 4 * 44100 * 2 * 2 = 705600 bytes

但实际获取录音数据时:

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
  if (flag) {
  
    NSData *recordedAudioData = [NSData dataWithContentsOfURL:_audioFileURL options:0 error:&error];
    NSUInteger recordedAudioLength = [recordedAudioData length];
}

recordedAudioLength的值略大,为709696 bytes。请问该如何避免这种情况?问题出在录音配置还是数据读取环节?

解答

问题原因

实际文件偏大是因为AVAudioRecorder默认会给Linear PCM格式的录音文件添加WAV文件头,这个文件头占用了额外字节数,导致读取到的文件总长度比纯PCM数据的预期值要大。

解决方法

  • 方法1:跳过文件头读取纯PCM数据
    WAV文件头通常为44字节,可直接跳过这部分读取纯PCM内容:
NSData *fullData = [NSData dataWithContentsOfURL:_audioFileURL options:0 error:&error];
// 跳过WAV头,提取纯PCM数据
NSData *purePCMData = [fullData subdataWithRange:NSMakeRange(44, fullData.length - 44)];
NSUInteger pcmLength = purePCMData.length;

如果WAV头长度非标准44字节,建议解析WAV头的Subchunk2Size字段,精准定位PCM数据的起始位置和长度,避免出错。

  • 方法2:改用底层API直接写入纯PCM数据
    若不需要WAV头,可使用AVAudioEngine或AudioQueueServices实现录音,这类API能直接输出无头部的纯PCM数据。示例(AVAudioEngine):
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AVAudioInputNode *inputNode = engine.inputNode;
AVAudioFormat *format = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatInt32 sampleRate:44100 channels:2 interleaved:YES];

[inputNode installTapOnBus:0 bufferSize:4096 format:format block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) {
    // 提取buffer中的PCM数据
    NSData *data = [NSData dataWithBytes:buffer.int32ChannelData[0] length:buffer.frameLength * format.streamDescription->mBytesPerFrame];
    // 追加写入文件
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:audioFilePath];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:data];
    [fileHandle closeFile];
}];

NSError *engineError;
[engine startAndReturnError:&engineError];
  • 方法3:调整配置(可靠性低,不推荐)
    尝试在recordSettings中添加AVLinearPCMIsNonInterleavedKey: @NO,但AVAudioRecorder仍可能自动添加WAV头,因此这个方案的效果不稳定。

总结

问题既不在录音的PCM参数配置,也不在数据读取环节,而是AVAudioRecorder对Linear PCM格式的默认处理逻辑——自动添加WAV文件头导致的。通过跳过文件头或改用底层录音API即可解决。

内容的提问来源于stack exchange,提问作者Grew112

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:50:54