Lahfir
Lahfir

Reputation: 379

View Immersive option is not visible on the AVPlayer

I'm trying to build a player to view spatial videos. When I try to open the video normally from Files or Photos in my VisionPro simulator, the View Immersive option is showing and the spatial video is representable. But I cannot view the same option in the player I build using AVPlayer

View Immersive Option in VisionPro

Here's my ContentView

import SwiftUI
import AVKit

struct ContentView: View {
    @ObservedObject var viewModel: ImmersiveVideoViewModel
    @Environment(\.openImmersiveSpace) var openImmersiveSpace
    @Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
    @State private var showVideoPlayer = false
    
    var body: some View {
        VStack {
            Toggle(viewModel.showImmersiveSpace ? "Back to Reality" : "Show Immersive space", isOn: $viewModel.showImmersiveSpace)
                .toggleStyle(.button)
                .onChange(of: viewModel.showImmersiveSpace) { _, newValue in
                    Task {
                        if newValue {
                            if viewModel.videoType == .degree180 {
                                showVideoPlayer = true
                            } else {
                                await openImmersiveSpace(id: "VideoImmersiveView")
                            }
                        } else {
                            await dismissImmersiveSpace()
                        }
                    }
                }
                .controlSize(.extraLarge)
            
            Picker("Video Type", selection: $viewModel.videoType) {
                Text("360°").tag(VideoType.degree360)
                Text("180°").tag(VideoType.degree180)
            }
            .pickerStyle(SegmentedPickerStyle())
            .padding()
        }
        .fullScreenCover(isPresented: $showVideoPlayer) {
            if let playerViewController = viewModel.presentVideoPlayer() {
                VideoPlayerViewControllerRepresentable(playerViewController: playerViewController)
            }
        }
    }
}

struct VideoPlayerViewControllerRepresentable: UIViewControllerRepresentable {
    let playerViewController: AVPlayerViewController
    
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        return playerViewController
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {}
}

Here's my ImmersiveViewModel:

import SwiftUI
import RealityKit
import AVKit

enum VideoType {
    case degree360
    case degree180
}

class ImmersiveVideoViewModel: ObservableObject {
    @Published var showImmersiveSpace = false
    @Published var videoType: VideoType = .degree360
    
    func generateVideoMaterial(for type: VideoType) -> VideoMaterial? {
        guard let url = Bundle.main.url(forResource: "SPATIAL", withExtension: "mov") else {
            print("Error loading video")
            return nil
        }
        
        self.videoType = type
        
        let avPlayer = AVPlayer(url: url)
        let videoMaterial = VideoMaterial(avPlayer: avPlayer)
        avPlayer.play()
        
        return videoMaterial
    }
    
    func presentVideoPlayer() -> AVPlayerViewController? {
        guard let url = Bundle.main.url(forResource: "SPATIAL", withExtension: "mov") else {
            print("Error loading video")
            return nil
        }
        
        let avPlayer = AVPlayer(url: url)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = avPlayer
        
        avPlayer.play()
        
        return playerViewController
    }
}

Here's the result of the code:

No option for switching to immerisve view

Note: The video opened using Files is the same as the video that I loaded on my code!

Upvotes: 1

Views: 113

Answers (0)

Related Questions