У меня есть строковая ошибка для видео локального пути для AVPlayer - PullRequest
0 голосов
/ 06 июня 2019

У меня ошибка строки с локальным видеофайлом для AVPlayer

В нижней строке videoItem отображается значение

Значение необязательного типа 'String?'должно быть развернуто до значения типа 'String'

Очень хотелось бы получить некоторую помощь по этому вопросу!

когда я отключаю определенные биты кода страницы, я могу получить один изотслеживание изображений для распознавания нормально, но я не могу заставить их распознаваться в одной сборке.

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

        let node = SCNNode()



       if let imageAnchor = anchor as? ARImageAnchor {


            let fileString = Bundle.main.path(forResource: "black", ofType: "mp4")

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

полный код здесь

import UIKit
import SceneKit
import ARKit



class ThirdViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    var FreemensNode: SCNNode?
    var VideoNode: SCNNode?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self
        sceneView.autoenablesDefaultLighting = true


        let FreemensScene = SCNScene(named: "ar.scnassets/Freemens.scn")
        let VideoScene = SCNScene(named: "ar.scnassets/Video.scn")
        FreemensNode = FreemensScene?.rootNode
        VideoNode = VideoScene?.rootNode




    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARImageTrackingConfiguration()


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

        configuration.trackingImages = trackingImages
        configuration.maximumNumberOfTrackedImages = 2

        }

        // Run the view's session
        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()



       if let imageAnchor = anchor as? ARImageAnchor {


        if let fileString = Bundle.main.path(forResource: "black", ofType: "mp4") {
            let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileString))


            let player = AVPlayer(playerItem: videoItem)
            //initialize video node with avplayer
            let videoNode = SKVideoNode(avPlayer: player)

            player.play()
            // add observer when our player.currentItem finishes player, then start playing from the beginning
            NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil) { (notification) in
                player.seek(to: CMTime.zero)
                player.play()
                print("Looping Video")
            }

            // set the size (just a rough one will do)
            let videoScene = SKScene(size: CGSize(width: 480, height: 360))
            // center our video to the size of our video scene
            videoNode.position = CGPoint(x: videoScene.size.width / 2, y: videoScene.size.height / 2)
            // invert our video so it does not look upside down
            videoNode.yScale = -1.0
            // add the video to our scene
            videoScene.addChild(videoNode)


            // Create a plane
            let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)
            if imageAnchor.referenceImage.name == "Tracker" {
                // Set AVPlayer as the plane's texture and play
            plane.firstMaterial?.diffuse.contents = videoScene

            } else if imageAnchor.referenceImage.name == "Vuforia" {
               plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.0)


            let planeNode = SCNNode(geometry: plane)
            planeNode.eulerAngles.x = -.pi / 2
            node.addChildNode(planeNode)

            }

            var shapeNode: SCNNode?
            switch imageAnchor.referenceImage.name {
            case ArItem.Freemens.rawValue :
                shapeNode = FreemensNode

            case ArItem.Video.rawValue :
                shapeNode = VideoNode
            default:
                break

            }



            if imageAnchor.referenceImage.name == "Vuforia" {
                 shapeNode = FreemensNode


            } else if imageAnchor.referenceImage.name == "Tracker"{
                shapeNode = VideoNode



            }

            guard let shape = shapeNode else { return nil}
            node.addChildNode(shape)
        }

        return node

    }

    enum ArItem : String {
        case Freemens = "Freemens"
        case Video = "Video"
    }

}


}

1 Ответ

0 голосов
/ 06 июня 2019

Ошибка компилятора,

Значение необязательного типа 'String?'должен быть развернут в значение типа 'String'

Причина:

path(forResource:ofType:) возвращает String?.Следовательно, fileString имеет тип String?.

Решение:

Итак, вам нужно unwrap, прежде чем использовать его в AVPlayerItem(url:) как,

if let fileString = Bundle.main.path(forResource: "black", ofType: "mp4") {
    let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileString))
}

Редактировать:

Вам необходимо return node или nil из renderer(_:, nodeFor:) метода.

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let node = SCNNode()
    if let imageAnchor = anchor as? ARImageAnchor {            
        if let fileString = Bundle.main.path(forResource: "black", ofType: "mp4") {
            let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileString))
        }
        return node
    }
    .
    .
    .
    return nil //here.....
}

Edit-2:

В своем коде добавьте оператор return nil после созданного вами enum, то есть

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    //Your code here...
    enum ArItem : String {
        case Freemens = "Freemens"
        case Video = "Video"
    }
    return nil //Here.............
}
...