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
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()
}
}
}