我正在尝试获取本地 m4a 文件并压缩/向下采样该文件(为了制作更小的文件)。
现在,当我尝试附加样本缓冲区时,我遇到了错误。
错误描述:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'*** -[AVAssetWriterInput appendSampleBuffer:] Cannot append sample buffer: Input
buffer must be in an uncompressed format when outputSettings is not nil'
我尝试将原始音频文件压缩为相同文件格式但比特率较低的代码:
@objc func nextTapped() {
let audioURL = RecordWhistleViewController.getWhistleURL()
var asset = AVAsset.init(url: audioURL)
let exportPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("out.m4a").path
print("export PATH IS \(exportPath)")
let exportURL = URL(fileURLWithPath: exportPath)
var readerError: Error? = nil
var reader: AVAssetReader? = nil
do {
reader = try AVAssetReader(asset: asset)
} catch {
print("error in reader \(error)")
}
let track = asset.tracks(withMediaType: .audio)[0]
let readerOutput = AVAssetReaderTrackOutput(track: track, outputSettings: nil)
reader?.add(readerOutput)
var writerError: Error? = nil
var writer: AVAssetWriter? = nil
do {
writer = try AVAssetWriter(outputURL: exportURL, fileType: .m4a)
} catch {
print("ERROR IN writer \(error)")
}
var channelLayout = AudioChannelLayout()
memset(&channelLayout, 0, MemoryLayout<AudioChannelLayout>.size)
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo
let outputSettings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 2,
AVEncoderBitRateKey: 128000,
AVChannelLayoutKey: Data(bytes: &channelLayout, count: MemoryLayout<AudioChannelLayout>.size)
] as [String : Any]
let writerInput = AVAssetWriterInput(mediaType: .audio, outputSettings: outputSettings as? [String: Any])
writerInput.expectsMediaDataInRealTime = false
writer?.add(writerInput)
writer?.startWriting()
writer?.startSession(atSourceTime: .zero)
reader?.startReading()
let mediaInputQueue = DispatchQueue(label: "mediaInputQueue")
writerInput.requestMediaDataWhenReady(on: mediaInputQueue) {
print("Asset writer ready: \(writerInput.isReadyForMoreMediaData)")
while writerInput.isReadyForMoreMediaData {
var nextBuffer: CMSampleBuffer?
nextBuffer = readerOutput.copyNextSampleBuffer()
if nextBuffer != nil {
if let nextBuffer = nextBuffer {
print("adding buffer")
writerInput.append(nextBuffer)
}
} else {
writerInput.markAsFinished()
reader?.cancelReading()
writer?.finishWriting {
print("Asset writer finished writing")
}
break
}
}
}
}
原始音频有设置:
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
原始文件的 URL 代码:
class func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
编辑:
这是错误的完整描述:
assetsWriter_finishBuildingAudioTrackWithSourceFormatDescription 在 /Library/Caches/com.apple.xbs/Sources/EmbeddedCoreMedia_Sim/EmbeddedCoreMedia-2765.6/Prototypes/Export/FigAssetWriter.c:636 处发出 err=-12413 (kFigAssetWriterError_InappropriateSourceFormat) (AssetWriter 只能压缩 LPCM 音频)
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** -[AVAssetWriterInput appendSampleBuffer:] 无法附加样本缓冲区:当 outputSettings 不为 nil 时,输入缓冲区必须为未压缩格式”