Reputation: 331
I'm trying to get a video to play in my macOS project and I want it to continuously loop. I was able to get it to play once but I can't figure out how to get it to loop. I'm using the AVPlayerLooper but seem to be messing up somewhere. Here is my code:
import Cocoa
import AVKit
import AVFoundation
class ViewController: NSViewController {
@IBOutlet weak var videoPlayer: AVPlayerView!
override func viewDidLoad() {
//var loop: AVPlayerLooper?
super.viewDidLoad()
guard let path = Bundle.main.path(forResource: "Background", ofType:"mp4") else {
debugPrint("Not found")
return
}
let asset = AVAsset(url: URL(fileURLWithPath: path))
let item = AVPlayerItem(asset: asset)
let queuePlayer = AVQueuePlayer(playerItem: item)
let loop = AVPlayerLooper(player: queuePlayer, templateItem: item)
videoPlayer.player = queuePlayer
videoPlayer.player?.play()
}
}
I also have an AVPlayerView in my storyboard that I have connected to my viewcontroller.
It builds and runs fine but when I run it nothing shows up. I just get a black screen.
Any help is appreciated. Thanks!
Upvotes: 1
Views: 1468
Reputation: 2712
Try assigning the AVPlayerLooper
to the class member instance. Since it is not used it very likely gets deallocated right away and so no looping happens.
self.loop = AVPlayerLooper(player: queuePlayer, templateItem: item)
Upvotes: 0
Reputation: 278
A bit late on the response here. There is better guidance now since your 2018 question. Take a close look at the sample code in the WWDC22 "Display HDR video in EDR with AVFoundation and Metal". https://developer.apple.com/wwdc22/110565
The WWDC session is quite packed.. For me it needed multiple replays to really take in the guidance.
I have found that the AVPlayerLoop needs to add the videoColorProperties and the outPutSettings in a AVPlayerItemVideoOutPut object to each member of the repeatingItems in the AVPlayerLoop. This is implied in the documentation for AVPlayerItemVideoOutPut
I don't see anything in your code sample that is listening for the
hasNewPixelBuffer(forItemTime: currentTime)
When there is a new buffer frame then copy the pixelBuffer as shown in the sample code from the WWDC session. A missing frame update could explain your black screen.
copyPixelBuffer(forItemTime: currentTime,
itemTimeForDisplay: nil)
Upvotes: 0
Reputation: 622
AVPlayerLoop is sort of a "top level" object that manages both the player and the player item. So you have to keep it around, e.g. in a custom property of the view controller, or it will be released before it can really do anything
Since AVPlayerLoop manages the items in the AVQueuePlayer, initialize the queue player without passing in the player item
Upvotes: 6