ReplayKit2 采集音视频回调格式分析

一、iOS中的音视频都是采用一个叫做CMSampleBuffer的格式封装的

  比如回调的App音频

Printing description of sampleBuffer:
CMSampleBuffer 0x143d06560 retainCount: 1 allocator: 0x25bae95e0
	invalid = NO
	dataReady = YES
	makeDataReadyCallback = 0x0
	makeDataReadyRefcon = 0x0
	formatDescription = <CMAudioFormatDescription 0x281940990 [0x25bae95e0]> {
	mediaType:'soun' 
	mediaSubType:'lpcm' 
	mediaSpecific: {
		ASBD: {
			mSampleRate: 44100.000000 
			mFormatID: 'lpcm' 
			mFormatFlags: 0xe 
			mBytesPerPacket: 2 
			mFramesPerPacket: 1 
			mBytesPerFrame: 2 
			mChannelsPerFrame: 1 
			mBitsPerChannel: 16 	} 
		cookie: {(null)} 
		ACL: {(null)}
		FormatList Array: {(null)} 
	} 
	extensions: {(null)}
}
	sbufToTrackReadiness = 0x0
	numSamples = 22528
	sampleTimingArray[1] = {
		{PTS = {619877934457375/1000000000 = 619877.934}, DTS = {INVALID}, duration = {1/44100 = 0.000}},
	}
	dataBuffer = 0x281940360

  

  比如回调的micphone音频

Printing description of sampleBuffer:
CMSampleBuffer 0x149e053b0 retainCount: 1 allocator: 0x25bae95e0
	invalid = NO
	dataReady = YES
	makeDataReadyCallback = 0x0
	makeDataReadyRefcon = 0x0
	formatDescription = <CMAudioFormatDescription 0x281b47b10 [0x25bae95e0]> {
	mediaType:'soun' 
	mediaSubType:'lpcm' 
	mediaSpecific: {
		ASBD: {
			mSampleRate: 44100.000000 
			mFormatID: 'lpcm' 
			mFormatFlags: 0xc 
			mBytesPerPacket: 2 
			mFramesPerPacket: 1 
			mBytesPerFrame: 2 
			mChannelsPerFrame: 1 
			mBitsPerChannel: 16 	} 
		cookie: {(null)} 
		ACL: {(null)}
		FormatList Array: {(null)} 
	} 
	extensions: {(null)}
}
	sbufToTrackReadiness = 0x0
	numSamples = 1024
	sampleTimingArray[1] = {
		{PTS = {27273930501/44100 = 618456.474, rounded}, DTS = {INVALID}, duration = {1/44100 = 0.000}},
	}
	dataBuffer = 0x281b47c30

 从这个结构中,可以得到这个音频数据的描述信息

  // Get samples.
        CMBlockBufferRef audioBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
        size_t lengthAtOffset;
        size_t totalLength;
        char *samples;
        CMBlockBufferGetDataPointer(audioBuffer, 0, &lengthAtOffset, &totalLength, &samples);

        // Get format.
        CMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);
        const AudioStreamBasicDescription *description = CMAudioFormatDescriptionGetStreamBasicDescription(format);

  输出为格式的描述信息

Printing description of format:
<CMAudioFormatDescription 0x28282f7b0 [0x25bae95e0]> {
	mediaType:'soun' 
	mediaSubType:'lpcm' 
	mediaSpecific: {
		ASBD: {
			mSampleRate: 44100.000000 
			mFormatID: 'lpcm' 
			mFormatFlags: 0xc 
			mBytesPerPacket: 2 
			mFramesPerPacket: 1 
			mBytesPerFrame: 2 
			mChannelsPerFrame: 1 
			mBitsPerChannel: 16 	} 
		cookie: {(null)} 
		ACL: {(null)}
		FormatList Array: {(null)} 
	} 
	extensions: {(null)}
}

  关于音频格式有几个关键信息:格式、采样率、采样精度、声道数

  关于音频数据除了上面的格式信息之外,还有 PTS 、 samples(帧数)描述信息

  比如上面的PCM数据中,采样率是44100hz、采样深度是16位、声道数是1,samples是1024帧,最后计算这段声音的长度信息是 (1/44100) * 1024 = 23ms , 这个声音的数据大小是 1024 * 2byte = 2014 Byte

  如果是录制声音的话,需要先设置需要录制的音频格式信息  

AudioStreamBasicDescription format;
memset(&format, 0, sizeof(format));
format.mSampleRate = 44100;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
format.mChannelsPerFrame = 1;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = (format.mBitsPerChannel/8) * format.mChannelsPerFrame;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;

  需要设置关键参数、采样率、采样精度、声道数、数据排列格式、 一个packet的帧数

 

附录:

  关于采样精度

  

关于采样率

  

 

原文地址:https://www.cnblogs.com/doudouyoutang/p/9908654.html