AVPlayer 帧动画

问题描述 投票:0回答:2

我正在开发一个应用程序,其中包含播放带有每帧动画的视频的功能。 您可以查看此类功能的示例

我已经尝试将

CAKeyFrameAnimation
添加到
AVSynchronizedLayer
的子层,但遇到了 一些麻烦

我也已经尝试使用

AVAssetExportSession
预渲染视频,并且效果很好。但速度非常慢。渲染此类视频最多需要 3 分钟。

也许还有其他方法可以实现?

更新:

这就是我用

AVSynchronizedLayer
实现动画的方法:

let fullScreenAnimationLayer = CALayer()
fullScreenAnimationLayer.frame = videoRect
fullScreenAnimationLayer.geometryFlipped = true

values: [NSValue] = [], times: [NSNumber] = []

// fill values array with positions of face center for each frame
values.append(NSValue(CATransform3D: t))

// fill times with corresoinding time for each frame
times.append(NSNumber(double: (Double(j) / fps) / videoDuration)) // where fps = 25 (according to video file fps)

...

let transform = CAKeyframeAnimation(keyPath: "transform")
transform.duration = videoDuration
transform.calculationMode = kCAAnimationDiscrete
transform.beginTime = AVCoreAnimationBeginTimeAtZero
transform.values = values
transform.keyTimes = times
transform.removedOnCompletion = false
transform.fillMode = kCAFillModeForwards
fullScreenAnimationLayer.addAnimation(transform, forKey: "a_transform")

...

if let syncLayer = AVSynchronizedLayer(playerItem: player.currentItem) {
    syncLayer.frame = CGRect(origin: CGPointZero, size: videoView.bounds.size)
    syncLayer.addSublayer(fullScreenAnimationLayer)
    videoView.layer.addSublayer(syncLayer)
}
ios swift video avfoundation
2个回答
0
投票
import AVFoundation
import UIKit


class ViewController: UIViewController {
    var player: AVPlayer?
    var displayLink: CADisplayLink?
    var animationImageView: UIImageView?

    override func viewDidLoad() {
        super.viewDidLoad()

        let videoURL = URL(fileURLWithPath: "path_to_your_video_file")
        player = AVPlayer(url: videoURL)

        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = view.bounds
        view.layer.addSublayer(playerLayer)

        player?.play()

        // Create an image view for per-frame animation
        animationImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        animationImageView?.animationImages = [UIImage(named: "frame1")!, UIImage(named: "frame2")!, UIImage(named: "frame3")!]
        animationImageView?.animationDuration = 1.0 // Adjust as needed
        animationImageView?.startAnimating()

        view.addSubview(animationImageView!)

        // Start CADisplayLink
        displayLink = CADisplayLink(target: self, selector: #selector(update))
        displayLink?.add(to: .main, forMode: .default)
    }

    @objc func update() {
        // Update animation position or any other logic here
        // For example, you could sync the animation with the video playback time
        guard let currentTime = player?.currentTime().seconds else { return }
        // Update animation based on currentTime
    }
}

将“frame1”、“frame2”、“frame3”等替换为动画帧的名称。根据需要调整动画持续时间和任何其他参数。


-2
投票

这是我的看法,

将 AVPlayer 图层属性(AVPlayerLayer 类)添加到 UIView 图层的子图层中,然后操作视图动画。

例如,

AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:blahURL options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:urlAsset];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = yourFrame;

UIView *videoView = [UIView new];
[videoView addSublayer:playerLayer];

然后

为 videoView 提供动画

© www.soinside.com 2019 - 2024. All rights reserved.