CMSampleBufferRef和AVAssetReaderMixAudioOutput和PCM问题

时间:2014-08-10 23:55:35

标签: macos cocoa audio avfoundation avassetreader

所以我使用AVAssetReaderMixAudioOutput从quicktime文件中提取音频样本。 在这种情况下,它是具有多个音频轨道的ProRes视频。

(4轨,16位,交错样本littleEndian @ 48000)

我可以把视频帧搞定, 但是当我调用[myAssetReaderAudioMixOutput copyNextSampleBuffer]时 我遇到了一些奇怪的问题.... 看来返回的音频都在第一个频道?

使用个人trackOutputReader,我得到了 第一帧的每个轨道的第一个音频样本是:

620B 700E 0000 0000

但是当我使用AVAssetReaderMixAudioOutput时,我得到了

D219 0000 0000 0000

(注意620B + 700E = D219) 所以看起来AVAssetReaderMixAudioOutput正在对所有值进行求和 4个频道并在曲目1中给我结果?

任何人都可以解释原因吗? 以及如何解决它? 我需要一个解决方案,它会给我一个1:1的频道映射,因为它们在quicktime文件中, 即。它需要适用于包含1声道和16声道音频的文件。

我通过在每个音频通道上自行执行copyNextSampleBuffer来获得第一个样本的正确值

这是我用来创建myAssetReaderAudioMixOutput ....

的字典
NSDictionary *outputSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:48000], AVSampleRateKey,
[NSNumber numberWithInt:4], AVNumberOfChannelsKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
[NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
nil];

myAssetReaderAudioMixOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:audioTracks audioSettings: outputSettings];

我正在使用以下代码来读取CMSampleBuffer中的实际音频样本/数据。

enteraudioBuffer = [assetReaderAudioMixOutput copyNextSampleBuffer]; if(audioBuffer) {     CMBlockBufferRef audioBlockBuffer = CMSampleBufferGetDataBuffer(audioBuffer);

// lets get some more info about our SampleBuffer, or at least sample size for sample 0!
CMTime sampleDuration = CMSampleBufferGetDuration(audioBuffer);
size_t sampleSize =  CMSampleBufferGetSampleSize(audioBuffer, 0);
CMItemCount numSamplesInBuffer = CMSampleBufferGetNumSamples(audioBuffer);

bfAudioBuffer* pbfBuffer = new bfAudioBuffer();
int samplesNeededForThisFrame = 1920;           // sample for FrameNo(frameNo, vidMode);
int sizeOfDataToBeCopied = samplesNeededForThisFrame * sampleSize
// Audio Samples for 1 frames worth of audio should be copied into pbfBuffer->pPcmBuffer
CMBlockBufferCopyDataBytes(audioBlockBuffer, 0, sizeOfDataToBeCopied, pbfBuffer->pPcmBuffer);

}

(对不起它似乎在修改代码,因为我粘贴它,不明白为什么,我确实尝试了一些不同的东西 - 抱歉)

所以我认为我的问题是设置字典或阅读样本。 我使用相同的系统来读取单个轨道的样本,所以我怀疑是吗? 我只是无法理解为什么它给了我4个音轨的正确数据/样本数量,但之后只将信息放在第一个音轨中?

最后我在OSX上,不在乎iOS。

感谢您的帮助, 这非常令人沮丧!

  • 詹姆斯

1 个答案:

答案 0 :(得分:0)

对,我终于找到了这个问题的答案,所以我想我会用解决方案更新我的问题。

所以问题在于我对AVAssetReaderMixAudioOutput实际上做了什么的理解。

我以为我能够给我混合多个音频轨道,但实际上是以用户指定的方式混合音轨然后它返回音频的音轨。 (请记住,这里的“轨道”可能是单声道的立体声声音)

为了从文件中获取多轨音,我需要为每个想要提取的音轨设置AVAssetReader。

希望有人发现这个有用的