当不再捕获检测到的图像时停止播放视频

Stop playing video when detected image is not captured anymore

我正在创建一个 AR 应用来检测立方体上的图像(立方体上印有 6 张图像)。根据检测到的图像,正在播放相关视频。不幸的是,即使识别出另一张图片,AVplayer 也不会停止播放视频 --> 可能会同时播放多个视频(对视频来说不是很糟糕,但尤其是重叠的音频太可怕了)。

我的假设是以下函数实际上会停止当前播放的视频,但什么也没有发生 --> 即使摄像机不再捕获立方体,音频也会继续。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let configuration = ARImageTrackingConfiguration()

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

        configuration.trackingImages = trackedImages
        configuration.maximumNumberOfTrackedImages = 6
    }

    sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    sceneView.session.pause()
    //sceneView?.removeFromSuperview()
}

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

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

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

    let player = AVPlayer(playerItem: videoItem)
    let videoNode = SKVideoNode(avPlayer: player)

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

    }

    let videoScene = SKScene(size: CGSize(width: 960, height: 720))
    videoNode.position = CGPoint(x: videoScene.size.width / 2, y: videoScene.size.height / 2)
    videoNode.yScale = -1.0
    videoScene.addChild(videoNode)
    let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
    plane.firstMaterial?.diffuse.contents = videoScene
    let planeNode = SCNNode(geometry: plane)
    planeNode.eulerAngles.x = -Float.pi / 2
    node.addChildNode(planeNode)
}

有没有人知道如何调用 "player.pause()" 或 "player.stop()" 函数在不再检测到捕获的图像时停止播放视频?

感谢您的支持!

抱歉,我没有用音频检查过这个(我的设备不知何故停止播放音频)。您有不同的 AVPlayer 实例为不同的图像节点播放视频。所以我只是把它们拿出来,这样同一个播放器就会有不同节点的新视频

var player = AVPlayer()
var videoScene: SKScene!
var videoNode: SKVideoNode!
var url: String!

func setupVideoNode(){
    videoNode = SKVideoNode(avPlayer: player)

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

    }
    videoScene = SKScene(size: CGSize(width: 960, height: 720))
    videoNode.position = CGPoint(x: videoScene.size.width / 2, y: videoScene.size.height / 2)
    videoNode.yScale = -1.0
    videoScene.addChild(videoNode)
}

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

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

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

    player.replaceCurrentItem(with: videoItem) //= AVPlayer(playerItem: videoItem)

    setupVideoNode()

    let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
    plane.firstMaterial?.diffuse.contents = videoScene
    let planeNode = SCNNode(geometry: plane)
    planeNode.eulerAngles.x = -Float.pi / 2
    node.addChildNode(planeNode)
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let imageAnchor = anchor as? ARImageAnchor,
        let name = imageAnchor.referenceImage.name,
        let fileUrlString = Bundle.main.path(forResource: name, ofType: "mp4") else {return}

    if url == fileUrlString{
        return
    }
    url = fileUrlString
    let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileUrlString))
    player.replaceCurrentItem(with: videoItem)
    player.play()
}