我正试着在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"];发布于 2015-08-02 01:24:18
当层由视图控制时,iOS默认情况下会关闭层的动画。但是,当您为UIView上的属性设置动画时,它会短暂启用该层的动画功能,并将动画参数发送到该层以执行,然后再次关闭该层的动画功能。也就是说:在它控制的UIView上做动画,而不是层。
也就是说,我也不知道如何通过我的UIView让我的AVPlayerLayer动画。我上面说的是它应该是如何工作的,但我现在也不能让它工作。哈哈。
发布于 2015-11-24 06:11:23
这并不令人惊讶。AVPlayerLayer是一个特殊的层类,因为它不存在于QuartzCore框架中,也不具有CA类前缀。它还经过了高度优化,可以将视频帧渲染到显示器上。尝试通过UIKit间接或直接通过核心动画将动画添加到AVPlayerLayer,会导致我出现奇怪的行为。
将任何类型的动画应用于AVPlayerLayer的唯一方法可能是只创建主机视图的快照,或者直接将层内容渲染到图形上下文中。然而,如果后者不起作用,我不会感到惊讶,因为AVPlayerLayer可能不包含核心动画能够渲染的后备存储。
编辑:这是一个解决这个问题的游乐场解决方案,尽管它确实依赖于使用UIKit,而不是仅仅使用核心动画。我还没有在设备或模拟器上进行测试,但这似乎可以工作:
import UIKit
import AVFoundation
import PlaygroundSupport
let rootView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 600.0, height: 400.0))
rootView.backgroundColor = .white
let playerLayerView = UIView()
playerLayerView.frame.size = CGSize(width: 480.0, height: 270.0)
playerLayerView.center = CGPoint(x: rootView.bounds.midX, y: rootView.bounds.midY)
guard let videoUrl = Bundle.main.url(
forResource: "HEVC_3_iPhone",
withExtension: "m4v")
else { fatalError() }
let player = AVPlayer(url: videoUrl)
player.play()
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = playerLayerView.bounds
playerLayerView.layer.addSublayer(playerLayer)
rootView.addSubview(playerLayerView)
UIView.animate(
withDuration: 1.0,
delay: 0.0,
options: [.autoreverse, .repeat],
animations: {
playerLayerView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
},
completion: nil
)
PlaygroundPage.current.liveView = rootView它看起来是这样的:

如果我理解正确的话,这个“问题”与其说是管道的必要性,不如说是一个问题-- AVPlayerLayer位于标准的UIKit渲染和合成管道之外。与其他特殊的层类,如CAMetalLayer,AVPlayerLayer在不同的进程中呈现,因为AVFoundation需要直接绘制访问不受UIKit的呈现循环限制的屏幕。因此,尝试将动画直接附加到层是不起作用的。
但是,将该层放置在UIView中可使核心动画将AVPlayerLayer合成到视图层次中,这意味着对视图所做的几何体更改将影响视频播放器层的显示。AVFoundation仍然很可能以它想要的方式呈现视频帧,但它为核心动画提供了一个纹理,以它想要的方式合成。
这可能会导致细微的播放器计时抖动,因为您正在将以前独立渲染的视频强制到UIKit的渲染循环中。一般来说,同步这些特殊的层是很棘手的,因为Core Animation必须不可避免地等待各种进程都完成为它们的层提供渲染的位图,以便它可以将所有内容合成到一个屏幕刷新中。
但这都是我的猜测。
https://stackoverflow.com/questions/24709607
复制相似问题