使用 AudioConverter 将 PCM 转换为 AAC 并使用 AVAssetWriter 写入 .mp4 文件时音频失真
Posted
技术标签:
【中文标题】使用 AudioConverter 将 PCM 转换为 AAC 并使用 AVAssetWriter 写入 .mp4 文件时音频失真【英文标题】:Distorted audio when converting PCM to AAC using AudioConverter and writing to .mp4 file using AVAssetWriter 【发布时间】:2020-01-19 14:01:00 【问题描述】:我正在尝试压缩来自 AVCaptureSession 的输入并将其保存到 .mp4 文件中。我已成功转换并保存视频,但音频有问题。
我已经到了使用https://github.com/nevyn/LBMediaToolkit 转换音频的地步。我可以将转换后的 CMSampleBuffer 保存为 .mp4,但是当我在 iPhone 上播放它时,音频听起来会失真。
奇怪的是,音频在 QuickTime 中播放时也听起来失真,但在通过网络浏览器播放时听起来不错。点击here下载示例文件。
我认为我将正确的格式传递给转换器:
let asbd = AudiostreamBasicDescription(
mSampleRate: 44_100,
mFormatID: kAudioFormatMPEG4AAC,
mFormatFlags: UInt32(MPEG4ObjectID.AAC_LC.rawValue),
mBytesPerPacket: 0,
mFramesPerPacket: 1024,
mBytesPerFrame: 0,
mChannelsPerFrame: 2,
mBitsPerChannel: 0,
mReserved: 0)
return LBAudioConverter(convertingTo: asbd)
我不确定这是否是音频转换或写入文件的问题。这是一个仅包含音频的示例项目的链接:https://github.com/gaperlinski/AudioConversion(按照 README.MD 中的说明重现问题)
是否有什么明显的错误导致音频听起来失真?
【问题讨论】:
【参考方案1】:原来罪魁祸首是以下代码:
UInt32 cookieSize = 0;
char cookie[cookieSize];
AudioConverterGetPropertyInfo(_converter, kAudioConverterCompressionMagicCookie, &cookieSize, NULL);
AudioConverterGetProperty(_converter, kAudioConverterCompressionMagicCookie, &cookieSize, cookie);
CMAudioFormatDescriptionRef audioFormat;
const OSStatus formatCreationError = CMAudioFormatDescriptionCreate(
kCFAllocatorDefault,
&_toFormat,
0, NULL, // layout
cookieSize, cookie, // cookie
NULL, // extensions
&audioFormat);
if(formatCreationError != noErr)
NSLog(@"Failed to convert a buffer because format creation failed: %d", (int)formatCreationError);
continue;
我注意到,当我为 CMSampleBuffer 创建格式描述时,我应该只将 magicCookie 添加到 第一个样本缓冲区,或者甚至应该在没有数据。
如果我这样做,音频不会失真,并且 mp4 文件容器中只有一个 esds atom。
【讨论】:
以上是关于使用 AudioConverter 将 PCM 转换为 AAC 并使用 AVAssetWriter 写入 .mp4 文件时音频失真的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 C# 的 MediaTranscoder 将 PCM 音频转码为 MP3
使用 AudioConverter Swift 将 .m4a 文件转换为 .aiff
音视频开发8. 使用ffmpeg 将pcm转码aac实践(C++)