AVPlayerLayer 没有显示 AVPlayer 视频?

AVPlayerLayer isn't showing AVPlayer video?

让 AVPlayer 视频内容显示在一个人的视图中有什么诀窍?

我们正在使用以下 AVPlayer 代码,但屏幕上没有显示任何内容。我们知道视频在那里,因为我们能够使用 MPMoviePlayerController 来显示它。

这是我们使用的代码:

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];

我们是否为当前视图设置了不正确的图层?

事实证明,AVPlayer 需要自己的上下文视图才能播放。

我们添加了这段代码,现在可以播放视频了。不幸的是,与 MPMoviePlayerController 不同,AVPlayer 没有内置控件。目前还不清楚为什么 Apple 不赞成使用具有非标准化视频播放选项的工具。

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];

您需要设置图层的边框属性。例如:

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

如果您尝试了此操作但它在视图控制器的视图中不起作用,则可能是您尝试将图层的 frame 属性 设置为视图控制器 framebounds 属性 在创建 AVPlayerLayer 时是 {0, 0, 0, 0}。您需要在布局过程中设置播放器的框架,此时视图控制器的 frame 将设置为 {0, 0, 0, 0} 以外的值。要正确执行此操作:

如果您在自定义 UIView(包括 IB)中使用自动布局:

override func layoutSubviews() {
    super.layoutSubviews()

    //Match size of view
    CATransaction.begin()
    CATransaction.setDisableActions(true)
    self.playerLayer.frame = self.bounds
    CATransaction.commit()
}

如果您在自定义 UIViewController 中使用自动布局:

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

CATransaction 行用于禁用图层帧更改时的隐式动画。如果您想知道为什么这通常不需要,那是因为默认情况下支持 UIView 的图层不会隐式设置动画。在这种情况下,我们使用非视图支持层 (AVPlayerLayer)

最佳途径是通过界面构建​​向视图控制器添加新视图,并在新添加的视图上设置自定义 class。然后创建该自定义视图 class 并实施 layoutSubviews 代码。