I have recently started touching swiftUI. For iOS16, I want to use AVFoundation to play the video for transition once and then loop the video for loop, but I don’t know a good way to do it.
I would like to be able to choose to play the transition video with or without the loop video.
I asked ChatGPT3.0 and it returned the code below, but this did not work: after the video for transition and the video for loop plays once each, nothing is displayed.
I think it is under NotificationCenter that is not working, but I don’t know how to change it.
import UIKit
import AVFoundation
class LoopingPlayerUIView: UIView {
private let playerLayer = AVPlayerLayer()
private var playerLooper: AVPlayerLooper?
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/// Depending on your video you can select a proper `videoGravity` property to fit better
init(loopedVideoName: String,
firstVideoName: String? = nil,
player: AVQueuePlayer,
videoGravity: AVLayerVideoGravity = .resizeAspectFill) {
super.init(frame: .zero)
// Load the looped video
guard let loopedFileUrl = Bundle.main.url(forResource: loopedVideoName, withExtension: "mp4") else { return }
let loopedAsset = AVAsset(url: loopedFileUrl)
let loopedItem = AVPlayerItem(asset: loopedAsset)
// Set up the player with the looped video
player.isMuted = true
playerLayer.player = player
playerLayer.videoGravity = videoGravity
layer.addSublayer(playerLayer)
// Play the first video once if provided
if let firstVideoName = firstVideoName {
guard let firstFileUrl = Bundle.main.url(forResource: firstVideoName, withExtension: "mp4") else { return }
let firstAsset = AVAsset(url: firstFileUrl)
let firstItem = AVPlayerItem(asset: firstAsset)
playerLooper = AVPlayerLooper(player: player, templateItem: firstItem)
// Observer for the end of the first video
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { _ in
// Switch to looped video and enable looping
self.player.replaceCurrentItem(with: loopedItem)
self.playerLooper = AVPlayerLooper(player: self.player, templateItem: loopedItem)
self.player.play()
}
} else {
// If firstVideoName is not provided, set up the looper for the looped video directly
playerLooper = AVPlayerLooper(player: player, templateItem: loopedItem)
}
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}




