我的AVPlayer本地路径视频出现字符串错误

时间:2019-06-06 11:30:12

标签: ios swift string xcode avplayer

我在AVPlayer的本地视频文件中出现字符串错误

videoItem的底行用

标记
  

可选类型'String?'的值必须解包为type的值   “字符串”

真的很感谢您的帮助!

当我禁用页面代码的某些位时,我可以获取其中一个跟踪图像以识别出正常,但是我无法使它们都在同一版本中被识别。

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 :(得分:0)

编译器错误

  

可选类型'String?'的值必须解包为type的值   “字符串”

原因:

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 nilrenderer(_:, 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.....
}

编辑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.............
}