Swift: Resize an AVPlayerLayer to match the bounds of its parent container

Connor Laurel picture Connor Laurel · Mar 12, 2015 · Viewed 17.7k times · Source

I have a local video playing using AVPlayer and AVPlayerLayer (Swift, iOS 8.2), and i need to resize the AVPlayerLayer (introPlayerLayer) when its parent view (introView) is resized, including on orientation change. So far nothing I have tried seems to work and the playerLayer has the wrong size and position.

The AVPlayer is set up using a local mp4 video, and the AVPlayerLayer is initialized using that player. The layer is then added as a sublayer to the parent view.

Here is my code:

func playIntro() {
    let path = NSBundle.mainBundle().pathForResource("intro", ofType: "mp4")
    let url  = NSURL.fileURLWithPath(path!)
    let introPlayer           = AVPlayer(URL: url)
    introPlayer.allowsExternalPlayback = false

    var introPlayerLayer = AVPlayerLayer(player: introPlayer)
    introView.layer.addSublayer(introPlayerLayer)
    introPlayerLayer.frame = introView.bounds

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: introPlayer.currentItem)

    introView.hidden = false
    introPlayer.play()
}

Should I be adding the AVPlayerLayer as a sublayer of the UIView, or should I be subclassing the parent container (UIView) as shown in the "The Player View" section of https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html. If so, how would I write that PlayerView subclass (shown in Objective-C) in Swift? Thank you in advance for any assistance.

Answer

Cristian Cardoso picture Cristian Cardoso · Jun 9, 2017

Swift 3.

private func playVideo() {
        guard let path = Bundle.main.path(forResource: "video", ofType:"mp4") else {
            debugPrint("video.m4v not found")
            return
        }
        let player = AVPlayer(url: URL(fileURLWithPath: path))
        var playerLayer: AVPlayerLayer?
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
        playerLayer!.frame = self.view.frame
        self.view!.layer.addSublayer(playerLayer!)
        player.play()

    }