如何在iOS设备上播放360度视频

16

在查看不同网站和分析不同资源后,我发现要在iPhone上播放360视频,应该使用第三方库(Panorama)。但是我真的很想知道如何自己实现它,因为标准iOS元素不支持这种功能。

请提供一些建议,指导我应该使用哪些方法来创建自己的360视频播放器。


1
我只是询问方向,应该在哪里进行调查。 - Oleg Gordiichuk
请忽略我之前的评论。我误读了你的帖子。你想自己做。 - Kirs Kringle
嗨,Oleg,你找到好的解决方案了吗?有免费的SDK吗?还是你自己做了(辛苦工作)? - jlmg5564
4个回答

13

您可以使用Scenekit来完成此操作,无需任何外部库或依赖项。

创建一个SCNScene,并将相机映射到设备的移动。相机有一定的偏移量,以映射每个眼睛并创建3D立体效果。

override func viewDidLoad() {
    super.viewDidLoad()
    leftSceneView?.backgroundColor = UIColor.blackColor()
    rightSceneView?.backgroundColor = UIColor.whiteColor()

    // Create Scene
    scene = SCNScene()
    leftSceneView?.scene = scene
    rightSceneView?.scene = scene

    // Create cameras
    let camX = 0.0 as Float
    let camY = 0.0 as Float
    let camZ = 0.0 as Float
    let zFar = 50.0

    let leftCamera = SCNCamera()
    let rightCamera = SCNCamera()

    leftCamera.zFar = zFar
    rightCamera.zFar = zFar

    let leftCameraNode = SCNNode()
    leftCameraNode.camera = leftCamera
    leftCameraNode.position = SCNVector3(x: camX - 0.5, y: camY, z: camZ)

    let rightCameraNode = SCNNode()
    rightCameraNode.camera = rightCamera
    rightCameraNode.position = SCNVector3(x: camX + 0.5, y: camY, z: camZ)

    camerasNode = SCNNode()
    camerasNode!.position = SCNVector3(x: camX, y:camY, z:camZ)
    camerasNode!.addChildNode(leftCameraNode)
    camerasNode!.addChildNode(rightCameraNode)

    camerasNode!.eulerAngles = SCNVector3Make(degreesToRadians(-90.0), 0, 0)

    cameraRollNode = SCNNode()
    cameraRollNode!.addChildNode(camerasNode!)

    cameraPitchNode = SCNNode()
    cameraPitchNode!.addChildNode(cameraRollNode!)

    cameraYawNode = SCNNode()
    cameraYawNode!.addChildNode(cameraPitchNode!)

    scene!.rootNode.addChildNode(cameraYawNode!)

    leftSceneView?.pointOfView = leftCameraNode
    rightSceneView?.pointOfView = rightCameraNode

    // Respond to user head movement. Refreshes the position of the camera 60 times per second.
    motionManager = CMMotionManager()
    motionManager?.deviceMotionUpdateInterval = 1.0 / 60.0
    motionManager?.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrame.XArbitraryZVertical)

    leftSceneView?.delegate = self

    leftSceneView?.playing = true
    rightSceneView?.playing = true        
}

在sceneRenderer中更新相机位置:

func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval){

    // Render the scene
    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        if let mm = self.motionManager, let motion = mm.deviceMotion {
            let currentAttitude = motion.attitude

            var orientationMultiplier = 1.0
            if(UIApplication.sharedApplication().statusBarOrientation == UIInterfaceOrientation.LandscapeRight){ orientationMultiplier = -1.0}

            self.cameraRollNode!.eulerAngles.x = Float(currentAttitude.roll * orientationMultiplier)
            self.cameraPitchNode!.eulerAngles.z = Float(currentAttitude.pitch)
            self.cameraYawNode!.eulerAngles.y = Float(currentAttitude.yaw)

        }
    }
}

这里是用于添加显示AVPlayer的SCNSphere的代码。

func play(){

    //let fileURL: NSURL? = NSURL(string: "http://www.kolor.com/360-videos-files/noa-neal-graffiti-360-music-video-full-hd.mp4")
    let fileURL: NSURL? = NSURL.fileURLWithPath(NSBundle.mainBundle().pathForResource("vr", ofType: "mp4")!)

    if (fileURL != nil){
        videoSpriteKitNode =  SKVideoNode(AVPlayer: AVPlayer(URL: fileURL!))
        videoNode = SCNNode()
        videoNode!.geometry = SCNSphere(radius: 30)

        let spriteKitScene = SKScene(size: CGSize(width: 2500, height: 2500))
        spriteKitScene.scaleMode = .AspectFit

        videoSpriteKitNode!.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
        videoSpriteKitNode!.size = spriteKitScene.size

        spriteKitScene.addChild(videoSpriteKitNode!)

        videoNode!.geometry?.firstMaterial?.diffuse.contents = spriteKitScene
        videoNode!.geometry?.firstMaterial?.doubleSided = true

        // Flip video upside down, so that it's shown in the right position
        var transform = SCNMatrix4MakeRotation(Float(M_PI), 0.0, 0.0, 1.0)
        transform = SCNMatrix4Translate(transform, 1.0, 1.0, 0.0)

        videoNode!.pivot = SCNMatrix4MakeRotation(Float(M_PI_2), 0.0, -1.0, 0.0)
        videoNode!.geometry?.firstMaterial?.diffuse.contentsTransform = transform
        videoNode!.position = SCNVector3(x: 0, y: 0, z: 0)

        scene!.rootNode.addChildNode(videoNode!)
        videoSpriteKitNode!.play()

        playingVideo = true   
    }
}

我在GitHub上创建了一个项目,以展示如何使用明确的说明:

此项目也适用于VR,使用谷歌纸板。

https://github.com/Aralekk/simple360player_iOS


虽然这个链接可能回答了问题,但最好在这里包含答案的关键部分,并提供链接作为参考。仅有链接的答案如果链接页面发生变化,就会失效。- 来自审核 - skypjack
完成!学习Stackoverflow仍在进行中。 - Arthuraw

3
除了Aralekk的存储库外,我发现在创建自己的视频360°播放器时hanton的存储库非常有用。 这里是我的存储库链接,这里是相关博客文章。

2
你可以使用这个框架来实现360度播放器 pod 'NYT360Video',在Objective C和Swift中都适用。对于Objective C,提供了默认示例;对于Swift,请使用相同的框架。
/// 用于360度视图
 // just import the frame work 
 import NYT360Video    

 // declare the nyt360VC global fro the view controller 
 var nyt360VC: NYT360ViewController!

/// Player implementation
let videoURL = Bundle.main.url(forResource: "360Video", withExtension: "mp4")!
let player = AVPlayer(url: videoURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()

/// 360 Degree VC implementation along with manager 
let manager: NYT360MotionManagement = NYT360MotionManager.shared()
self.nyt360VC = NYT360ViewController.init(avPlayer: player2,
                                          motionManager: manager)

// Adding the 360 degree view controller to view
self.addChildViewController(nyt360VC)
self.view.addSubview(self.nyt360VC.view)
self.nyt360VC.didMove(toParentViewController: self)

0

我在这里使用SceneKit为iOS实现了一个类似的解决方案:ThreeSixtyPlayer

在我看来,这段代码比其他解决方案更简单、更可扩展。然而,它只是基础部分(没有立体播放,仅支持球形几何,还不支持cardboard等)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接