中心思路

经过SCNView的回调,取到id<SCNSceneRenderer>中 metal renderPass的烘托方针纹路,将烘托方针纹路复制到基于CVPixelBuffer创立的Metal纹路,再将CVPixelBuffer写到视频文件中即可。

准备线程是什么意思视频写入东西

运用体系自带的AVAssetWriter能够轻松的进行视频创立,经过下面的代码创立并装备AVAssetWriter

self.videoWriter = [AVAssetWriter assetWriterWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:&error];
NSDictionary *writerInputParams = [NSDictionary dictionaryWithObjectsAndKeys:
                                               AVVideoCodecTypeH264, AVVideoCodecKey,
                                                         [NSNumber numberWithInt:width], AVVideoWidthKey,
                                                         [NSNumber numberWithInt:height], AVVideoHeightKey,
                                                         AVVideoScalingModeResizeAspectFill, AVVideoScalingModeKey,
                                                         nil];
self.assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:writerInputParams];
if ([self.videoWriter canAddInput:self.assetWriterInput]) {
    [self.videoWriter addInput:self.assetWriterInput];
} else {
    // show error message
}
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange], (NSString*)kCVPixelBufferPixelFormatTypeKey,
                            [NSNumber numberWithBool:YES], (NSString *)kCVPixelBufferCGImageCompatibilityKey,
                            [NSNumber numberWithBool:YES], (NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey,
                            nil];
self.writerAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:self.assetWriterInput sourcePixelBufferAttributes:attributes];

经过下面的API能够将CVPixelBuffer写入视频文件ios应用商店

[self.writerAdaptor appendPixelBuffer:cvBuffer withPresentationTime:presentationTime]

准备承受图像数据的CVPixelBuffer

创立CVPixelBuffer并经过CVPixelBuffer创立MTLTexture,用于复制SCNView的烘托方针纹路

int imageWidth = size.width;
int imageHeight = size.height;
NSDictionary *pixelAttributes = @{( id )kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferCreate(
            kCFAllocatorDefault,
                    imageWidth,
                    imageHeight,
            kCVPixelFormatType_32BGRA,
                    (__bridge CFDictionaryRef)pixelAttributes,
                    &_renderTargetPixelBuffer);
CVReturn ret = CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _mtlDevice, nil, &_textureCache);
CVMetalTextureRef renderTargetMetalTextureRef;
ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, _renderTargetPixelBuffer, nil, MTLPixelFormatBGRA8Unorm, imageWidth, imageHeight, 0, &renderTargetMetalTextureRef);
id<MTLTexture> mtlTexture = CVMetalTextureGetTexture(renderTargetMetalTextureRef);
CFRelease(renderTargetMetalTextureRef);

将SCNVieios14.4.1更新了什么w的烘托成果复制到C线程池VPixelBuffer

咱们需要在SCNView的- (vios16oid)renderer:(id<SCNSceneRenderer>)renderappearanceer didRenderScene:(SCNScen线程池面试题e *)scene atTime:(NSTimeInterval)time回调中复制烘托成果,为了能够复制SCNView的烘托方针纹路,需要做以下设置

CAMetalLayer *metalLayer = (CAMetalLayer *)self.sceneView.layer;
[metalLayer setAllowsNextDrawableTimeout:NO];
metalLayer.framebufferOnly = NO;

在回调中咱们使用MTLBlios是苹果还是安卓itCommandEncoder复制烘托方针纹路到咱们自己的纹路

MTLRenderPassDescriptor *renderPassDesc = renderer.currentRenderPassDescriptor;
id<MTLTexture> readTexture = renderPassDesc.colorAttachments[0].texture;
if (readTexture.width != _renderTargetTexture.width || readTexture.height != _renderTargetTexture.height) {
    _renderTargetTexture = [self createRenderTargetTexture:CGSizeMake(readTexture.width, readTexture.height)];
}
id<MTLCommandBuffer> blitCommandBuffer = [renderer.commandQueue commandBuffer];
id <MTLBlitCommandEncoder> blitEncoder = [blitCommandBuffer blitCommandEncoder];
[blitEncoder copyFromTexture:readTexture toTexture:_renderTargetTexture];
[blitEncoder endEncoding];
[blitCommandBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull buffer) {
    [self updateWithFrame:self->_renderTargetPixelBuffer];
}];
[blitCommandBuffer commit];

blitCommandBuffer来自SCNView的commandQueue,所以复制纹路的command会在SCNView烘托完之后才履行,确保了复制的纹路是一次完好线程是什么意思的烘托。留意blitCommandBuffer不能够运用waitUntilCompleted阻塞线程,会导致死锁。最后在updateWithFrame将CVPixelBuffer写入AVAssetWriter