第47月第4天 arkit录制

1.

获取当前渲染的图像帧数据

要想保存视频,最重要一点就是得到当前渲染好的帧数据。得到帧数据后,下面的工作交给AVFoundation就可以轻松搞定了。
那么,如何得到当前画面的帧数据呢?
可以看到渲染的视图ARSCNView最终是继承自UIView,从UIView截取画面是很容易的。但是这样得到的画面,分辨率和当前视图的frame是一致的,如果要保存高分辨率就得缩放,这样肯定会模糊。所以这个方法最先排除。
再来看看ARSCNView这个类,它的直接父类是SCNView。前面提到SceneKit是苹果自带的游戏框架,这个框架里面或许有API能直接获取。查找了相关资料,确实发现SCNRenderer有个snapshotAtTime:withSize:antialiasingMode:方法可以截取UIImage,而SCNRenderer所需要的场景scene属性可以从ARSCNView中直接获取。既然可以得到UIImage,就可以转换为CVPixelBufferRel扔给AVFoundation框架处理。

 

https://blog.csdn.net/weixin_34267123/article/details/89565403

 

https://github.com/AFathi/ARVideoKit/

 

        if let view = view as? ARSCNView {
            guard let mtlDevice = MTLCreateSystemDefaultDevice() else {
                logAR.message("ERROR:- This device does not support Metal")
                return
            }
            renderEngine = SCNRenderer(device: mtlDevice, options: nil)
            renderEngine.scene = view.scene

            gpuLoop = CADisplayLink(target: WeakProxy(target: self),
                                    selector: #selector(renderFrame))
            gpuLoop.preferredFramesPerSecond = fps.rawValue
            gpuLoop.add(to: .main, forMode: .common)
            
            status = .readyToRecord
        }


if view is ARSCNView {
            guard let size = bufferSize else { return nil }
            //UIScreen.main.bounds.size
            var renderedFrame: UIImage?
            pixelsQueue.sync {
                renderedFrame = renderEngine.snapshot(atTime: self.time, with: size, antialiasingMode: .none)
            }
            if let _ = renderedFrame {
            } else {
                renderedFrame = renderEngine.snapshot(atTime: time, with: size, antialiasingMode: .none)
            }
            guard let buffer = renderedFrame!.buffer else { return nil }
            return buffer
        }

 

posted @ 2020-08-04 14:51  lianhuaren  阅读(196)  评论(0编辑  收藏  举报