Подтвердить что ты не робот

AVPlayerLayer оживляет изменения кадров

Всякий раз, когда я меняю кадр моего AVPlayerLayer, видео не изменяется сразу, а анимируется до нового размера.

Например: я меняю фрейм с (0, 0, 100, 100) на (0, 0, 400, 400), рамка просмотра сразу изменяется, но размер видео анимируется до нового размера.

Кто-нибудь столкнулся с этой проблемой? И если да, то кто-нибудь знает способ отключить анимацию по умолчанию?

Спасибо!

4b9b3361

Ответ 1

Вы можете попробовать отключить неявные действия и использовать анимацию нулевой длины:

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];

Ответ 2

Самый простой и чистый способ справиться с этим - создать подкласс 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;

Ответ 3

Это то, что я использовал:

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

Надеюсь, это поможет. Я не знаю, являются ли его лучшие практики, но это работает для меня. Кажется, что всякий раз, когда используется ".frame" или "setFrame", он добавляет анимацию к слою.

Ответ 4

Вы используете?:

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

Ответ 5

Вот что я делаю в Swift сразу после изменения playerLayer frame:

playerLayer.removeAllAnimations()

Ответ 6

Вероятно, это поможет в некоторых случаях:

добавление настраиваемого установщика setFrame: ', содержащего слой игрока

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

    self.playerLayer.frame = CGRectMake(0.0f, 0.0f, frame.size.width, frame.size.height);
}

Ответ 7

Я получил это, работая в 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()