为什么我的ARKit视频未在应用视图中显示

时间:2019-06-03 11:42:53

标签: ios swift xcode arkit

我有一个ARKit可以识别两个不同的跟踪图像

Vuforia和Tracker

当我为每个跟踪器使用不同的.scn时,它会起作用,并且它会在两者之间跳转。

我正在尝试获取Tracker图片以覆盖视频播放器,

我已经尽力想了一切,但现在陷入困境。

我检查了所有文件名和链接,但认为我必须缺少某些东西才能启动视频播放器。

帮助!

import UIKit
import SceneKit
import ARKit

class ThirdViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    let exampleVideoPlayer: AVPlayer = {
        //load example video from bundle
        guard let url = Bundle.main.url(forResource: "homer video", withExtension: "mov", subdirectory: "AR.scnassets") else {
            print("Could not find video file")
            return AVPlayer()
        }

        return AVPlayer(url: url)
    }()

    var FreemensNode: SCNNode?
    var VideoNode: SCNNode?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self
        sceneView.autoenablesDefaultLighting = true


        let FreemensScene = SCNScene(named: "AR.scnassets/Freemens.scn")
        let VideoScene = SCNScene(named: "AR.scnassets/Video.scn")
        FreemensNode = FreemensScene?.rootNode
        VideoNode = VideoScene?.rootNode

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARImageTrackingConfiguration()


        if let trackingImages = ARReferenceImage.referenceImages(inGroupNamed: "Photos", bundle: Bundle.main){

        configuration.trackingImages = trackingImages
        configuration.maximumNumberOfTrackedImages = 2

        }

        // Run the view's session
        sceneView.session.run(configuration)

    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate

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

        let node = SCNNode()

        if let imageAnchor = anchor as? ARImageAnchor {

            // Create a plane
            let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
            if imageAnchor.referenceImage.name == "Tracker" {
                // Set AVPlayer as the plane's texture and play
                plane.firstMaterial?.diffuse.contents = self.exampleVideoPlayer
                self.exampleVideoPlayer.play()

            } else if imageAnchor.referenceImage.name == "Vuforia" {
               plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.0)


            let planeNode = SCNNode(geometry: plane)
            planeNode.eulerAngles.x = -.pi / 2
            node.addChildNode(planeNode)

            }

            var shapeNode: SCNNode?
            switch imageAnchor.referenceImage.name {
            case ArItem.Freemens.rawValue :
                shapeNode = FreemensNode

            case ArItem.Video.rawValue :
                shapeNode = VideoNode
            default:
                break

            }



            if imageAnchor.referenceImage.name == "Vuforia" {
                 shapeNode = FreemensNode


            } else if imageAnchor.referenceImage.name == "Tracker"{
                shapeNode = VideoNode
            }

            guard let shape = shapeNode else { return nil}
            node.addChildNode(shape)
        }

        return node

    }

    enum ArItem : String {
        case Freemens = "Freemens"
        case Video = "Video"
    }

}

完整页面代码在这里

import UIKit
import SceneKit
import ARKit



class ThirdViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    var FreemensNode: SCNNode?
    var VideoNode: SCNNode?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self
        sceneView.autoenablesDefaultLighting = true


        let FreemensScene = SCNScene(named: "ar.scnassets/Freemens.scn")
        let VideoScene = SCNScene(named: "ar.scnassets/Video.scn")
        FreemensNode = FreemensScene?.rootNode
        VideoNode = VideoScene?.rootNode




    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARImageTrackingConfiguration()


        if let trackingImages = ARReferenceImage.referenceImages(inGroupNamed: "Photos", bundle: Bundle.main){

        configuration.trackingImages = trackingImages
        configuration.maximumNumberOfTrackedImages = 2

        }

        // Run the view's session
        sceneView.session.run(configuration)

    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate





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

        let node = SCNNode()



       if let imageAnchor = anchor as? ARImageAnchor {


        if let fileString = Bundle.main.path(forResource: "black", ofType: "mp4") {
            let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileString))


            let player = AVPlayer(playerItem: videoItem)
            //initialize video node with avplayer
            let videoNode = SKVideoNode(avPlayer: player)

            player.play()
            // add observer when our player.currentItem finishes player, then start playing from the beginning
            NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil) { (notification) in
                player.seek(to: CMTime.zero)
                player.play()
                print("Looping Video")
            }

            // set the size (just a rough one will do)
            let videoScene = SKScene(size: CGSize(width: 480, height: 360))
            // center our video to the size of our video scene
            videoNode.position = CGPoint(x: videoScene.size.width / 2, y: videoScene.size.height / 2)
            // invert our video so it does not look upside down
            videoNode.yScale = -1.0
            // add the video to our scene
            videoScene.addChild(videoNode)


            // Create a plane
            let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
            if imageAnchor.referenceImage.name == "Tracker" {
                // Set AVPlayer as the plane's texture and play
            plane.firstMaterial?.diffuse.contents = videoScene

            } else if imageAnchor.referenceImage.name == "Vuforia" {
               plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.0)


            let planeNode = SCNNode(geometry: plane)
            planeNode.eulerAngles.x = -.pi / 2
            node.addChildNode(planeNode)

            }

            var shapeNode: SCNNode?
            switch imageAnchor.referenceImage.name {
            case ArItem.Freemens.rawValue :
                shapeNode = FreemensNode

            case ArItem.Video.rawValue :
                shapeNode = VideoNode
            default:
                break

            }



            if imageAnchor.referenceImage.name == "Vuforia" {
                 shapeNode = FreemensNode


            } else if imageAnchor.referenceImage.name == "Tracker"{
                shapeNode = VideoNode



            }

            guard let shape = shapeNode else { return nil}
            node.addChildNode(shape)
        }

        return node

    }

    enum ArItem : String {
        case Freemens = "Freemens"
        case Video = "Video"
    }

}


}

1 个答案:

答案 0 :(得分:0)

我已经成功使用了这段代码

// 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 player
let skSceneSize = orientation == .horizontal ? CGSize(width: 1280, height: 720) : CGSize(width: 406, height: 720)
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

let scnPlaneSize : [String : CGFloat] = orientation == .horizontal ? ["width": 0.9, "height": 0.5063] : ["width": 0.5063, "height": 0.9]
let videoPlane = SCNPlane(width: scnPlaneSize["width"]!, height: scnPlaneSize["height"]!)
videoPlane.firstMaterial?.diffuse.contents = skScene
videoPlane.firstMaterial?.isDoubleSided = true

let videoPlaneNode = SCNNode(geometry: videoPlane)
node.addChildNode(videoPlaneNode)

// 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()