使用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
相关产品推荐
相关产品推荐

