ios - 如何使用 CMSampleBuffer 创建 AVAudioPCMBuffer?
问题描述
我有一个AVAsset
,我AVAssetReaderAudioMixOutput
用来获取CMSampleBuffer
,我想用它来CMSampleBuffer
创建AVAudioPlayerNode
scheduleBuffer
怎么办,有大佬帮忙吗?
解决方案
extension AVAudioPCMBuffer {
static func create(from sampleBuffer: CMSampleBuffer) -> AVAudioPCMBuffer? {
guard let description: CMFormatDescription = CMSampleBufferGetFormatDescription(sampleBuffer),
let sampleRate: Float64 = description.audioStreamBasicDescription?.mSampleRate,
let channelsPerFrame: UInt32 = description.audioStreamBasicDescription?.mChannelsPerFrame /*,
let numberOfChannels = description.audioChannelLayout?.numberOfChannels */
else { return nil }
guard let blockBuffer: CMBlockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else {
return nil
}
let samplesCount = CMSampleBufferGetNumSamples(sampleBuffer)
//let length: Int = CMBlockBufferGetDataLength(blockBuffer)
let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: sampleRate, channels: AVAudioChannelCount(1), interleaved: false)
let buffer = AVAudioPCMBuffer(pcmFormat: audioFormat!, frameCapacity: AVAudioFrameCount(samplesCount))!
buffer.frameLength = buffer.frameCapacity
// GET BYTES
var dataPointer: UnsafeMutablePointer<Int8>?
CMBlockBufferGetDataPointer(blockBuffer, atOffset: 0, lengthAtOffsetOut: nil, totalLengthOut: nil, dataPointerOut: &dataPointer)
guard var channel: UnsafeMutablePointer<Float> = buffer.floatChannelData?[0],
let data = dataPointer else { return nil }
var data16 = UnsafeRawPointer(data).assumingMemoryBound(to: Int16.self)
for _ in 0...samplesCount - 1 {
channel.pointee = Float32(data16.pointee) / Float32(Int16.max)
channel += 1
for _ in 0...channelsPerFrame - 1 {
data16 += 1
}
}
return buffer
}
}
推荐阅读
- javascript - 如果尝试使用 getElementByClassName 获取元素,为什么 ChildNode 属性不起作用
- xtext - 困惑如何用 xbase 支持数组
- python - 如何从多个序列创建转换表?
- graph - 根据父节点和双向关系获取节点
- amazon-web-services - Alexa 开发人员控制台 - DynamoDB
- jspdf - html2canvas 和 jspdf 不呈现 .svg 图像
- r - 基于其他列创建新列的 data.table 方式
- c++ - 如何使用opencv的局部阈值对图像进行二值化
- sql - 如何在 SQL Server 中删除具有 Not Null 约束的现有列
- random - 概率分布中的随机数