首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用CMSampleBuffer创建AVAudioPCMBuffer?

如何用CMSampleBuffer创建AVAudioPCMBuffer?
EN

Stack Overflow用户
提问于 2021-11-10 06:48:40
回答 1查看 99关注 0票数 1

我有一个AVAsset,我使用AVAssetReaderAudioMixOutput来获取CMSampleBuffer,我想使用这个CMSampleBuffer来创建到scheduleBufferAVAudioPlayerNode

怎么做,有人帮我吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-10 13:57:29

代码语言:javascript
复制
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
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69908897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档