AVPlayerLayer not showing AVPlayer video?

What's the trick for getting AVPlayer video content in one view?

We are using the following AVPlayer code, but nothing appears on the screen. We know the video is there because we were able to show it using MPMoviePlayerController.

Here's the code we're 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 incorrectly for the current view?

+3


source to share


2 answers


It turns out that AVPlayer needs its own contextual view to play it.

We added this code and the video is now playing. Unfortunately AVPlayer does not have built-in controls, unlike MPMoviePlayerController. It's unclear why Apple is ditching a tool that will have custom 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];

      

+2


source


You need to set the frame property of the layer. eg:.

 self.playerLayer.frame = CGRectMake(0, 0, 100, 100)

      

If you've tried this and didn't work in the view of the view controller, it is likely that you tried to set the layer frame

property to the view-controllers frame

or bounds

, which was {0, 0, 0, 0}

at the time of creation AVPlayerLayer

. You will need to set the player frame during layouts, after which the view controller frame

will be set to something other than {0, 0, 0, 0}

. To do it right:

If you are 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 are using auto layout in your custom UIViewController:

override fun viewDidLayoutSubviews() {
  //Match size of view-controller
  CATransaction.begin()
  CATransaction.setDisableActions(true)
  self.playerLayer.frame = self.view.bounds
  CATransaction.commit()
}

      

Rows CATransaction

should turn off implicit animations when the layer border changes. If you're wondering why this isn't usually needed, it's because the layers that return the UIView won't animate differently by default. In this case, we are using an unsupported hidden layer ( AVPlayerLayer

)

The best route would be to add a new view to your view controller through building the interface and setting up a custom class on the new added view. Then create this custom view class and implement the code layoutSubviews

.

+5


source







All Articles