Swift: Resize an AVPlayerLayer to match the bounds of its parent container
Solution 1
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()
}
Solution 2
I was able to do what you are trying to do, I think, in my own project. This is without subclassing. Here is my code:
override func viewWillLayoutSubviews() {
previewScene()
}
func previewScene() {
var firstAsset: AVAsset!, secondAsset: AVAsset!, thirdAsset: AVAsset!
firstAsset = MediaController.sharedMediaController.s3Shot1
secondAsset = MediaController.sharedMediaController.s3Shot2
thirdAsset = MediaController.sharedMediaController.s3Shot3
if firstAsset != nil && secondAsset != nil && thirdAsset != nil {
let assets = [firstAsset, secondAsset, thirdAsset]
var shots = [AVPlayerItem]()
for item in assets {
let shot = AVPlayerItem(asset: item)
shots.append(shot)
}
self.videoPlayer = AVQueuePlayer(items: shots)
self.playerLayer = AVPlayerLayer(player: self.videoPlayer)
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
AVPlayerItemDidPlayToEndTimeNotification, object: self.videoPlayer.items().last)
self.videoPreviewLayer.layer.addSublayer(playerLayer)
self.playerLayer.frame = self.videoPreviewLayer.bounds
}
}
Solution 3
introView.layer.masksToBounds = true
may also be helpful
Admin
Updated on June 19, 2022Comments
-
Admin almost 2 years
I have a local video playing using
AVPlayer
andAVPlayerLayer
(Swift, iOS 8.2), and i need to resize theAVPlayerLayer
(introPlayerLayer
) when its parent view (introView
) is resized, including on orientation change. So far nothing I have tried seems to work and theplayerLayer
has the wrong size and position.The
AVPlayer
is set up using a local mp4 video, and theAVPlayerLayer
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 theUIView
, 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 thatPlayerView
subclass (shown in Objective-C) in Swift? Thank you in advance for any assistance.