Ios7 AVPlayerLayer收缩动画

Ios7 AVPlayerLayer收缩动画,ios7,avfoundation,avplayer,caanimation,avplayerlayer,Ios7,Avfoundation,Avplayer,Caanimation,Avplayerlayer,我正试图在AVPlayerLayer上制作一个“收缩”动画,但一旦我这样做,视频内容就会从屏幕上消失。设置包含AVPlayerLayer的UIView的动画可以工作,但不能设置AVPlayerLayer的动画。设置动画的正确方法是什么 CGRect oldBounds = playerLayer.bounds; CGRect newBounds = oldBounds; newBounds.size = CGSizeZero; CABasicAnimation *animation =

我正试图在AVPlayerLayer上制作一个“收缩”动画,但一旦我这样做,视频内容就会从屏幕上消失。设置包含AVPlayerLayer的UIView的动画可以工作,但不能设置AVPlayerLayer的动画。设置动画的正确方法是什么

 CGRect oldBounds = playerLayer.bounds;
 CGRect newBounds = oldBounds;
 newBounds.size = CGSizeZero;
 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
 animation.duration = 5.f;
 animation.beginTime = CACurrentMediaTime();
 animation.fromValue = [NSValue valueWithCGRect:oldBounds];
 animation.toValue = [NSValue valueWithCGRect:newBounds];


[playerLayer addAnimation:animation forKey:@"shrink"];

默认情况下,iOS会在某个层受视图控制时关闭该层的动画。但是,在UIView上设置特性动画时,它会短暂地启用层的动画功能,并将动画参数发送到要执行的层,然后关闭层上的动画功能。也就是说:在它控制的UIView上制作动画,而不是图层


也就是说,我也不知道如何让我的AVPlayerLayer通过UIView进行动画制作。我上面说的是它应该如何工作,但我现在也不能让它工作。嘿。

这并不奇怪
AVPlayerLayer
是一个特殊的层类,因为它不存在于
QuartzCore
框架中,也没有
CA
类前缀。它还经过高度优化,可以将视频帧渲染到显示器上。试图通过UIKit或直接通过核心动画向
AVPlayerLayer
添加动画,会导致我的行为怪异

可能将任何类型的动画应用于
AVPlayerLayer
的唯一方法就是创建宿主视图的快照或将层内容直接渲染到图形上下文中。但是,如果后者不起作用,我也不会感到惊讶,因为
AVPlayerLayer
可能不包含核心动画能够渲染的后台存储

编辑:这里有一个解决此问题的游乐场解决方案,尽管它确实依赖于使用UIKit,而不仅仅是核心动画。我尚未在设备或模拟器上进行测试,但这似乎可行:

导入UIKit
进口AVF基金会
导入PlaygroundSupport
让rootView=UIView(帧:CGRect(x:0.0,y:0.0,宽度:600.0,高度:400.0))
rootView.backgroundColor=.white
让playerLayerView=UIView()
playerLayerView.frame.size=CGSize(宽度:480.0,高度:270.0)
playerLayerView.center=CGPoint(x:rootView.bounds.midX,y:rootView.bounds.midY)
guard let videoUrl=Bundle.main.url(
forResource:“HEVC_3_iPhone”,
带扩展名:“m4v”)
else{fatalError()}
let player=AVPlayer(url:videoUrl)
player.play()
let playerLayer=AVPlayerLayer(玩家:玩家)
playerLayer.frame=playerLayerView.bounds
playerLayerView.layer.addSublayer(playerLayer)
rootView.addSubview(playerLayerView)
UIView.animate(
持续时间:1.0,
延迟:0.0,
选项:[.autoreverse,.repeat],
动画:{
playerLayerView.transform=CGAffineTransform(scaleX:1.2,y:1.2)
},
完成日期:无
)
PlaygroundPage.current.liveView=rootView
下面是它的样子:

如果我理解正确的话,“问题”在于它不在标准的UIKit渲染和合成管道中,尽管这并不是一个问题,而在
AVPlayerLayer
中是一个管道需要的问题。与其他特殊图层类(如
camertallayer
)一样,
AVPlayerLayer
以不同的过程进行渲染,因为AVFoundation需要直接绘制不受UIKit渲染循环限制的屏幕。因此,尝试将动画直接附加到层是不可行的

但是,将该层放置在
UIView
中,可以使核心动画将
AVPlayerLayer
合成到视图层次结构中,这意味着视图的几何体更改将影响视频播放器层的显示。AVFoundation仍然很可能以它想要的方式渲染视频帧,但为核心动画提供了纹理,以便以它想要的方式进行合成

这可能会导致微妙的播放器计时抖动,因为您正在将以前独立渲染的视频强制到UIKit的渲染循环中。一般来说,同步这些特殊层是很困难的,因为核心动画不可避免地要等待各种进程都完成为它们的层提供渲染位图,以便它可以将所有内容组合到一个屏幕刷新中


但这都是我的猜测。

你找到解决办法了吗?我正在尝试用AVPlayerLayer支持的UIView做类似的事情。所以。。。我们如何通过播放视频层来设置UIView的动画(大小)?@Thyselius我用一个对我有用的游乐场示例更新了我的答案。