AVPlayerLayer isn't showing AVPlayer video?
Asked Answered
B

2

6

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?

Belittle answered 14/7, 2015 at 9:38 Comment(1)
Is the video store in your bundle?Hagerty
B
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];
Belittle answered 14/7, 2015 at 9:57 Comment(1)
Doesn't work for me. I have a dedicated UIView in Storyboard that contains the player layer. I see the green background color, but no video.Wheelsman
B
14

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.

Behave answered 17/12, 2015 at 1:15 Comment(1)
This did not work for me; the frame property immediately has the correct values (not CGRectZero) but setting it again does not help. (iOS 14, real device).Prosthodontics
B
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];
Belittle answered 14/7, 2015 at 9:57 Comment(1)
Doesn't work for me. I have a dedicated UIView in Storyboard that contains the player layer. I see the green background color, but no video.Wheelsman

© 2022 - 2024 — McMap. All rights reserved.