将MP3流的NSData转换为AVAudioPCMBuffer出现isPCMFormat报错如何解决
问题根因
AVAudioPCMBuffer仅支持存储未压缩的PCM音频数据,初始化时要求传入的格式必须是PCM格式。你当前传入的format是压缩MP3格式,不满足格式校验要求,所以抛出required condition is false: isPCMFormat(fmt)异常。- 从你打印的format信息也可以验证:格式标识为
.mp3,且bits/channel、bytes/frame等PCM格式必填字段值均为0,符合压缩格式的特征。
解决步骤
你需要先将MP3压缩数据流解码为PCM格式,再初始化AVAudioPCMBuffer,可以使用AVAudioConverter完成解码操作,具体实现如下:
- 保留已创建的MP3格式作为源格式,再创建匹配参数的目标PCM格式:
// 源MP3格式,即你之前通过流描述创建的format AVAudioFormat *sourceFormat = [[AVAudioFormat alloc] initWithStreamDescription:&description]; // 目标PCM格式,参数可根据实际需求调整,此处匹配源MP3的采样率、声道数,采用16位整型存储 AVAudioFormat *destFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatInt16 sampleRate:sourceFormat.sampleRate channels:sourceFormat.channelCount interleaved:NO];
- 初始化格式转换器:
NSError *converterError = nil; AVAudioConverter *converter = [[AVAudioConverter alloc] initFromFormat:sourceFormat toFormat:destFormat]; if (!converter) { NSLog(@"转换器初始化失败:%@", converterError.localizedDescription); return; }
- 执行解码转换得到PCM Buffer:
// 初始化PCM Buffer,此处frameCapacity用你原逻辑的frameCount即可 AVAudioPCMBuffer *pcbBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:destFormat frameCapacity:frameCount]; // 转换输入回调,填充你的MP3数据流到输入缓冲区 AVAudioConverterInputBlock inputBlock = ^AVAudioBuffer * _Nonnull(AVAudioPacketCount requestPacketCount, AVAudioConverterInputStatus *outStatus) { // 创建MP3压缩格式的输入Buffer,maximumPacketSize替换为你MP3流的最大包大小 AVAudioCompressedBuffer *inputBuffer = [[AVAudioCompressedBuffer alloc] initWithFormat:sourceFormat packetCapacity:requestPacketCount maximumPacketSize:maxMP3PacketSize]; // 此处替换为你自己的MP3数据流读取逻辑,将数据拷贝到inputBuffer.data memcpy(inputBuffer.data, yourMP3StreamPointer, availableDataLength); inputBuffer.packetCount = requestPacketCount; *outStatus = AVAudioConverterInputStatus_HaveData; return inputBuffer; }; // 执行转换 NSError *convertError = nil; AVAudioConverterOutputStatus convertStatus = [converter convertToBuffer:pcbBuffer error:&convertError withInputFromBlock:inputBlock]; if (convertStatus == AVAudioConverterOutputStatus_Error) { NSLog(@"MP3解码为PCM失败:%@", convertError.localizedDescription); }
内容的提问来源于stack exchange,提问作者gerbil
相关产品推荐
相关产品推荐

