I fixed the problem myself.
PlayerLooper must be a member variable in the class, otherwise it will not work, because after calling the method the local variable will disappear. So I put this line at the beginning of the class to declare it. I did not declare it as AVPlayerLooper, because it is only for tvos10.0 and newer versions. I want my class to be adaptive to tvos9.0. This is my working code.
var playerLooper: NSObject? var playerLayer:AVPlayerLayer! var queuePlayer: AVQueuePlayer? func playVideo(_ filmName: String){ if let path = Bundle.main.path(forResource: filmName, ofType: "mov") { let url = URL(fileURLWithPath: path) if #available(tvOS 10.0, *) { // Use a new player looper with the queue player and template item let playerItem = AVPlayerItem(url: url as URL) self.player = AVQueuePlayer(items: [playerItem]) self.playerLayer = AVPlayerLayer(player: self.player) self.playerLooper = AVPlayerLooper(player: self.player! as! AVQueuePlayer, templateItem: playerItem) self.view.layer.addSublayer(self.playerLayer!) self.playerLayer?.frame = self.view.frame self.player?.play() } else { // Fallback on earlier versions, this solution has hicup at end player = AVPlayer(url: url) player?.play() loopVideo(player!) } } } func loopVideo(_ videoPlayer: AVPlayer) { NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in if(!self.isStopped){ videoPlayer.seek(to: kCMTimeZero) videoPlayer.play() } } }
flame3
source share