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>) { }
}
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.
import Foundation
import SwiftUI
import AVKit
struct ContentView: View {
var body: some View {
MainVideoPlayer(url: URL(string: "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4")!)
}
}
struct MainVideoPlayer: View {
let url: URL
@State var player = AVPlayer()
var body: some View {
VideoPlayer(player: player)
.frame(height: 300)
.onDisappear {
player.pause()
}
.onAppear {
player = AVPlayer(url: url)
player.play()
}
}
}
See also: VideoPlayer