Отслеживание нескольких изображений и воспроизведение их видео в ARkit2 - PullRequest
0 голосов
/ 06 сентября 2018

Ниже приведен пример кода, отслеживание одного изображения, а затем воспроизведение видео с помощью Apple ARkit. В настоящее время видео хранятся локально на устройстве. Код ниже просто отслеживает одно изображение и воспроизводит соответствующее видео. Как я могу изменить его и позволить ему отслеживать несколько изображений и воспроизводить их видео?

 @IBOutlet var sceneView: ARSCNView!

// Create video player
let videoPlayer: AVPlayer = {
    // Load cat video from bundle
    guard let url = Bundle.main.url(forResource: "nyan-cat", withExtension: "mp4", subdirectory: "art.scnassets") else {
        print("Could not find video file")
        return AVPlayer()
    }

    let player = AVPlayer(url: url)

    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in
        player.seek(to: CMTime.zero)
        player.play()
    }
    return player
}()

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let node = SCNNode()

    // Show video overlayed to image
    if let imageAnchor = anchor as? ARImageAnchor {

        // Create a plane
        let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width,
                             height: imageAnchor.referenceImage.physicalSize.height)

        // Set AVPlayer as the plane's texture and play
        plane.firstMaterial?.diffuse.contents = self.videoPlayer
        self.videoPlayer.play()

        let playNode = SCNNode(geometry: plane)

        // Rotate the plane to match the anchor
        playNode.eulerAngles.x = -.pi / 2

        // Add plane node to parent
        node.addChildNode(playNode)
    }

    return node
}

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Как сказано в @SilentK, для отслеживания нескольких ARImageAnchors необходимо установить максимальное количество отслеживаемых изображений, например:

configuration.maximumNumberOfTrackedImages = 10

Который с IOS12 доступен как для ARWorldTrackingConfiguration, так и для ARImageTrackingConfiguration.

Поскольку вы также знаете, что когда вы добавляете ARReferenceImage к вашему Assets Bundle, вы должны присвоить ему name например:

enter image description here

Теперь, поскольку каждая цель содержит уникальное имя, вы можете легко использовать это для загрузки различных видео. Поэтому наиболее целесообразно называть каждое видео тем же, что и ваше imageTarget.

Пример того, что вы пытаетесь сделать, может выглядеть так:

//-------------------------
//MARK: - ARSCNViewDelegate
//-------------------------

extension ViewController: ARSCNViewDelegate{

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        //1. Check We Have Detected An ARImageAnchor
        guard let validAnchor = anchor as? ARImageAnchor else { return }

        //2. Create A Video Player Node For Each Detected Target
        node.addChildNode(createdVideoPlayerNodeFor(validAnchor.referenceImage))

    }


    /// Creates An SCNNode With An AVPlayer Rendered Onto An SCNPlane
    ///
    /// - Parameter target: ARReferenceImage
    /// - Returns: SCNNode
    func createdVideoPlayerNodeFor(_ target: ARReferenceImage) -> SCNNode{

        //1. Create An SCNNode To Hold Our VideoPlayer
        let videoPlayerNode = SCNNode()

        //2. Create An SCNPlane & An AVPlayer
        let videoPlayerGeometry = SCNPlane(width: target.physicalSize.width, height: target.physicalSize.height)
        var videoPlayer = AVPlayer()

        //3. If We Have A Valid Name & A Valid Video URL The Instanciate The AVPlayer
        if let targetName = target.name,
            let validURL = Bundle.main.url(forResource: targetName, withExtension: "mp4", subdirectory: "/art.scnassets") {
            videoPlayer = AVPlayer(url: validURL)
            videoPlayer.play()
        }

        //4. Assign The AVPlayer & The Geometry To The Video Player
        videoPlayerGeometry.firstMaterial?.diffuse.contents = videoPlayer
        videoPlayerNode.geometry = videoPlayerGeometry

        //5. Rotate It
        videoPlayerNode.eulerAngles.x = -.pi / 2

        return videoPlayerNode

    }

}

Воспроизведение с бесконечным циклом при использовании этого метода довольно сильно загружает процессор, если у вас есть несколько визуализированных экземпляров:

 NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in
        player.seek(to: CMTime.zero)
        player.play()
    }

Таким образом, вы, вероятно, захотите добавить логику, чтобы проигрывать только одно видео за раз, например выполнение SCNHitTest для VideoNode, что приведет к его воспроизведению и т. д.

Надеюсь, это поможет ...

0 голосов
/ 08 сентября 2018

Вы должны установить MaximumNumberOfTrackedImages в вашей конфигурации AR.

Установка максимального количества отслеживаемых изображений ограничит количество изображения, которые можно отслеживать в заданном кадре. Если видно больше максимума, только отслеживаемые изображения будут продолжать отслеживаться, пока отслеживание не будет потеряно или другое изображение удалено Значение по умолчанию - один.

        configuration.maximumNumberOfTrackedImages = 2
...