What's the trick to getting AVPlayer video content to show up in one's view?
We are using the following AVPlayer code but nothing is appearing on screen. We know the video is there because we were able to show it using an MPMoviePlayerController.
Here is the code we are using:
AVAsset *asset = [AVAsset assetWithURL:videoTempURL];
AVPlayerItem *item = [[AVPlayerItem alloc] initWithAsset:asset];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
// layer.frame = self.view.frame;
[self.view.layer addSublayer:layer];
layer.backgroundColor = [UIColor clearColor].CGColor;
//layer.backgroundColor = [UIColor greenColor].CGColor;
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[player play];
Are we setting the layer improperly for the current view?
You need to set the layer's frame property. e.g.:
self.playerLayer.frame = CGRectMake(0, 0, 100, 100)
If you tried this and it didn't work in the view controller's view, it is likely that you tried to set the layer's frame
property to the view-controllers frame
or bounds
property which was {0, 0, 0, 0}
at the time the AVPlayerLayer
was created. You will need to set the frame of the player during layout-passes, at which point the view-controller's frame
will be set to something other than {0, 0, 0, 0}
. To do this properly:
If you're using auto-layout in a custom UIView (including IB):
override func layoutSubviews() {
super.layoutSubviews()
//Match size of view
CATransaction.begin()
CATransaction.setDisableActions(true)
self.playerLayer.frame = self.bounds
CATransaction.commit()
}
If you're using auto-layout in a custom UIViewController:
override fun viewDidLayoutSubviews() {
//Match size of view-controller
CATransaction.begin()
CATransaction.setDisableActions(true)
self.playerLayer.frame = self.view.bounds
CATransaction.commit()
}
The CATransaction
lines are to disable implicit animations on the layer's frame change. If you're wondering why this normally not needed, it's because layers that back UIView's will not implicitly animate by default. In this case, we are using a non-view backed layer (AVPlayerLayer
)
The best route to take will be to add a new view to your view-controller through interface build and set a custom class on the newly added view. Then create that custom view class and implement the layoutSubviews
code.