I have a basic video player that presents videos from a url. When the view appears I call player.play()
and in doing so I think it causes the error below. I think I have to wait until the video is fully fetched from the url to try and play it. How can I achieve this?
Main thread blocked by synchronous property query on not-yet-loaded property (PreferredTransform) for HTTP(S) asset. This could have been a problem if this asset were being read from a slow network.
import SwiftUI
import AVKit
struct MainVideoPlayer: View {
let url: URL
@State var player = AVPlayer(url: URL(string: "https://www.google.com")!)
var body: some View {
ZStack {
VideoPlayer(player: $player)
}
.onAppear {
player = AVPlayer(url: url)
self.player.play()
}
}
}
struct VideoPlayer : UIViewControllerRepresentable {
@Binding var player : AVPlayer
func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPlayer>) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
controller.showsPlaybackControls = false
controller.videoGravity = .resizeAspectFill
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayer>) { }
}
2
Answers
Can’t use
@State
or@Binding
with classes. ThatAVPlayer
needs to go inside yourAVPlayerViewController
. You need alet url
and you can useupdateUIViewController
to start playing if the url is different from last time the representable was init, e.g. something like:You could try a different (more modern) approach, using Apple
VideoPlayer
, such as in this example code:Works well for me in my tests. On MacOS 14.3, using Xcode 15, tested on real ios 17 devices (and Previews), macCatalyst and MacOS.
See also: VideoPlayer