我正在使用记录音频和视频的外部摄像头。
我的应用使用以下结构接收 AAC 格式的音频:
struct AudioPacket {
let timestamp: TimeInterval
let data: Data
let asbd: AudioStreamBasicDescription
let magicCookie: Data
let audioSpecificConfigData: Data
}
AudioStreamBasicDescription
属性包含以下内容:
- mSampleRate : 48000.0
- mFormatID : 1633772320
- mFormatFlags : 0
- mBytesPerPacket : 0
- mFramesPerPacket : 1024
- mBytesPerFrame : 0
- mChannelsPerFrame : 1
- mBitsPerChannel : 0
- mReserved : 0
我正在使用AVAssetWriter
将音频和视频写入文件,需要向资产编写器提供CMSampleBuffer
-s。
那么如何将上述AudioPacket
结构转换为CMSampleBuffer
呢?
不是一个确切的答案,但我会尝试如下:
func convertPacket(_ packet: AudioPacket) -> CMSampleBuffer? {
var data = packet.data
var asbd = packet.asbd
var magicCookie = packet.magicCookie
var blockBuffer: CMBlockBuffer?
var formatDescription: CMFormatDescription?
var sampleBuffer: CMSampleBuffer?
CMBlockBufferCreateWithMemoryBlock(
allocator: nil, memoryBlock: &data, blockLength: data.count,
blockAllocator: nil, customBlockSource: nil, offsetToData: 0,
dataLength: data.count, flags: 0, blockBufferOut: &blockBuffer
)
CMAudioFormatDescriptionCreate(
allocator: nil, asbd: &asbd, layoutSize: 0, layout: nil,
magicCookieSize: magicCookie.count, magicCookie: &magicCookie,
extensions: nil, formatDescriptionOut: &formatDescription
)
CMAudioSampleBufferCreateWithPacketDescriptions(
allocator: nil, dataBuffer: blockBuffer, dataReady: true,
makeDataReadyCallback: nil, refcon: nil, formatDescription: formatDescription!,
sampleCount: 1, // <- provide correct number
presentationTimeStamp: CMTime(seconds: packet.timestamp, preferredTimescale: 100),
packetDescriptions: nil, sampleBufferOut: &sampleBuffer
)
return sampleBuffer
}