【问题标题】:ARKit – How to implement SCNRenderer().audioListener?ARKit – 如何实现 SCNRenderer().audioListener?
【发布时间】:2021-05-17 09:14:49
【问题描述】:

我正在尝试在我的应用程序中实现这个新的位置音频。

我用一个 tapGesture 在我的场景中插入一个 Drone,然后我将 sound.mp3 附加到它上面

    func tapToPlace(node: SCNNode, recognizer: UITapGestureRecognizer, view : ARSCNView){
        debugPrint("tap")
        if gameState == .placeObject {
                DispatchQueue.global().async {
                    let tapedScreen = recognizer.location(in: view)
                    guard let query = view.raycastQuery(from: tapedScreen, allowing: .existingPlaneGeometry, alignment: .horizontal) else {return}
                    let result = view.session.raycast(query).first
                    
                    guard let worldTransform = result?.worldTransform else {return}// simd_Float4x4
                    let newNode = node.clone() // duplicate the node create at app start up
                    newNode.position = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z) // place it at position tapped
                    
                    // set up position audio
                    let audio = SCNAudioSource(fileNamed: "sound.mp3")! // add audio file
                    audio.loops = true
                    audio.volume = 0.3
                    audio.rate = 0.1
                    audio.isPositional = true
                    audio.shouldStream = false
                    audio.load()
                    let player = SCNAudioPlayer(source: audio)
                    newNode.addAudioPlayer(player)
                    
                    view.scene.rootNode.addChildNode(newNode)
                    
                }
            
        }
    }

阅读苹果文档看起来需要实现这个audioListner: SCNnode

我该怎么做?

我尝试了以下方法:

我得到了相机的当前位置。

func trackCameraLocation(arView: ARSCNView) -> simd_float4x4 {
            var cameraloc : simd_float4x4!
            if let camera = arView.session.currentFrame?.camera.transform {
                cameraloc = camera
            }
            return cameraloc
        }

我用这个里面的方法做update frame,为了得到准确的用户位置。

func session(_ session: ARSession, didUpdate frame: ARFrame) {
            cameraLocation = trackCameraLocation(arView: sceneView)
        }

一旦我有了相机位置,在方法 didAdd 节点内我尝试设置 audioListner..

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
            let cameraNode = SCNNode()
            cameraNode.position = SCNVector3(cameraLocation.columns.3.x, cameraLocation.columns.3.y, cameraLocation.columns.3.z)
            
            renderer.audioListener = cameraNode
        }

但是.. 没有任何效果.. 听不到任何声音.. 我只看到我的无人机在我家的地板上保持沉默。

寻求一些帮助或解释如何实现这个新的 ARKit 未来。

提前感谢您的帮助。

我放音频文件的地方:

【问题讨论】:

    标签: swift audio augmented-reality scenekit arkit


    【解决方案1】:

    试试这个解决方案。它适用于 VR 应用和 AR 应用。

    import SceneKit
    
    extension ViewController: SCNSceneRendererDelegate {
    
        func renderer(_ renderer: SCNSceneRenderer, 
               updateAtTime time: TimeInterval) {
    
            listener.position.z = -20  // change listener's position here
            renderer.audioListener = self.listener
        }
    }
    

    ...

    class ViewController: UIViewController {
        
        let scene = SCNScene()
        let audioNode = SCNNode()
        let listener = SCNNode()
    
        override func viewDidLoad() {
            super.viewDidLoad()    
            let sceneView = self.view as! SCNView
            sceneView.scene = self.scene
            sceneView.backgroundColor = .black
            sceneView.delegate = self
            
            let node = SCNNode()
            node.geometry = SCNSphere(radius: 0.05)
            node.position = SCNVector3(0,0,-2)
            self.scene.rootNode.addChildNode(node)
            
            let path = Bundle.main.path(forResource: "art.scnassets/audio",
                                             ofType: "mp3")      // MONO AUDIO
            let url = URL(fileURLWithPath: path!)
            let source = SCNAudioSource(url: url)!
            source.isPositional = true
            source.shouldStream = false
            source.load()
            let player = SCNAudioPlayer(source: source)                 
            node.addChildNode(audioNode)
            
            // THE LOCATION OF THIS LINE IS IMPORTANT
            audioNode.addAudioPlayer(player)
            audioNode.addChildNode(self.listener)
        }
    }
    

    【讨论】:

    • 我已经尝试了你的代码,我终于可以听一些音频了,现在的问题是音量不会像我假设的那样改变,如果我靠近源,我已经尝试改变listener.position.z 的位置,从 0 到 -200 声音没有变化...
    • 哦,我只是注意到现在代码正在运行,这取决于我正在使用的音频文件..(抱歉不是专家)它必须是 MONO 文件 .WAV,不能做一个简单的mp3音乐文件
    • 我写过它必须是 cmets 中的单声道。很高兴你得到了你想要的。))
    猜你喜欢
    • 2019-02-01
    • 2017-05-14
    • 1970-01-01
    • 2020-02-17
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2019-11-05
    相关资源
    最近更新 更多