【问题标题】:ARKIT : SKVideoNode continue playing while node is out of scene, pause is not workingARKIT:SKVideoNode 在节点不在场景时继续播放,暂停不起作用
【发布时间】:2019-12-23 21:59:55
【问题描述】:

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

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

在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!)")
    }
}

当任何新视频开始播放时,我都会在此处获取日志,但我无法停止以前播放的新视频在后台(仅音频)播放的视频。它完全搞砸了我的过程。如果我将相机远离两个图像,但声音会继续播放。有人可以帮我解决这个问题吗?

提前致谢。

【问题讨论】:

  • 你可以直接添加AVPlayer作为漫反射内容不需要使用SKScene
  • @PrashantTukadiya,直接添加 AVPlayer 会为视频播放和自定义视图处理做一些额外的工作。我找到了解决方法并解决了问题。很高兴你。

标签: ios swift scenekit avaudioplayer arkit


【解决方案1】:

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

node.removeFromParentNode() 

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

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
        }
    }
}

【讨论】:

    【解决方案2】:

    sceneView.session.remove() 用于在 didUpdate() 方法中停止视频,但您还需要暂停播放器,否则音频仍将播放。这对我有用:

        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)
                    player.pause()
                }
            } else {
                player.play()
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多