0

I am starting on SwiftUI dev and I tried to create a Signin screen with a video playing in background. The Sign-in screen works fine but now it's time to make it nice.

I found on Internet this class below to play the video but I cannot make it build


import SwiftUI
import AVKit


struct VideoPlayerView: UIViewRepresentable {
    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<VideoPlayerView>) {
    }
    
    func makeUIView(context: Context) -> UIView {
        return PlayerUIView(frame: .zero)
    }
}

class PlayerUIView: UIView {
    @State var urlLink = Bundle.main.path(forResource: "splash", ofType: "mp4")!
    private let playerLayer = AVPlayerLayer()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
       // guard let filePath = Bundle.main.path(forResource: "splash", ofType: "mp4") else { return }
        
        let player = AVPlayer(url: urlLink)
        //player.actionAtItemEnd = .none
        player.play()
        
        playerLayer.player = player
        playerLayer.videoGravity = .resizeAspectFill
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(playerItemDidReachEnd(notification:)),
                                               name: .AVPlayerItemDidPlayToEndTime,
                                               object: player.currentItem)

        layer.addSublayer(playerLayer)
    }
    
    @objc func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: .zero, completionHandler: nil)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}


struct VideoPlayerView_Previews: PreviewProvider {
    static var previews: some View {
        VideoPlayerView()
    }
}

The issue is on let player = AVPlayer(url: urlLink) where it complains that he cannot convert a string to URL.

I drag'n'drop my mp4 video into the assets' folder.

Any idea? I do not look to build a real player just having a video looping in background of my signin screen

Thanks

Seb
  • 2,929
  • 4
  • 30
  • 73

1 Answers1

0

yes you have to use a different API for that. The current API you are using is only returning the string which is the path to your file. It's not a URL, And for that, you have to replace your code with the below line.

//Your code 
`Bundle.main.path(forResource: "splash", ofType: "mp4")!`
//with 
` URL(fileURLWithPath: Bundle.main.path(forResource: "", ofType: "")))

This will give you a URL for your file and you can load it on your AVPlayerLayer.

Now this is the whole solution you were trying to do.

import SwiftUI
import AVKit

struct VideoPlayerView: UIViewControllerRepresentable {
    let videoURL: URL

    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let player = AVPlayer(url: videoURL)
        player.isMuted = true
        player.play()
        
        let playerViewController = AVPlayerViewController()
        playerViewController.player = player
        
        NotificationCenter.default.addObserver(
            forName: .AVPlayerItemDidPlayToEndTime,
            object: player.currentItem,
            queue: nil
        ) { _ in
            player.seek(to: .zero)
            player.play()
        }
        
        return playerViewController
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
    }
}

struct ContentView: View {
    var body: some View {
        ZStack {
            VideoPlayerView(videoURL: URL(fileURLWithPath: Bundle.main.path(forResource: "Video", ofType: "mp4")!))
                .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
            
            VStack {
                Text("Some UI elements")
                    .foregroundColor(.white)
                    .background(Color.black)
                    .font(.title)
                            
            }
            .padding()
        }
    }
}

Attaching working video. enter image description here

B25Dec
  • 2,301
  • 5
  • 31
  • 54
  • that's not working still complain on the type – Seb Jul 07 '23 at 05:42
  • 1
    So before downvoting any answer, I would suggest you check the authenticity of that answer. It is another thing if someone provided you with a solution and it's not working for you. But it could be correct for other users, If it is not working for you only and you are downvoting that means you are not understanding the purpose of Stackoverflow. i am updating my answer and its working for me. – B25Dec Jul 07 '23 at 06:05