AVPlayerLayer动画帧更改

问题描述 投票:11回答:7

每当我更改AVPlayerLayer的帧时,视频不会立即调整大小,而是动画为新大小。

例如:我将帧从(0,0,100,100)更改为(0,0,400,400),视图的帧立即更改,但视频的大小设置为新大小。

有没有人遇到过这个问题?如果有,是否有人知道禁用默认动画的方法?

谢谢!

ios video avfoundation movie
7个回答
22
投票

您可以尝试禁用隐式操作并使用零长度动画:

CALayer *videolayer = <# AVPlayerLayer #>
[CATransaction begin];
[CATransaction setAnimationDuration:0];
[CATransaction setDisableActions:YES];
CGRect rect = videolayer.bounds;
rect.size.width /= 3;
rect.size.height /= 3;
videolayer.bounds = rect; 
[CATransaction commit];

4
投票

这是我用过的:

AVPlayerLayer * playerLayer = <# AVPlayerLayer #>;
playerLayer.frame = <# CGRect #>;
[playerLayer removeAllAnimations];

我希望这有帮助。我不知道它是否是最佳实践,但它对我有用。似乎每当使用“.frame”或“setFrame”时,它都会向图层添加动画。


4
投票

处理这个问题最简单,最干净的方法是创建一个UIView子类,它将AVPlayerLayer作为其layerClass。这样做时,AVPlayerLayer的行为就像常规的UIView层一样。您可以更改视图的框架而不是图层,并且不会发生隐式动画。

AVPlayerLayerView.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AVPlayerLayerView : UIView

@property (nonatomic, readonly) AVPlayerLayer *playerLayer;

@end

AVPlayerLayerView.m

#import "AVPlayerLayerView.h"

@implementation AVPlayerLayerView

+ (Class)layerClass {
    return [AVPlayerLayer class];
}

- (AVPlayerLayer *)playerLayer {
    return (AVPlayerLayer *)self.layer;
}

@end

你现在可以这样做:

playerLayerView.frame = CGRectMake(0, 0, 400, 400);

要将AVPlayerLayer与AVPlayer关联,只需执行以下操作:

playerLayerView.playerLayer.player = player;

1
投票

你用的是?:

- (void)setPlayer:(AVPlayer *)player {
    [(AVPlayerLayer *)[self layer] setPlayer:player];
    [(AVPlayerLayer *)[self layer] setVideoGravity:AVLayerVideoGravityResize];
}

1
投票

这是我在更改playerLayerframe之后在Swift中所做的事情:

playerLayer.removeAllAnimations()

1
投票

我通过以下方式在Swift 4中工作:

    var videoLayer = AVPlayerLayer()
    CATransaction.begin()
    CATransaction.setAnimationDuration(0)
    CATransaction.setDisableActions(true)
    var rect = videoLayer.bounds
    rect.size.width /= 3
    rect.size.height /= 3
    videoLayer.bounds = rect
    CATransaction.commit()

0
投票

可能这个,在某些情况下会有所帮助:

在视图中添加自定义'setFrame:'setter,用于保存播放器图层

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];

    self.playerLayer.frame = CGRectMake(0.0f, 0.0f, frame.size.width, frame.size.height);
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.