Использование YoutubePlayerView на ARKit - PullRequest
1 голос
/ 27 сентября 2019

Я работаю над приложением ARKit, в котором я обнаруживаю поверхность плана и добавляю видео YouTube, используя YoutubePlayerView pod на поверхности.Мне удалось обнаружить поверхность и добавить YouTubePlayerView.

Звук из видео на YouTube воспроизводится, но видео не отображается.

Может кто-нибудь сталкивался с таким же раньше.

Ниже приведен мой код.

    import UIKit
    import SceneKit
    import ARKit
    import YoutubePlayerView
     
    class ViewController: UIViewController, ARSCNViewDelegate {
     
    @IBOutlet var sceneView: ARSCNView!
    let videoPlayerNode = SCNNode()
     
        override func viewDidLoad() {
            super.viewDidLoad()
            // Set the view's delegate
            sceneView.delegate = self
     
            // Show statistics such as fps and timing information
            sceneView.showsStatistics = true
        }
     
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
     
            // Create a session configuration
            let configuration = ARWorldTrackingConfiguration()
     
            // Enable horizontal plane detection
            configuration.planeDetection = .horizontal
     
            // show Feature Points
            sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
     
            // Run the view's session
            sceneView.session.run(configuration)
        }
     
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
     
            // Pause the view's session
            sceneView.session.pause()
        }
     
        func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
     
            if let planeAnchor = anchor as? ARPlaneAnchor {
     
            let videoPlayerGeometry = SCNPlane(width: CGFloat(planeAnchor.extent.x), height: CGFloat(planeAnchor.extent.z))
     
            DispatchQueue.main.async {
                let playerView = YoutubePlayerView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
                let playerVars: [String: Any] = [
                                    "controls": 1,
                                    "modestbranding": 1,
                                    "playsinline": 1,
                                    "autoplay": 1,
                                    "origin": "https://youtube.com"
                ]
                playerView.delegate = self
                playerView.loadWithVideoId("w277oTvoKAM", with: playerVars) // CdXesX6mYUE

                videoPlayerGeometry.firstMaterial?.diffuse.contents = playerView
                self.videoPlayerNode.geometry = videoPlayerGeometry
                self.videoPlayerNode.eulerAngles.x = -.pi / 2
                node.addChildNode(self.videoPlayerNode)
                }
            }
        }
    }
     
     
    extension ViewController: YoutubePlayerViewDelegate {
        func playerViewDidBecomeReady(_ playerView: YoutubePlayerView) {
            print("Ready")
            playerView.fetchPlayerState { (state) in
            print("Fetch Player State: \(state)")
        }
     
        func playerView(_ playerView: YoutubePlayerView, didChangedToState state: YoutubePlayerState) {
            print("Changed to state: \(state)")
        }
     
        func playerView(_ playerView: YoutubePlayerView, didChangeToQuality quality: YoutubePlaybackQuality) {
            print("Changed to quality: \(quality)")
        }
     
        func playerView(_ playerView: YoutubePlayerView, receivedError error: Error) {
            print("Error: \(error)")
        }
     
        func playerView(_ playerView: YoutubePlayerView, didPlayTime time: Float) {
            print("Play time: \(time)")
        }
     
        func playerViewPreferredInitialLoadingView(_ playerView: YoutubePlayerView) -> UIView? {
            let view = UIView()
            view.backgroundColor = .red
            return view
        }
    }

enter image description here

Спасибо!

1 Ответ

0 голосов
/ 27 сентября 2019

Основная проблема заключается в использовании UIView вместо использования сцены SpriteKit или AVPlayer:

videoPlayerGeometry.firstMaterial?.diffuse.contents = skScene

или:

videoPlayerGeometry.firstMaterial?.diffuse.contents = avPlayer

Вот возможные кандидаты для .contents свойства экземпляра:

  • NSColor / UIColor / CGColor
  • NSNumber
  • NSImage / UIImage / CGImage
  • NSString или NSURL объект в AVPlayer
  • CALayer
  • SKTexture / MDLTexture / MTLTexture
  • Сцена SpriteKit
  • Карта кубов со специально отформатированным массивом из шести изображений

Вы также пропустили /watch?v= на вашем веб-адресе:

let playerVars: [String: Any] = [ "controls" : 1,
                                  "modestbranding" : 1,
                                  "playsinline" : 1,
                                  "autoplay" : 1,
                                  "origin" : "https://www.youtube.com/embed/"
                                ]

playerView.loadWithVideoId("w277oTvoKAM", with: playerVars)

Если это не сработает, попробуйте https://www.youtube.com/embed/w277oTvoKAM.

Также объявите свойplayerView недвижимость по всему миру.И поместите playerView.delegate внутрь viewDidLoad() метод:

override func viewDidLoad() {
    super.viewDidLoad()

    sceneView.delegate = self
    playerView.delegate = self   // a delegate for using playerView() methods
}

PS

Обычный подход к игре videos as a textures в приложении ARKit, не работает сYouTube видео.Но если вам интересен этот подход, я пишу его здесь (чтобы узнать, как подать текстуру):

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

    if let planeAnchor = anchor as? ARPlaneAnchor {

        let playerGeo = SCNPlane(width: CGFloat(planeAnchor.extent.x),
                                height: CGFloat(planeAnchor.extent.z))

        DispatchQueue.main.async {

            // here's how your video would be in a full screen mode
            // let videoURL = URL(string: "https://www.youtube.com/embed/w277oTvoKAM")

            let videoURL = URL(fileURLWithPath: "Assets/video.mp4")

            let videoNode = SKVideoNode(url: videoURL!)

            let skScene = SKScene(size:
                          CGSize(width: playerGeo.width * 1280,
                                height: playerGeo.height * 720))

            videoNode.position = CGPoint(
                                     x: skScene.size.width / 2,
                                     y: skScene.size.height / 2)

            videoNode.size = skScene.size

            skScene.addChild(videoNode)
            playerGeo.firstMaterial?.diffuse.contents = skScene
            videoNode.play()

            let playerNode = SCNNode()
            playerNode.geometry = playerGeo
            playerNode.eulerAngles.x = -.pi / 2
            node.addChildNode(playerNode)
        }
    }
}

Видео YouTube воспроизводятся в формате WKWebView, но это 2D.Заставить его работать с трехмерной геометрией - сложная задача.

...