ARKit 如何在没有跟踪时暂停视频

Posted

技术标签:

【中文标题】ARKit 如何在没有跟踪时暂停视频【英文标题】:ARKit How to Pause video when out of tracking 【发布时间】:2019-03-21 13:50:12 【问题描述】:

我正在使用 ARKit 将视频放在跟踪的图像上。

问题是当我不跟踪图像时,视频仍然在播放,声音也在播放。

当我不跟踪图像时,有什么方法可以暂停视频吗?

func setupVideoOnNode(_ node: SCNNode, fromURL url: URL)


    var videoPlayerNode: SKVideoNode!      
    let videoPlayer = AVPlayer(url: url)

    videoPlayerNode = SKVideoNode(avPlayer: videoPlayer)
    videoPlayerNode.yScale = -1       

    let spriteKitScene = SKScene(size: CGSize(width: 1000, height: 1000))
    spriteKitScene.scaleMode = .aspectFit
    videoPlayerNode.position = CGPoint(x: spriteKitScene.size.width/2, y: spriteKitScene.size.height/2)
    videoPlayerNode.size = spriteKitScene.size
    spriteKitScene.addChild(videoPlayerNode)

    node.geometry?.firstMaterial?.diffuse.contents = spriteKitScene

    videoPlayerNode.play()


我怎样才能实现它?

感谢您的帮助。

我在下面添加了当前代码。

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

    guard let imageAnchor = anchor as? ARImageAnchor else  return 

    let referenceImage = imageAnchor.referenceImage

    let width = CGFloat(referenceImage.physicalSize.width)
    let height = CGFloat(referenceImage.physicalSize.height)


    let videoHolder = SCNNode()
    let videoHolderGeometry = SCNPlane(width: width, height: height)
    videoHolder.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
    videoHolder.geometry = videoHolderGeometry


    if let videoURL = Bundle.main.url(forResource: "img.scnassets/route", withExtension: "MOV")
        setupVideoOnNode(videoHolder, fromURL: videoURL)
    


    node.addChildNode(videoHolder)

    videoHolder.name = "route"



var videoPlayerNode: SKVideoNode?
var videoPlayer: AVPlayer?


func setupVideoOnNode(_ node: SCNNode, fromURL url: URL)

    let videoPlayer = AVPlayer(url: url)

    videoPlayerNode = SKVideoNode(avPlayer: videoPlayer)
    videoPlayerNode?.yScale = -1


    let spriteKitScene = SKScene(size: CGSize(width: 1000, height: 1000))
    spriteKitScene.scaleMode = .aspectFit
    videoPlayerNode?.position = CGPoint(x: spriteKitScene.size.width/2, y: spriteKitScene.size.height/2)
    videoPlayerNode?.size = spriteKitScene.size
    spriteKitScene.addChild(videoPlayerNode!)


    node.geometry?.firstMaterial?.diffuse.contents = spriteKitScene


    videoPlayerNode?.play()
    videoPlayer.volume = 100

    videoPlayer.actionAtItemEnd = AVPlayer.ActionAtItemEnd.none;
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.stateEnd),
                                           name: NSNotification.Name("AVPlayerItemDidPlayToEndTimeNotification"),
                                           object: videoPlayer.currentItem)




@objc func stateEnd(notification: NSNotification) 
    let avPlayerItem = notification.object as? AVPlayerItem
    avPlayerItem?.seek(to: CMTime.zero)


func session(_ session: ARSession, didUpdate frame: ARFrame) 
    if !sceneView.isNode(videoPlayerNode, insideFrustumOf: sceneView!.pointOfView) 
        videoPlayerNode?.pause()
    

上述代码发生错误。

if !sceneView.isNode(videoPlayerNode, insideFrustumOf: sceneView!.pointOfView)

无法转换“SKVideoNode”类型的值?到预期的参数类型'SCNNode'

【问题讨论】:

您好,您对此有什么解决方案吗?我也卡在那里了。 你好,还没有。您是否尝试过以下答案? 【参考方案1】:

如果你符合ARSessionDelegate,你可以使用func session(ARSession, didUpdate: ARFrame) ,与isNode(_:insideFrustumOf:)一起检查视频节点是否在帧中,每帧,如果不是则暂停。

var videoPlayerNode: SKVideoNode?      
var videoPlayer: AVPlayer?

func setupVideoOnNode(_ node: SCNNode, fromURL url: URL)

    videoPlayer = AVPlayer(url: url)

    videoPlayerNode = SKVideoNode(avPlayer: videoPlayer)
    videoPlayerNode?.yScale = -1       

    let spriteKitScene = SKScene(size: CGSize(width: 1000, height: 1000))
    spriteKitScene.scaleMode = .aspectFit
    videoPlayerNode?.position = CGPoint(x: spriteKitScene.size.width/2, y: spriteKitScene.size.height/2)
    videoPlayerNode?.size = spriteKitScene.size
    spriteKitScene.addChild(videoPlayerNode!)

    node.geometry?.firstMaterial?.diffuse.contents = spriteKitScene

    videoPlayerNode?.play()



func session(_ session: ARSession, didUpdate frame: ARFrame) 
    if !sceneView.isNode(videoPlayerNode, insideFrustumOf: sceneView!.pointOfView) 
        videoPlayerNode?.pause()
    

【讨论】:

非常感谢您的评论!我正在努力充分利用您的建议,但是我无法解决下一行的问题。 if !sceneView.isNode(videoPlayerNode, insideFrustumOf: sceneView!.pointOfView) 无法转换类型“SKVideoNode?”的值到预期的参数类型 'SCNNode' 感谢您的帮助!【参考方案2】:

试试这个:

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

    // Pause the view's session
    sceneView.session.pause()

【讨论】:

以上是关于ARKit 如何在没有跟踪时暂停视频的主要内容,如果未能解决你的问题,请参考以下文章

如何在html中自动暂停视频?

用户不移动时如何自动暂停 GPS 跟踪器

应用程序暂停时如何在 iPhone 上获取屏幕锁定/解锁事件?

使用 jQuery 单击按钮时,如何暂停 YouTube 视频?

如何改善 ARKit 3.0 中的人物遮挡

如何在没有外部库的情况下在 React 中播放/暂停视频?