ios視頻實時渲染

需求

由于需求的原因要做到視頻的實時渲染但是并不改變原視頻,也就是說不是針對視頻本身去加濾鏡,所以就一直在網(wǎng)上找方法,網(wǎng)上大神說是要拿到視頻的每一幀圖片進行渲染。接下來就開始動手。


截圖


1.拿到視頻每一幀

在AVFoundation框架里有一個類AVPlayerItemVideoOutput,用來獲取視頻輸出的每一幀,具體看代碼

AVPlayerItem *item = [AVPlayerItem playerItemWithURL:videoUrl];

_videoOutPut = [[AVPlayerItemVideoOutput alloc] initWithOutputSettings:nil];

_player = [[AVPlayer alloc] initWithPlayerItem:item];

[self.player.currentItem addOutput:_videoOutPut];

上面初始化了一個item和videoOutPut,并且把videoOutPut加到了item上面,現(xiàn)在我們要在每一幀的時候去獲取buffer。

CMTime itemTime = [_videoOutPut itemTimeForHostTime:CACurrentMediaTime()];

if ([_videoOutPut hasNewPixelBufferForItemTime:itemTime]) {

CVPixelBufferRef pixelBuffer = [_videoOutPut copyPixelBufferForItemTime:itemTime itemTimeForDisplay:nil];

CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];

CVBufferRelease(pixelBuffer);

}else{

}

這樣我們就獲取到了視頻每一幀的CIImage,現(xiàn)在我們就可以加上濾鏡了。

2.加濾鏡

加濾鏡就簡單用了系統(tǒng)的對比度,亮度之類的具體的大家可自行配置好看的濾鏡。

CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];

[filter setValue:ciImg forKey:kCIInputImageKey];

[filter setDefaults];

// 修改亮度 -1---1 數(shù)越大越亮

[filter setValue:@(self.light) forKey:@"inputBrightness"];

// 修改飽和度 0---2

[filter setValue:@(self.saturation) forKey:@"inputSaturation"];

// 修改對比度 0---4

[filter setValue:@(self.contrast) forKey:@"inputContrast"];

CIImage *outputImage = [filter outputImage];

現(xiàn)在就剩顯示出來了,我們選擇了用opengl進行渲染,用CPU的話會稍微有些卡頓。

3.顯示

初始化glkview,進行配置。然后我們傳入一個經(jīng)過CIFilter處理的CIImage就可以渲染出來了。

- (void)initGlkView{

EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

_glkView = [[GLKView alloc] initWithFrame:CGRectZero context:eaglContext];

_glkView.delegate = self;

[_glkView bindDrawable];

_glkView.enableSetNeedsDisplay = NO;

[self addSubview:_glkView];

[EAGLContext setCurrentContext:eaglContext];

_imageContext = [CIContext contextWithEAGLContext:eaglContext options:@{kCIContextWorkingColorSpace:[NSNull null]}];

}


在傳入CIImage的方法里,調(diào)用display方法進行繪制。

- (void)setRenderImg:(CIImage *)renderImg{

_renderImg = renderImg;

[self.glkView display];

}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{

[self.imageContext drawImage:self.renderImg inRect:CGRectMake(0, 0, self.glkView.drawableWidth, self.glkView.drawableHeight) fromRect:[self.renderImg extent]];

}

具體代碼地址:https://github.com/zhuyongqing/ZYPlayerView

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容