I'm using the following code to create a video player for detected reference images in AR session. Currently I display a placeholder video and after 1 second switch to real video that I want played. However, I would like to show the placeholder video until the real video is ready to be played.
I tried experimenting with AVAsset and observing the playable status based on this: Knowing when AVPlayer object is ready to play - however I didn't have any success.
func createVideoNode(_ target: ARReferenceImage) -> ModelEntity {
var videoPlane = ModelEntity()
var targetName: String = ""
if let name = target.name,
let validURL = URL(string: "https://testdomain.com/\(name).mp4") {
targetName = name
// Use the preloaded placeholder asset to create an AVPlayer
if let placeholderAsset = parent.placeholderAsset {
let placeholderPlayer = AVPlayer(playerItem: AVPlayerItem(asset: placeholderAsset))
let videoMaterial = VideoMaterial(avPlayer: placeholderPlayer)
videoPlane = ModelEntity(mesh: .generatePlane(width: Float(target.physicalSize.width), depth: Float(target.physicalSize.height)), materials: [videoMaterial])
placeholderPlayer.play()
DispatchQueue.global(qos: .background).async {
let videoPlayer = AVPlayer(url: validURL)
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: videoPlayer.currentItem, queue: .main) { [weak videoPlayer] _ in
videoPlayer?.seek(to: CMTime.zero)
videoPlayer?.play()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
let videoMaterial = VideoMaterial(avPlayer: videoPlayer)
videoPlane.model?.materials = [videoMaterial]
videoPlayer.play()
self.parent.videoPlayers[targetName] = videoPlayer
print (target.name as Any)
}
}
} else {
fatalError("Failed to load placeholder video asset.")
}
}
return videoPlane
}