Created
August 8, 2024 11:23
-
-
Save igor11191708/2784ff7841e48199b14d3d3ac5a1b99f to your computer and use it in GitHub Desktop.
Transforming Standard Videos into Immersive Spherical Experiences
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import SceneKit | |
import AVFoundation | |
// the video is from https://www.videvo.net/video/chicago-skate-park-from-above/578690/#rs=video-box | |
struct ContentView: View { | |
var body: some View { | |
CustomSceneView() | |
.ignoresSafeArea() | |
} | |
} | |
struct CustomSceneView: UIViewRepresentable { | |
func makeUIView(context: Context) -> SCNView { | |
let sceneView = SCNView() | |
sceneView.scene = setupScene() | |
sceneView.allowsCameraControl = true | |
sceneView.autoenablesDefaultLighting = true | |
sceneView.isPlaying = true // Keep updating the view even when there are no interactions | |
return sceneView | |
} | |
func updateUIView(_ uiView: SCNView, context: Context) { | |
// Update the view if necessary | |
} | |
private func setupScene() -> SCNScene { | |
let scene = SCNScene() | |
let cameraNode = SCNNode() | |
cameraNode.camera = SCNCamera() | |
cameraNode.camera?.fieldOfView = 75 | |
cameraNode.position = SCNVector3(x: 0, y: 0, z: -10) | |
cameraNode.eulerAngles.y = .pi // Rotate the camera 180 degrees around the Y-axis | |
scene.rootNode.addChildNode(cameraNode) | |
let videoNode = SCNNode() | |
let sphere = SCNSphere(radius: 25) | |
sphere.firstMaterial?.diffuse.contents = setupPlayer() | |
sphere.firstMaterial?.isDoubleSided = true | |
sphere.firstMaterial?.cullMode = .front | |
videoNode.geometry = sphere | |
videoNode.position = SCNVector3(x: 0, y: 0, z: -5) | |
scene.rootNode.addChildNode(videoNode) | |
return scene | |
} | |
private func setupPlayer() -> AVPlayer? { | |
guard let url = Bundle.main.url(forResource: "Chicago_Skatepark_1596465264", withExtension: "mp4") else { | |
print("Video file not found") | |
return nil | |
} | |
let player = AVPlayer(url: url) | |
let playerItem = AVPlayerItem(url: url) | |
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: playerItem, queue: .main) { _ in | |
player.seek(to: CMTime.zero) { _ in | |
player.play() | |
} | |
} | |
player.replaceCurrentItem(with: playerItem) | |
player.play() | |
return player | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment