首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将AudioBufferList转换为CMSampleBuffer?

如何将AudioBufferList转换为CMSampleBuffer?
EN

Stack Overflow用户
提问于 2015-04-08 20:31:30
回答 1查看 1.8K关注 0票数 5

我有一个连接到AVPlayerItem的AudioTapProcessor。它将在处理时调用static void tap_ProcessCallback(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut, CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut)

我需要将AudioBufferList转换为CMSampleBuffer,这样我才能使用AVAssetWriterAudioInput.appendSampleBuffer将其写入电影文件。

那么如何将AudioBufferList转换为CMSampleBuffer呢?我试过了,但得到了-12731错误:Error :Optional("-12731")

代码语言:javascript
复制
func processAudioData(audioData: UnsafeMutablePointer<AudioBufferList>, framesNumber: UInt32) {
    var sbuf : Unmanaged<CMSampleBuffer>?
    var status : OSStatus?
    var format: Unmanaged<CMFormatDescription>?

    var formatId =  UInt32(kAudioFormatLinearPCM)
    var formatFlags = UInt32( kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked )
    var audioFormat = AudioStreamBasicDescription(mSampleRate: 44100.00, mFormatID:formatId, mFormatFlags:formatFlags , mBytesPerPacket: 1, mFramesPerPacket: 1, mBytesPerFrame: 16, mChannelsPerFrame: 2, mBitsPerChannel: 2, mReserved: 0)

    status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &audioFormat, 0, nil, 0, nil, nil, &format)
    if status != noErr {
        println("Error CMAudioFormatDescriptionCreater :\(status?.description)")
        return
    }


    var timing = CMSampleTimingInfo(duration: CMTimeMake(1, 44100), presentationTimeStamp: kCMTimeZero, decodeTimeStamp: kCMTimeInvalid)

    status = CMSampleBufferCreate(kCFAllocatorDefault,nil,Boolean(0),nil,nil,format?.takeRetainedValue(), CMItemCount(framesNumber), 1, &timing, 0, nil, &sbuf);
    if status != noErr {
        println("Error CMSampleBufferCreate :\(status?.description)")
        return
    }
    status =   CMSampleBufferSetDataBufferFromAudioBufferList(sbuf?.takeRetainedValue(), kCFAllocatorDefault , kCFAllocatorDefault, 0, audioData)
    if status != noErr {
        println("Error cCMSampleBufferSetDataBufferFromAudioBufferList :\(status?.description)")
        return
    }

    var currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sbuf?.takeRetainedValue());
    println(" audio buffer at time: \(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime))")

    if !assetWriterAudioInput!.readyForMoreMediaData {
        return
    }else if assetWriter.status == .Writing {

        if !assetWriterAudioInput!.appendSampleBuffer(sbuf?.takeRetainedValue()) {
            println("Problem appending audio buffer at time: \(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime))")
        }

    }else{
        println("assetWriterStatus:\(assetWriter.status.rawValue), Error: \(assetWriter.error.localizedDescription)")
        println("Could not write a frame")
    }




}
EN

回答 1

Stack Overflow用户

发布于 2015-04-09 16:02:55

好了,我已经成功地解决了这个问题。

问题是我不应该自己构造AudioStreamBasicDescription结构。但请使用AudioProcessorTap的准备回调提供的回调。

static void tap_PrepareCallback(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat) //retain this one

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29514701

复制
相关文章

相似问题

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