【问题标题】:How to get CMSampleBufferRef from AudioQueueBufferRef如何从 AudioQueueBufferRef 获取 CMSampleBufferRef
【发布时间】:2013-12-11 07:34:00
【问题描述】:

我正在使用一个私人图书馆,它是为从 iPhone 直播而制作的。 在每次录制每一帧时,它都会调用一个delegate 函数

void MyAQInputCallback(void *inUserData,
                              AudioQueueRef inQueue,
                              AudioQueueBufferRef inBuffer,
                              const AudioTimeStamp *inStartTime,
                              UInt32 inNumPackets,
                              const AudioStreamPacketDescription *inPacketDesc);

现在我如何像往常一样将此 inBuffer 附加到我的AVAssetWriterInput

[self.audioWriterInput appendSampleBuffer:sampleBuffer];

我想可能会以某种方式将AudioQueueBufferRef 转换为CMSampleBufferRef

谢谢。

【问题讨论】:

  • 您找到解决方案了吗?

标签: ios iphone ffmpeg avfoundation


【解决方案1】:

我不认为两年后您仍在寻找解决方案,但以防万一有人处于类似情况并找到这个问题(就像我一样),这是我的解决方案。

我的音频队列回调函数调用下面的 appendAudioBuffer 函数,将 AudioQueueBufferRef 及其长度 (mAudioDataByteSize) 传递给它。

void appendAudioBuffer(void* pBuffer, long pLength)
{      
    // CMSampleBuffers require a CMBlockBuffer to hold the media data; we
    // create a blockBuffer here from the AudioQueueBuffer's data.

    CMBlockBufferRef blockBuffer;
    OSStatus status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
                                                 pBuffer,
                                                 pLength,
                                                 kCFAllocatorNull,
                                                 NULL,
                                                 0,
                                                 pLength,
                                                 kCMBlockBufferAssureMemoryNowFlag,
                                                 &blockBuffer);

    // Timestamp of current sample
    CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
    CFTimeInterval elapsedTime = currentTime - mStartTime;
    CMTime timeStamp = CMTimeMake(elapsedTime * mTimeScale, mTimeScale);

    // Number of samples in the buffer
    long nSamples = pLength / mWaveRecorder->audioFormat()->mBytesPerFrame;

    CMSampleBufferRef sampleBuffer;
    OSStatus err = CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault,
                                                                   blockBuffer,
                                                                   true,
                                                                   NULL,
                                                                   NULL,
                                                                   mAudioFormatDescription, 
                                                                   nSamples,
                                                                   timeStamp, 
                                                                   NULL,
                                                                   &sampleBuffer);
    // Add the audio sample to the asset writer input
    if ([mAudioWriterInput isReadyForMoreMediaData]) {
        if(![mAudioWriterInput appendSampleBuffer:sampleBuffer])
            // print an error
    }
    else 
        // either do nothing and just print an error, or queue the CMSampleBuffer 
        // somewhere and add it later, when the AVAssetWriterInput is ready


    CFRelease(sampleBuffer);
    CFRelease(blockBuffer);

}

请注意,当我调用appendAudioBuffer 时,声音没有被压缩;音频格式被指定为 LPCM(这就是我不使用数据包描述符的原因,因为 LPCM 没有)。 AVAssetWriterInput 处理压缩。 我最初尝试将 AAC 数据传递给 AVAssetWriter,但这导致了太多的复杂性,我无法让它工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多