问题
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?
回答1:
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.
回答2:
It turns out that AVPlayer needs its own contextual view in order to play.
We added this code and now the video plays. Unfortunately, AVPlayer has no built in controls unlike MPMoviePlayerController. It is unclear why Apple is deprecating towards a tool that will have non-standardized video playback options.
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0, 320.0f, 200.0f)];
layer.frame = self.view.frame;
[containerView.layer addSublayer:layer];
[self.view addSubview:containerView];
layer.backgroundColor = [UIColor greenColor].CGColor;
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[player play];
来源:https://stackoverflow.com/questions/31403013/avplayerlayer-isnt-showing-avplayer-video