首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVPlayerLayer收缩动画

AVPlayerLayer收缩动画
EN

Stack Overflow用户
提问于 2014-07-12 12:17:56
回答 2查看 1K关注 0票数 3

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

代码语言:javascript
复制
 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"];
EN

回答 2

Stack Overflow用户

发布于 2015-08-02 01:24:18

当层由视图控制时,iOS默认情况下会关闭层的动画。但是,当您为UIView上的属性设置动画时,它会短暂启用该层的动画功能,并将动画参数发送到该层以执行,然后再次关闭该层的动画功能。也就是说:在它控制的UIView上做动画,而不是层。

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

票数 1
EN

Stack Overflow用户

发布于 2015-11-24 06:11:23

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

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

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

代码语言:javascript
复制
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渲染和合成管道之外。与其他特殊的层类,如CAMetalLayerAVPlayerLayer在不同的进程中呈现,因为AVFoundation需要直接绘制访问不受UIKit的呈现循环限制的屏幕。因此,尝试将动画直接附加到层是不起作用的。

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

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

但这都是我的猜测。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24709607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档