本文介绍了为什么我的ARKit视频没有显示在应用程序视图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个ARKit
,可以识别两个不同的跟踪图像
I have an ARKit
that recognises two different tracking images
Vuforia和Tracker
Vuforia and Tracker
当我为每个跟踪器使用不同的.scn时,它会起作用,并且它会在两者之间跳来跳去.
It works when I have a different .scn for each tracker, and it hops between the two.
我正在尝试获取Tracker图片以覆盖视频播放器,
I am trying to get the Tracker image to overlay a video player,
我已经尝试了所有我能想到的,但是现在被卡住了.
I have tried everything I can think of but am now stuck.
我已经检查了所有文件名和链接,但认为我必须缺少某些东西才能启动视频播放器.
I have checked all the file names and links, but think I must be missing something to get the video player to fire up.
帮助!
import UIKit
import SceneKit
import ARKit
class ThirdViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
let exampleVideoPlayer: AVPlayer = {
//load example video from bundle
guard let url = Bundle.main.url(forResource: "homer video", withExtension: "mov", subdirectory: "AR.scnassets") else {
print("Could not find video file")
return AVPlayer()
}
return AVPlayer(url: url)
}()
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
public func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
if let imageAnchor = anchor as? ARImageAnchor {
// 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 = self.exampleVideoPlayer
self.exampleVideoPlayer.play()
} 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"
}
}
此处有完整的页面代码
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"
}
}
}
推荐答案
此代码已成功完成
// setup AV player & create SKVideoNode from avPlayer
let videoURL = URL(fileURLWithPath: Bundle.main.path(forResource: videoAssetName, ofType: videoAssetExtension)!)
let player = AVPlayer(url: videoURL)
player.actionAtItemEnd = .none
videoPlayerNode = SKVideoNode(avPlayer: player)
// setup player
let skSceneSize = orientation == .horizontal ? CGSize(width: 1280, height: 720) : CGSize(width: 406, height: 720)
let skScene = SKScene(size: skSceneSize)
skScene.addChild(videoPlayerNode)
videoPlayerNode.position = CGPoint(x: skScene.size.width/2, y: skScene.size.height/2)
videoPlayerNode.size = skScene.size
let scnPlaneSize : [String : CGFloat] = orientation == .horizontal ? ["width": 0.9, "height": 0.5063] : ["width": 0.5063, "height": 0.9]
let videoPlane = SCNPlane(width: scnPlaneSize["width"]!, height: scnPlaneSize["height"]!)
videoPlane.firstMaterial?.diffuse.contents = skScene
videoPlane.firstMaterial?.isDoubleSided = true
let videoPlaneNode = SCNNode(geometry: videoPlane)
node.addChildNode(videoPlaneNode)
// setup node to auto remove itself upon completion
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil, using: { (_) in
DispatchQueue.main.async {
if self.debug { NSLog("video completed") }
// do something when the video ends
}
})
// play the video node
videoPlayerNode.play()
这篇关于为什么我的ARKit视频没有显示在应用程序视图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!