Как воспроизвести видео с помощью функции отслеживания изображения на камере (SCNNode) с помощью Swift - PullRequest
1 голос
/ 11 марта 2020

Я новичок в ARKit. Я использую отслеживание изображений, чтобы обнаружить изображение и отобразить содержимое рядом с этим изображением. На левой стороне изображения я отображаю некоторую информацию изображения и на правая сторона Я показываю Веб-просмотр . Я просто хочу показать видео поверх изображения (вверху). Не могли бы вы, ребята, помогите мне показать видео поверх изображения (вверху). Я прикрепил код для Info и webview similary, который я хочу отобразить к видео

func displayDetailView(on rootNode: SCNNode, xOffset: CGFloat) {
        let detailPlane = SCNPlane(width: xOffset, height: xOffset * 1.4)
        detailPlane.cornerRadius = 0.25

        let detailNode = SCNNode(geometry: detailPlane)
        detailNode.geometry?.firstMaterial?.diffuse.contents = SKScene(fileNamed: "DetailScene")

        // Due to the origin of the iOS coordinate system, SCNMaterial's content appears upside down, so flip the y-axis.
        detailNode.geometry?.firstMaterial?.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)
        detailNode.position.z -= 0.5
        detailNode.opacity = 0

        rootNode.addChildNode(detailNode)
        detailNode.runAction(.sequence([
            .wait(duration: 1.0),
            .fadeOpacity(to: 1.0, duration: 1.5),
            .moveBy(x: xOffset * -1.1, y: 0, z: -0.05, duration: 1.5),
            .moveBy(x: 0, y: 0, z: -0.05, duration: 0.2)
            ])
        )
    }

    func displayWebView(on rootNode: SCNNode, xOffset: CGFloat) {
        // Xcode yells at us about the deprecation of UIWebView in iOS 12.0, but there is currently
        // a bug that does now allow us to use a WKWebView as a texture for our webViewNode
        // Note that UIWebViews should only be instantiated on the main thread!
        DispatchQueue.main.async {
            let request = URLRequest(url: URL(string: "https://www.youtube.com/watch?v=QvzVCOiC-qs")!)
            let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: 400, height: 672))
            webView.loadRequest(request)

            let webViewPlane = SCNPlane(width: xOffset, height: xOffset * 1.4)
            webViewPlane.cornerRadius = 0.25

            let webViewNode = SCNNode(geometry: webViewPlane)
            webViewNode.geometry?.firstMaterial?.diffuse.contents = webView
            webViewNode.position.z -= 0.5
            webViewNode.opacity = 0

            rootNode.addChildNode(webViewNode)
            webViewNode.runAction(.sequence([
                .wait(duration: 3.0),
                .fadeOpacity(to: 1.0, duration: 1.5),
                .moveBy(x: xOffset * 1.1, y: 0, z: -0.05, duration: 1.5),
                .moveBy(x: 0, y: 0, z: -0.05, duration: 0.2)
                ])
            )
        }
    }

Я вызвал этот метод в нижеследующая функция ..

  func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let imageAnchor = anchor as? ARImageAnchor else { return }

        updateQueue.async {
            let physicalWidth = imageAnchor.referenceImage.physicalSize.width
            let physicalHeight = imageAnchor.referenceImage.physicalSize.height

            // Create a plane geometry to visualize the initial position of the detected image
            let mainPlane = SCNPlane(width: physicalWidth, height: physicalHeight)
            mainPlane.firstMaterial?.colorBufferWriteMask = .alpha

            // Create a SceneKit root node with the plane geometry to attach to the scene graph
            // This node will hold the virtual UI in place
            let mainNode = SCNNode(geometry: mainPlane)
            mainNode.eulerAngles.x = -.pi / 2
            mainNode.renderingOrder = -1
            mainNode.opacity = 1

            // Add the plane visualization to the scene
            node.addChildNode(mainNode)

            // Perform a quick animation to visualize the plane on which the image was detected.
            // We want to let our users know that the app is responding to the tracked image.
            self.highlightDetection(on: mainNode, width: physicalWidth, height: physicalHeight, completionHandler: {

                // Introduce virtual content
                self.displayDetailView(on: mainNode, xOffset: physicalWidth)

                // Animate the WebView to the right
                self.displayWebView(on: mainNode, xOffset: physicalWidth)

            })
        }
    }

Любая помощь приветствуется ..

1 Ответ

0 голосов
/ 13 марта 2020

Эффект, который вы пытаетесь достичь, - это воспроизведение видео на SCNNode. Чтобы сделать это, в вашем приложении для визуализации c вам нужно создать AVPlayer и использовать его для создания SKVideoNode. Затем вам нужно создать SKScene, добавить SKVideoNode. Затем установите текстуру вашего самолета в SKScene.

, так что в контексте кода выше:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let imageAnchor = anchor as? ARImageAnchor else { return }

    updateQueue.async {
        let physicalWidth = imageAnchor.referenceImage.physicalSize.width
        let physicalHeight = imageAnchor.referenceImage.physicalSize.height

        // Create a plane geometry to visualize the initial position of the detected image
        let mainPlane = SCNPlane(width: physicalWidth, height: physicalHeight)
        mainPlane.firstMaterial?.colorBufferWriteMask = .alpha

        // Create a SceneKit root node with the plane geometry to attach to the scene graph
        // This node will hold the virtual UI in place
        let mainNode = SCNNode(geometry: mainPlane)
        mainNode.eulerAngles.x = -.pi / 2
        mainNode.renderingOrder = -1
        mainNode.opacity = 1

        // Add the plane visualization to the scene
        node.addChildNode(mainNode)

        // Perform a quick animation to visualize the plane on which the image was detected.
        // We want to let our users know that the app is responding to the tracked image.
        self.highlightDetection(on: mainNode, width: physicalWidth, height: physicalHeight, completionHandler: {

            // Introduce virtual content
            self.displayDetailView(on: mainNode, xOffset: physicalWidth)

            // Animate the WebView to the right
            self.displayWebView(on: mainNode, xOffset: physicalWidth)

            // setup AV player & create SKVideoNode from avPlayer
            let videoURL = URL(fileURLWithPath: Bundle.main.path(forResource: videoAssetName, ofType: videoAssetExtension)!)
            let player = AVPlayer(url: videoURL)
            player.actionAtItemEnd = .none
            videoPlayerNode = SKVideoNode(avPlayer: player)

            // setup SKScene to hold the SKVideoNode
            let skSceneSize = CGSize(width: physicalWidth, height: physicalHeight)
            let skScene = SKScene(size: skSceneSize)
            skScene.addChild(videoPlayerNode)

            videoPlayerNode.position = CGPoint(x: skScene.size.width/2, y: skScene.size.height/2)
            videoPlayerNode.size = skScene.size

            // Set the SKScene as the texture for the main plane
            mainPlane.firstMaterial?.diffuse.contents = skScene
            mainPlane.firstMaterial?.isDoubleSided = true

            // setup node to auto remove itself upon completion
            NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil, using: { (_) in
                DispatchQueue.main.async {
                    if self.debug { NSLog("video completed") }
                    // do something when the video ends
                }
            })
            // play the video node
            videoPlayerNode.play()

        })
    }
}
...