暂时只简单做个笔记,后面再考虑写详细一点。如果您知道还有其他方式,真心希望在留言里告诉我,不用说得很详细,告诉我个方向就行(学习最怕的是不知道方向)
一、最简单粗暴:让UI导出不同质量的动画,根据机型或者剩余性能播放不同的动画。好处是其质量由UI控制,可以选择性去掉一些特效,坏处是导入多个SVGA使得包变大。
二、忽略一些帧的播放:SVGA内部是通过CADisplayLink轮番切换帧播放的,可以均匀间隔的选择播放一些帧。优化效果很明显,但是忽略一些帧,可能会导致部分动画看起来不连续
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WLSVGAOptimizeView : UIView
/*
默认为1,隔多少帧采一帧
如果2,则是播放0 2 4 6 8......
如果3则播放0 3 6 9.........
总播放时长不变
*/
@property (nonatomic, assign) int samplingKM;
@end
NS_ASSUME_NONNULL_END
#import "WLSVGAOptimizeView.h"
#import "SVGA.h"
@interface WLSVGAOptimizeView ()
@property (nonatomic, strong) SVGAPlayer *playerKM;
@property (nonatomic, strong) SVGAParser *parserKM;
@property (nonatomic, strong) CADisplayLink *displayLinkKM;
//总帧率
@property (nonatomic, assign) int framesKM;
//记录当前的帧数
@property (nonatomic, assign) int currentFramesCount;
@end
@implementation WLSVGAOptimizeView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.samplingKM = 1;
self.playerKM = [[SVGAPlayer alloc] init];
[self addSubview:self.playerKM];
[self.parserKM parseWithNamed:@"Goddess"
inBundle:nil
completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
self.framesKM = videoItem.frames;
self.currentFramesCount = -1;
self.playerKM.videoItem = videoItem;
[self.displayLinkKM invalidate];
self.displayLinkKM = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkKMCallBack:)]; //强饮用问题还没解决
self.displayLinkKM.preferredFramesPerSecond = videoItem.FPS;
[self.displayLinkKM addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
} failureBlock:nil];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.playerKM.frame = self.bounds;
}
- (void)displayLinkKMCallBack:(CADisplayLink *)displayLink {
self.currentFramesCount++;
/*
默认为1,隔多少帧采一帧
如果2,则是播放0 2 4 6 8......
如果3则播放0 3 6 9.........
总播放时长不变
*/
if ((self.currentFramesCount % self.samplingKM) != 0) return; //忽略一些帧
[self.playerKM stepToFrame:self.currentFramesCount % self.framesKM
andPlay:NO];
}
- (SVGAParser *)parserKM {
if (!_parserKM) {
_parserKM = [[SVGAParser alloc] init];
}
return _parserKM;
}
@end
三、对SVGA图片素材进行优化,可以在图片加载进内存的时候就进行压缩或者采样。以下是关键方法
//这两个方法位于SVGAVideoEntity中
- (void)resetImagesWithProtoObject:(SVGAProtoMovieEntity *)protoObject;
- (void)resetImagesWithJSONObject:(NSDictionary *)JSONObject;