ios - 如何从 AudioQueueBufferRef 获取 CMSampleBufferRef

标签 ios iphone ffmpeg avfoundation

我正在使用一个专为 iPhone 直播而设计的私有(private)图书馆。 在每次记录每一帧时,它都会调用一个委托(delegate)函数

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

Now how I can append this inBuffer to my AVAssetWriterInput as usual:

[self.audioWriterInput appendSampleBuffer:sampleBuffer];

我想也许可以将 AudioQueueBufferRef 转换为 CMSampleBufferRef

谢谢。

最佳答案

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

我的音频队列回调函数调用下面的 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,但这导致了太多的复杂性,我无法让它工作。

关于ios - 如何从 AudioQueueBufferRef 获取 CMSampleBufferRef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20212320/

相关文章:

iOS - UITextView 在 Storyboard中关闭键盘

iphone - 为什么我的 CLLocation 速度如此不准确?

ubuntu - 如何使用 ffmpeg 更改部分视频的帧速率

ffmpeg - 为 windows phone 8 构建 ffmpeg

ios - Swift 中的逻辑与运算不起作用

ios - 如何在 IOS 中的联系人更改事件中得到通知?

ios - 如果当前 View Controller 被呈现并被推送,如何展开到正确的 View Controller ?

ios - 解析 .osm XML 数据以获取经度/纬度坐标

iphone - 在通用应用程序中添加核心数据?

ffmpeg - 如何更高效地使用 FFMPEG 对 50 个 H264 流进行转码?