ios - 将 CMSampleBuffer 转换为 AVAudioPCMBuffer 以获取实时音频

标签 ios swift audio-streaming

我正在尝试从 AVCaptureAudioDataOutputSampleBufferDelegatecaptureOutput 返回的 CMSampleBuffer 中读取频率值。

我的想法是创建一个AVAudioPCMBuffer,这样我就可以读取它的floatChannelData。但我不确定如何将缓冲区传递给它。

我想我可以创建它:

public func captureOutput(_ output: AVCaptureOutput,
                              didOutput sampleBuffer: CMSampleBuffer,
                              from connection: AVCaptureConnection) {
guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else {
  return
}
let length = CMBlockBufferGetDataLength(blockBuffer)

let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 44100, channels: 1, interleaved: false)
let pcmBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat!, frameCapacity: AVAudioFrameCount(length))
pcmBuffer?.frameLength = pcmBuffer!.frameCapacity

但是我该如何填充它的数据呢?

最佳答案

这些方面的内容应该有所帮助:

var asbd = CMSampleBufferGetFormatDescription(sampleBuffer)!.audioStreamBasicDescription!
var audioBufferList = AudioBufferList()
var blockBuffer : CMBlockBuffer?

CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
    sampleBuffer,
    bufferListSizeNeededOut: nil,
    bufferListOut: &audioBufferList,
    bufferListSize: MemoryLayout<AudioBufferList>.size,
    blockBufferAllocator: nil,
    blockBufferMemoryAllocator: nil,
    flags: 0,
    blockBufferOut: &blockBuffer
)

let mBuffers = audioBufferList.mBuffers
let frameLength = AVAudioFrameCount(Int(mBuffers.mDataByteSize) / MemoryLayout<Float>.size)
let pcmBuffer = AVAudioPCMBuffer(pcmFormat: AVAudioFormat(streamDescription: &asbd)!, frameCapacity: frameLength)!
pcmBuffer.frameLength = frameLength
pcmBuffer.mutableAudioBufferList.pointee.mBuffers = mBuffers
pcmBuffer.mutableAudioBufferList.pointee.mNumberBuffers = 1

这似乎在捕获 session 的末尾创建了一个有效的 AVAudioPCMBuffer。但它现在的帧长度对于我的用例来说是错误的,所以需要做一些进一步的缓冲。

关于ios - 将 CMSampleBuffer 转换为 AVAudioPCMBuffer 以获取实时音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57083315/

相关文章:

ios - 如何禁用 UIScrollView 的水平滚动?

ios - 关于 Swift 中模型结构的可选绑定(bind)的问题

ios - 无法为 UIButton 添加目标 - 无法识别的选择器发送到实例,尽管方法在同一个类中

ios - UI分段控制ui修改

swift - 如何在 Swift 中从 CMutablePointer<CGFloat> 到 CGFloat[]

swift - 使用链式函数的 Swift 完成处理程序

php - 使用网络服务器录制广播/音频流 (asx/asf)

ios - 从 NSURLSessionDataTask 请求的 NSData 响应中获取 XML

iphone - 在 iPhone 上,如何使用 fileHandle 即时下载 mp3 文件?

android - 当视频中不存在音频流时速度更改命令失败 - ffmpeg