在我們使用AVAssetWriter的時候可帽,經(jīng)常會用到AVAssetWriterInputPixelBufferAdaptor
這個類昵时,從字義上來理解,它是一個輸入的像素緩沖適配器脂凶,看起來就像你電腦的電源適配器一樣敲街。我們來看一下apple官網(wǎng)對它的解釋:
A buffer used to append video samples packaged as pixel buffers to a single asset writer input.
apple的解釋是,它是一個緩沖區(qū)绞旅,作為assetWriter的輸入摆尝,用于把緩沖池中的像素打包追加到視頻樣本上温艇。這樣解釋,是不是很清晰了结榄?
那么中贝,為什么要使用它呢?
舉例來說臼朗,當我們要將攝像頭獲取的原數(shù)據(jù)(一般是CMSampleBufferRef
)寫入文件的時候邻寿,需要將CMSampleBufferRef
轉(zhuǎn)成CVPixelBuffer
,而這個轉(zhuǎn)換是在CVPixelBufferPool
中完成的
CVPixelBufferRef newPixelBuffer = NULL;
CVPixelBufferPoolCreatePixelBuffer(NULL, self.inputPixelBufferAdptor.pixelBufferPool, &newPixelBuffer);
AVAssetWriterInputPixelBufferAdaptor
的實例提供了一個CVPixelBufferPool
视哑,可用于分配像素緩沖區(qū)來寫入輸出數(shù)據(jù)绣否。 使用它提供的像素緩沖池進行緩沖區(qū)分配通常比使用額外創(chuàng)建的緩沖區(qū)更有效。這是官方的說法挡毅,不建議我們另行創(chuàng)建一個CVPixelBufferPool
來使用蒜撮。
下面仔細來研究一下AVAssetWriterInputPixelBufferAdaptor
這個類:
它有三個重要的屬性:
@property (nonatomic, readonly) AVAssetWriterInput *assetWriterInput;
@property (nonatomic, readonly, nullable) NSDictionary<NSString *, id> *sourcePixelBufferAttributes;
@property (nonatomic, readonly, nullable) CVPixelBufferPoolRef pixelBufferPool;
首先,每個AVAssetWriterInputPixelBufferAdaptor
都包含一個assetWriterInput跪呈,用于接收緩沖區(qū)中的數(shù)據(jù)段磨,并且AVAssetWriterInput
有一個很重要的屬性readyForMoreMediaData
,這是一個鍵值觀察屬性耗绿,它會經(jīng)常地異步地在NO和YES之間變換苹支,來標識現(xiàn)在緩沖區(qū)中的數(shù)據(jù)是否已經(jīng)處理完成。通過判斷這個屬性误阻,我們可以向AVAssetWriterInputPixelBufferAdaptor
中添加數(shù)據(jù)以進行處理债蜜。
if (self.inputPixelBufferAdptor.assetWriterInput.isReadyForMoreMediaData ) {
BOOL success = [self.inputPixelBufferAdptor appendPixelBuffer:newPixelBuffer withPresentationTime:self.currentSampleTime];
if (!success) {
NSLog(@"append pixel buffer failed");
}
}
再來說一下第二個屬性sourcePixelBufferAttributes:
它是輸入像素源的一些屬性,一般由CVPixelBufferPool
提供究反,比如像素寬高寻定,色彩空間等
NSDictionary* sourcePixelBufferAttributesDictionary =
@{
(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA),
(NSString*)kCVPixelBufferWidthKey:@(self.currentVideoDimensions.width),
(NSString*)kCVPixelBufferHeightKey:@(self.currentVideoDimensions.height),
(NSString*)kCVPixelFormatOpenGLESCompatibility:@(1)
};
與之對應(yīng)的,是編碼輸出屬性精耐,這個屬性在AVAssetWriterInput
里狼速,我們上面說過,每個AVAssetWriterInputPixelBufferAdaptor
都包含一個assetWriterInput黍氮。輸出屬性包括輸出碼率唐含,幀率,最大I幀間隔沫浆,編碼方式捷枯,輸出分辨率以及填充模式,方向等专执。
NSDictionary* compressionProperties =
@{
AVVideoAverageBitRateKey:@(bitsPerSecond),
AVVideoExpectedSourceFrameRateKey:@(30),
AVVideoMaxKeyFrameIntervalKey:@(30),
AVVideoProfileLevelKey:AVVideoProfileLevelH264BaselineAutoLevel
};
NSDictionary* outputSettings =
@{
AVVideoCodecKey:type,
AVVideoWidthKey:@480,
AVVideoHeightKey:@640,
AVVideoScalingModeKey:AVVideoScalingModeResizeAspect,
AVVideoCompressionPropertiesKey:compressionProperties
};
這些是視頻的主要參數(shù)淮捆,當然還有音頻的,比如采樣率,聲道攀痊,編碼方式桐腌,輸出碼率等」毒叮可以對比demo進行查看案站。
對于第三個屬性CVPixelBufferPoolRef
,上面有說過棘街,它是處理像素的緩沖區(qū)蟆盐,我們一般會使用它將CMSampleBufferRef
生成CVPixelBufferRef
。
哈勒遭殉,關(guān)于AVAssetWriterInputPixelBufferAdaptor
的常見用法就說到這里石挂,如果這篇文章對您有所幫助,請點擊下面的支持险污,非常感謝~ 點擊支持后痹愚,會有demo的下載鏈接。
【Light & Shallow】(https://github.com/RonbeKing/Light-Shallow)
若您喜歡demo蛔糯,還請點擊star拯腮,能讓更多的同學(xué)看到,共同探討蚁飒,指正疾瓮,拜謝!