Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Main thread blocked using AVPlayer in SwiftUI

iOS 17.4 - iPhone 14 Pro - Real device

I'm facing an error when I try to implement a simple VideoPlayer view:

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.

This is the code I'm using to show the video player:

struct ContentView: View {
    @State var player: AVPlayer = AVPlayer(url: URL(string: "https://video.twimg.com/amplify_video/1760315643142750208/vid/avc1/640x360/-1etorSK7w2g9Nlc.mp4?tag=16")!)

    var body: some View {
        VideoPlayer(player: player)
    }
}

I noticed that the bundle initi method of AVPlayer doesn't trigger this error:

AVPlayer(url: Bundle.main.url(forResource: "video", withExtension: "mp4")!)

I also tried to load metadata's asset with:

try await AVAsset.load(_:)

Before giving It to AVPlayer via AVPlayerItem with no success :/

Does anyone is facing this error too ? Or is It a bug from the SDK ?

like image 880
mbc Avatar asked Nov 30 '25 16:11

mbc


1 Answers

I got same error when i tried to play my videos and solved it with below load func

func load(player: AVPlayer?) async {
        guard let player,
              let playerItem = player.currentItem,
              let asset = await playerItem.asset as? AVURLAsset
        else { return }

        do {
            let tracks: [AVAssetTrack] = try await asset.load(.tracks)

            if let track = tracks.first {
                let _ = try await track.load(.preferredTransform) // magic here
                await play()
            }

        } catch {
            print("Failed to load asset properties: \(error.localizedDescription)")
        }
    }

    @MainActor
    private func play() {
        self.readyToPlay = true
    }

when readyToPlay you can update your view to play video

example

 @StateObject
 private var viewModel = VideoViewModel()

  var body: some View {
    if viewModel.readyToPlay {
        VideoPlayer(player: player) // this can be CustomVideoPlayer up to you
            .onAppear {
                player.play()
            }
            .onDisappear {
                player.pause()
            }
    } else {
        ProgressView()
            .onAppear {
                Task {
                    await viewModel.load(player: player)
                }
            }
    }
}
like image 141
Tolga İskender Avatar answered Dec 05 '25 06:12

Tolga İskender



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!