如何在Swift中将CMSampleBuffer转换为Data?

ldxq2e6h  于 2023-10-15  发布在  Swift
关注(0)|答案(3)|浏览(141)

我需要将CMSampleBuffer转换为Data。我使用一个第三方框架音频相关的任务。该框架为我提供了CMSampleBuffer对象中的流(即真实的时间音频)音频。
就像这样:

func didAudioStreaming(audioSample: CMSampleBuffer!) {
    //Here I need to conver this to Data format. 
    //Because I am using GRPC framework for Audio Recognization, 
}

请提供我的步骤转换为DataCMSampleBuffer
FYI

let formatDesc:CMFormatDescription? = CMSampleBufferGetFormatDescription(audioSample)

    <CMAudioFormatDescription 0x17010d890 [0x1b453ebb8]> {
    mediaType:'soun' 
    mediaSubType:'lpcm' 
    mediaSpecific: {
        ASBD: {
            mSampleRate: 16000.000000 
            mFormatID: 'lpcm' 
            mFormatFlags: 0xc 
            mBytesPerPacket: 2 
            mFramesPerPacket: 1 
            mBytesPerFrame: 2 
            mChannelsPerFrame: 1 
            mBitsPerChannel: 16     } 
        cookie: {(null)} 
        ACL: {(null)}
        FormatList Array: {(null)} 
    } 
    extensions: {(null)}
}
nwlqm0z1

nwlqm0z11#

尝试下面的代码将CMSampleBuffer转换为NSData。

let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
let src_buff = CVPixelBufferGetBaseAddress(imageBuffer!)
let data = NSData(bytes: src_buff, length: bytesPerRow * height)
CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))

编辑-

对于AudioBuffer使用下面的代码-

var audioBufferList = AudioBufferList()
var data = Data()
var blockBuffer : CMBlockBuffer?

CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nil, &audioBufferList, MemoryLayout<AudioBufferList>.size, nil, nil, 0, &blockBuffer)

let buffers = UnsafeBufferPointer<AudioBuffer>(start: &audioBufferList.mBuffers, count: Int(audioBufferList.mNumberBuffers))

for audioBuffer in buffers {
    let frame = audioBuffer.mData?.assumingMemoryBound(to: UInt8.self)
    data.append(frame!, count: Int(audioBuffer.mDataByteSize))
}
wqnecbli

wqnecbli2#

使用CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer将需要在某个时候调用CFRelease(blockBuffer),因为缓冲区被保留,如果不释放,缓冲区池最终将变为空,并且不会生成新的CMSampleBuffer
我建议使用以下方法直接获取数据:

CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
size_t lengthAtOffset;
size_t totalLength;
char *data;
CMBlockBufferGetDataPointer(blockBuffer, 0, &lengthAtOffset, &totalLength, &data);

NSData *audioData = [NSData dataWithBytes:data length:totalLength];
n9vozmp4

n9vozmp43#

@plamkata__的代码转换为Swift:

var lengthAtOffset = Int()
var totalLength = Int()
var dataPointer: UnsafeMutablePointer<CChar>?

if let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) {
    CMBlockBufferGetDataPointer(blockBuffer, atOffset: 0, lengthAtOffsetOut: &lengthAtOffset, totalLengthOut: &totalLength, dataPointerOut: &dataPointer)
    let audioData = Data(bytes: dataPointer!, count: totalLength)
}

相关问题