0

私は ARKit をいじっており、ビデオ コンテンツを認識された画像にオーバーレイするアプリを作成しました。コードは次のとおりです。

import UIKit
import SceneKit
import ARKit
import SpriteKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

        sceneView.delegate = self

    }

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

        let configuration = ARImageTrackingConfiguration()

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

            configuration.trackingImages = imageToTrack

            configuration.maximumNumberOfTrackedImages = 3

            print("Images successfully added")

        }

        sceneView.session.run(configuration)
    }

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

        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate

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

        var videoNode = SKVideoNode()

        var videoScene = SKScene()

        if let imageAnchor = anchor as? ARImageAnchor {


            videoNode = SKVideoNode(fileNamed: "video1.mp4")

            videoNode.play()

            videoScene = SKScene(size: CGSize(width: 640, height: 360))

            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 = -.pi/2

            node.addChildNode(planeNode)

        }
        return node
    }
}

これは完全に機能します...一度!しかし、問題は、ビデオの再生が終了すると、SKVideoNode を介して使用できるコントロールが限られているため、ビデオを自動的に再開する方法がわからないことです。理想的には、これらはループで再生する必要があります。

いくつかの調査を行ったところ、AVPlayer オブジェクトを使用してビデオ ノードを初期化するのが最善の方法のようです。

だから、私はこれをやろうとしましたが、うまくいきません。

クラスに var player = AVPlayer() を追加し、次のように videoNode を初期化しようとしました。

var videoNode: SKVideoNode? = {
    guard let urlString = Bundle.main.path(forResource: "video1", ofType: "mov") else {
        return nil
    }

    let url = URL(fileURLWithPath: urlString)
    let item = AVPlayerItem(url: url)
    let player = AVPlayer(playerItem: item)

    return SKVideoNode(avPlayer: player)
}()

次に、ユーザー player.play() を試みましたが、ビデオが再生されません。代わりに、飛行機が画像の上に空白の長方形として表示されます。

これを正常に初期化したら、オブザーバーを追加して、ビデオのプレーヤーがいつ終了したかを確認して再起動できると思いますが、その時点に到達するのに苦労しています。

4

1 に答える 1