ARKIT:SKVideoNode 在节点不在场景中时继续播放,暂停不起作用 [英] ARKIT : SKVideoNode continue playing while node is out of scene, pause is not working

查看:22
本文介绍了ARKIT:SKVideoNode 在节点不在场景中时继续播放,暂停不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SceneKit 和 ARKit 实现一个演示项目,其中我将相机放在一些图片上并从 url 播放视频.一切正常,但我无法停止之前的视频并开始另一个视频.以前的视频在后台播放.当我切换图像时有时会发生这种情况.我的实现是:

I am implementing a demo project using SceneKit and ARKit where i keep camera on some picture and play video from url. Everything works fine but i could not be able to stop previous video and it starts another video. Previous video plays on background. It happens sometimes when i switch image. My implementation is :

@IBOutlet var sceneView: ARSCNView!
var videosNames = [String]()
var player  = AVPlayer()
var videoNode = SKVideoNode()

在 viewDidload 中,

In viewDidload,

sceneView.delegate = self

// Create a session configuration
    let configuration = ARImageTrackingConfiguration()

    // first see if there is a folder called "ARImages" Resource Group in our Assets Folder
    if let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "ARImages", bundle: Bundle.main) {

    // if there is, set the images to track
        configuration.trackingImages = trackedImages
        // at any point in time, only 1 image will be tracked
        configuration.maximumNumberOfTrackedImages = 1
    }

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

回调方法如下:

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

    // if the anchor is not of type ARImageAnchor (which means image is not detected), just return
    if let _ : Bool = videosNames.contains(anchor.name!) {

    guard let imageAnchor = anchor as? ARImageAnchor, var fileUrlString = Bundle.main.path(forResource:  "baby1", ofType: "mp4") else {return}

    print("didAdd node:\(anchor.name!)")
    //find our video file
    fileUrlString = "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" // i set the file URL path directly here


    let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileUrlString))

    self.player.seek(to: CMTime.zero)
    self.player.pause() // Tried to pause the video, set seek time zero. Nothing works. 
    self.videoNode.pause()

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


    //videoNode.removeAllChildren()
    self.player.play()
    //self.videoNode.play()
    // add observer when our player.currentItem finishes player, then start playing from the beginning
    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: nil) { (notification) in
        self.player.seek(to: CMTime.zero)
        self.player.play()
        //self.videoNode.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
    self.videoNode.position = CGPoint(x: videoScene.size.width / 2, y: videoScene.size.height / 2)
    // invert our video so it does not look upside down
    self.videoNode.yScale = -1.0
    // add the video to our scene
    videoScene.addChild(self.videoNode)
    // create a plan that has the same real world height and width as our detected image
    let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
    // set the first materials content to be our video scene
    plane.firstMaterial?.diffuse.contents = videoScene
    // create a node out of the plane
    let planeNode = SCNNode(geometry: plane)
    // since the created node will be vertical, rotate it along the x axis to have it be horizontal or parallel to our detected image
    planeNode.eulerAngles.x = -Float.pi / 2
    // finally add the plane node (which contains the video node) to the added node
    node.addChildNode(planeNode)

    }
}

当任何节点获得更新时

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

    if node.isHidden == true {
        print("Node is out of view:\(anchor.name!) :")
        self.player.seek(to: CMTime.zero)
        videoNode.pause()

    } else {
        print("Node is not out of view:\(anchor.name!)")
    }
}

在这里,当任何新视频开始播放时,我都会收到日志,但我无法停止之前开始播放的视频,这些视频在后台播放(仅音频)和新视频.它完全搞砸了我的过程.如果我将相机放在远离两个图像的地方,但声音会一直播放.任何人都可以帮我解决这个问题吗?

Here i get log when any new video start playing , but i could not stop previously started video which plays in background (only audio) with the new video. It totally messed up my process. If i put camera away from both image, but the sounds keeps playing. Could anyone please help me for the issue ?

提前致谢.

推荐答案

节点必须从 ARSCNView 的会话中删除.以下方法不会从会话中删除节点.

Node must be removed from ARSCNView's session. Following method does not removed the node from session.

node.removeFromParentNode() 

只有sceneView.session.remove() 在didUpdate() 方法中完美运行.

Only sceneView.session.remove() works perfectly in didUpdate() method.

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

    if node.isHidden == true {            
        if let imageAnchor = anchor as? ARImageAnchor {
            sceneView.session.remove(anchor: imageAnchor)
        }
    } else {
        if !isNodeAdded {
            isNodeAdded = true
        }
    }
}

这篇关于ARKIT:SKVideoNode 在节点不在场景中时继续播放,暂停不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆