我有一个绘制了虚拟对象的ARSCNView。虚拟对象被绘制在用户的脸上。会话的配置如下:
let configuration = ARFaceTrackingConfiguration()
configuration.worldAlignment = .gravityAndHeading
sceneView.session.run(configuration)此ARSCNView是视频呼叫的一部分。如果我们像下面这样发回像素缓冲区,
public func session(_ session: ARSession, didUpdate frame: ARFrame) {
videoSource.sendBuffer(frame.capturedImage, timestamp: frame.timestamp)
}虚拟对象不会显示给我的调用者。
我尝试过的一件事是,不依赖于ARSessionDelegate的回调,而是使用DispatchSourceTimer来发送事件。
func startCaptureView() {
// Timer with 0.1 second interval
timer.schedule(deadline: .now(), repeating: .milliseconds(100))
timer.setEventHandler { [weak self] in
// Turn sceneView data into UIImage
guard let sceneImage: CGImage = self?.sceneView.snapshot().cgImage else {
return
}
self?.videoSourceQueue.async { [weak self] in
if let buffer: CVPixelBuffer = ImageProcessor.pixelBuffer(forImage: sceneImage) {
self?.videoSource.sendBuffer(buffer, timestamp: Double(mach_absolute_time()))
}
}
}
timer.resume()
}呼叫者接收数据的速度很慢,视频体验不稳定,图像大小不正确。
关于如何将有关虚拟对象的数据与捕获的帧一起发送,有什么建议吗?
参考:https://medium.com/agora-io/augmented-reality-video-conference-6845c001aec0
发布于 2020-04-21 01:37:20
没有显示虚拟对象的原因是因为ARKit仅提供原始图像,因此frame.capturedImage是摄像机捕获的图像,没有任何SceneKit渲染。要传递渲染的视频,您需要实现一个离屏SCNRenderer,并将像素缓冲区传递给Agora的SDK。
我建议你去看看开源框架AgoraARKit。我编写了这个框架,它将Agora.io Video SDK和ARVideoKit实现为依赖项。ARVideoKit是一个流行的库,它实现了屏幕外的渲染器,并提供了渲染的像素缓冲区。
默认情况下,该库实现WorldTracking。如果想要扩展ARBroadcaster类来实现faceTracking,可以使用以下代码:
import ARKit
class FaceBroadcaster : ARBroadcaster {
// placements dictionary
var faceNodes: [UUID:SCNNode] = [:] // Dictionary of faces
override func viewDidLoad() {
super.viewDidLoad()
}
override func setARConfiguration() {
print("setARConfiguration") // Configure ARKit Session
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
// run the config to start the ARSession
self.sceneView.session.run(configuration)
self.arvkRenderer?.prepare(configuration)
}
// anchor detection
override func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
super.renderer(renderer, didAdd: node, for: anchor)
guard let sceneView = renderer as? ARSCNView, anchor is ARFaceAnchor else { return }
/*
Write depth but not color and render before other objects.
This causes the geometry to occlude other SceneKit content
while showing the camera view beneath, creating the illusion
that real-world faces are obscuring virtual 3D objects.
*/
let faceGeometry = ARSCNFaceGeometry(device: sceneView.device!)!
faceGeometry.firstMaterial!.colorBufferWriteMask = []
let occlusionNode = SCNNode(geometry: faceGeometry)
occlusionNode.renderingOrder = -1
let contentNode = SCNNode()
contentNode.addChildNode(occlusionNode)
node.addChildNode(contentNode)
faceNodes[anchor.identifier] = node
}
}https://stackoverflow.com/questions/61295894
复制相似问题