Swift ARKit:不在视图中时停止AVPlayer音频

Swift ARKit:不在视图中时停止AVPlayer音频,swift,xcode,scenekit,avplayer,arkit,Swift,Xcode,Scenekit,Avplayer,Arkit,我正在开发一款ARKit图像跟踪应用程序,它将AVPlayer视频覆盖在图像目标(Swift5和XCode 13)上。目前,我已经将其设置为仅同时跟踪1个图像,但在我的AR参考组中有多个图像目标,具有独特的视频 除了一个问题外,所有这些都可以正常工作——即使AR摄像机不再跟踪和渲染视频,每个视频的音频也会继续播放。如果用户导航到应用程序中的其他视图控制器,音频甚至会继续播放 当AVPlayer音频的图像目标不再被跟踪时,如何停止该音频? 有很多代码,我不确定需要什么来帮助解决问题(最初不包括所有

我正在开发一款ARKit图像跟踪应用程序,它将AVPlayer视频覆盖在图像目标(Swift5和XCode 13)上。目前,我已经将其设置为仅同时跟踪1个图像,但在我的AR参考组中有多个图像目标,具有独特的视频

除了一个问题外,所有这些都可以正常工作——即使AR摄像机不再跟踪和渲染视频,每个视频的音频也会继续播放。如果用户导航到应用程序中的其他视图控制器,音频甚至会继续播放

当AVPlayer音频的图像目标不再被跟踪时,如何停止该音频?

有很多代码,我不确定需要什么来帮助解决问题(最初不包括所有内容),请告诉我其他信息是否有用

使用AVPlayer作为材质设置平面

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

    let node = SCNNode()


    if let imageAnchor = anchor as? ARImageAnchor {

        let size = imageAnchor.referenceImage.physicalSize


        let videoUrl = Bundle.main.url(forResource: "Nine", withExtension: "mp4")!
        let videoPlayer = AVPlayer(url: videoUrl)
        videoPlayer.play()
        let plane = SCNPlane(width: size.width, height: size.height)
        plane.firstMaterial?.diffuse.contents = videoPlayer
        let planeNode = SCNNode(geometry: plane)
        planeNode.eulerAngles.x = -.pi / 2
    }

    node.addChildNode(planeNode)
}

return node
谢谢你的帮助

  • 存储
    视频播放器

    var videoPlayer: AVPlayer?    
    
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
      let node = SCNNode()
      if let imageAnchor = anchor as? ARImageAnchor {
      ...
      let videoUrl = Bundle.main.url(forResource: "Nine", withExtension: "mp4")!
      let videoPlayer = AVPlayer(url: videoUrl)
      videoPlayer.play()
      self.videoPlayer = videoPlayer 
      ...
      }
    }
    
  • 检查当前帧是否有任何图像定位,如果没有,请暂停视频

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
      if frame.anchors.filter({$0 is ARImageAnchor}).count == 0 {
        videoPlayer?.pause()
      }
    }
    

  • 当不再跟踪主播时,有一种更简单的方法来停止视频和音频。您需要使用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()
            }
        }
    
    
    当锚不在视线范围内时,您还需要暂停播放机,否则音频将继续播放