ios - AVFoundation视频播放问题

标签 ios xcode avfoundation arkit

我已经关注了this excellent tutorial来自尤马并有一些工作。下面是我在 View Controller 中使用的代码

import UIKit
import SceneKit
import ARKit
import AVFoundation
import SpriteKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

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

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true

        // Create a new scene
        let scene = SCNScene(named: "art.scnassets/notebook.scn")!

        // Set the scene to the view
        sceneView.scene = scene
    }

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

        // Create a session configuration
        let configuration = ARImageTrackingConfiguration()

        guard let arImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { return }
        configuration.trackingImages = arImages
        // 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) {
        guard anchor is ARImageAnchor else { return }

        // Amy Image recognition
        guard let amyContainer = sceneView.scene.rootNode.childNode(withName: "amy", recursively: false) else { return }
        amyContainer.removeFromParentNode()
        node.addChildNode(amyContainer)
        amyContainer.isHidden = false

        // Video
        let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4")!

        let videoPlayer = AVPlayer(url: videoURL)

        let videoScene = SKScene(size: CGSize(width: 900.0, height: 1400.0))

        let videoNode = SKVideoNode(avPlayer: videoPlayer)

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

        videoNode.size = videoScene.size

        videoNode.yScale = -1

        videoNode.play()

        videoScene.addChild(videoNode)

        guard let video = amyContainer.childNode(withName: "video", recursively: true)
        else { return }
    video.geometry?.firstMaterial?.diffuse.contents = videoScene

 }
 }

当我使用作为教程的一部分提供的视频时,一切都运行良好,但是当我尝试包含我创建的视频时,我只在目标图像上看到一个白框,但没有视频。

我已经检查了三次名称,我尝试导出具有完全相同尺寸的视频,但没有成功。我已经测试过上传视频的新版本,该版本确实可以作为不同的文件名使用,并且更改了名称并且可以正常工作,因此我必须假设问题出在我正在生成的 .mp4 上。

对于这种方法,mp4 是否需要特定的规则/设置,premiere pro 或 Handbrake 中是否有我可以使用的设置?或者我如何调试 Xcode 本身发生的任何内部错误?

最佳答案

可能是因为您的视频尺寸太大。在尝试播放视频之前,您需要先等待 AVPlayer 准备就绪

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    var observer: NSKeyValueObservation?
    var videoNode: SKVideoNode?

    override func viewDidLoad() {
        super.viewDidLoad()

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

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true

        // Create a new scene
        let scene = SCNScene(named: "art.scnassets/notebook.scn")!

        // Set the scene to the view
        sceneView.scene = scene
    }

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

        // Create a session configuration
        let configuration = ARImageTrackingConfiguration()

        guard let arImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { return }
        configuration.trackingImages = arImages
        // 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) {
        guard anchor is ARImageAnchor else { return }

        // Amy Image recognition
        guard let amyContainer = sceneView.scene.rootNode.childNode(withName: "amy", recursively: false) else { return }
        amyContainer.removeFromParentNode()
        node.addChildNode(amyContainer)
        amyContainer.isHidden = false

        let videoPlayer = self.createAVPlayer()

        let videoScene = SKScene(size: CGSize(width: 900.0, height: 1400.0))

        self.videoNode = SKVideoNode(avPlayer: videoPlayer)

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

        self.videoNode?.size = videoScene.size

        self.videoNode?.yScale = -1

        videoScene.addChild(self.videoNode!)

        guard let video = amyContainer.childNode(withName: "video", recursively: true)
            else { return }
        video.geometry?.firstMaterial?.diffuse.contents = videoScene

    }

    func createAVPlayer() -> AVPlayer {
        let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4")!
        let asset = AVAsset(url: videoURL)

        let assetKeys = [
            "playable",
            "hasProtectedContent"
        ]
        let playerItem = AVPlayerItem(asset: asset,
                                      automaticallyLoadedAssetKeys: assetKeys)

        self.observer = playerItem.observe(\.status, options:  [.new, .old], changeHandler: { (playerItem, change) in
            if playerItem.status == .readyToPlay {

                self.videoNode?.play() // Only play when Its ready
            }
        })

        return AVPlayer(playerItem: playerItem)
    }
}

关于ios - AVFoundation视频播放问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55301481/

相关文章:

objective-c - 关闭 Assets 目录编译器警告

swift - 从 Xcode 9 上传到应用商店/iTunes 连接的问题

iphone - AVPlayer 缓冲、暂停通知和海报帧

ios - Swift 视频缩放器 AVAsset

ios - 如何删除使用交互式键盘时出现的关于 resignFirstResponder 的警告?

ios - 在哪里快速设置委托(delegate)?

ios - 无法让 SearchController 与 TableView 一起显示

ios - 来自主机应用程序的 Swift 数据到今天的小部件

iOS 应用商店提交错误

objective-c - AVFoundation 的 AVAssetWriterInput expectsMediaDataInRealTime 属性究竟做了什么?