//
// ZKRBaiWeiAdManager.m
// VAPictureBoomAnimationDemo
//
// Created by ZAKER on 2019/6/4.
// Copyright © 2019 ZAKER. All rights reserved.
//
#import "ZKRBaiWeiAdManager.h"
static ZKRBaiWeiAdManager *shareManager = nil;
@interface ZKRBaiWeiAdManager ()
@property (nonatomic, strong) UIView *animationView;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerLayer *palyLayer;
@property (nonatomic, assign) ZKRBaiWeiAVPlayerStatus status;
@property (nonatomic, weak) UIButton *maskBtn;
@property (nonatomic, strong) id listenObj;
@property (nonatomic, weak) id <ZKRBaiWeiAdManagerPlayerDelegate>delegate;
@property (nonatomic, assign) BOOL isAlreadlyStartPlaying;
@property (nonatomic, assign) BOOL isAlreadlyStartAnimating;
@end
@implementation ZKRBaiWeiAdManager
+ (instancetype)shareManager{
shareManager = [[ZKRBaiWeiAdManager alloc] init];
return shareManager;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
if (shareManager) {
return shareManager;
}
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareManager = [super allocWithZone:zone];
});
return shareManager;
}
- (UIImage *)clipTofullScreen{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGSize imageSize = CGSizeZero;
if (UIInterfaceOrientationIsPortrait(orientation))
imageSize = [UIScreen mainScreen].bounds.size;
else
imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
CGContextSaveGState(context);
CGContextTranslateCTM(context, window.center.x, window.center.y);
CGContextConcatCTM(context, window.transform);
CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
if(orientation == UIInterfaceOrientationLandscapeLeft){
CGContextRotateCTM(context, (CGFloat)M_PI_2);
CGContextTranslateCTM(context, 0, -imageSize.width);
}
else if(orientation == UIInterfaceOrientationLandscapeRight){
CGContextRotateCTM(context, (CGFloat)-M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, 0);
}
else if(orientation == UIInterfaceOrientationPortraitUpsideDown)
{
CGContextRotateCTM(context, (CGFloat)M_PI);
CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
}
if([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO];
}
else{
[window.layer renderInContext:UIGraphicsGetCurrentContext()];
}
CGContextRestoreGState(context);
}
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (UIView *)animationView{
if (!_animationView) {
UIView *animationView = [[UIView alloc] init];
_animationView = animationView;
}
return _animationView;
}
- (UIView *)lancinateAnimationView:(UIView *)view size:(CGSize)size{
self.animationView.frame = view.bounds;
[view.superview addSubview:self.animationView];
UIGraphicsBeginImageContext(view.bounds.size);
[[UIColor clearColor] setFill];
[[UIBezierPath bezierPathWithRect:view.bounds] fill];
CGContextRef ctx = UIGraphicsGetCurrentContext();
[view.layer renderInContext:ctx];
UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSInteger maxX = floor(screenshotImage.size.width / size.width);
NSInteger maxY = floor(screenshotImage.size.height / size.height);
for (int i=0; i<maxX; i++) {
for (int j = 0; j<maxY; j++) {
@autoreleasepool {
CALayer* layer = [[CALayer alloc] init];
layer.frame = CGRectMake(i*size.width, (maxY-j-1)*size.height, size.width, size.height);
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
size.width,
size.height,
8,
0,
CGImageGetColorSpace(screenshotImage.CGImage),
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
CGContextTranslateCTM(offscreenContext, -i*size.width, -j*size.height);
CGContextDrawImage(offscreenContext, CGRectMake(0, 0, screenshotImage.size.width, screenshotImage.size.height), screenshotImage.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(offscreenContext);
layer.contents = CFBridgingRelease(imageRef);
CGContextRelease(offscreenContext);
[self.animationView.layer addSublayer:layer];
}
}
}
return self.animationView;
}
- (void)lancinateAnimationView:(UIView *)view horizontalscale:(CGFloat)sublayerH animationScaleRatio:(CGFloat)scaleRatio animationDuration:(CGFloat)duration repeatCount:(NSInteger)conut isRemoveMask:(BOOL)isRemove completeBlock:(completeBlock)completeBlock{
[self lancinateAnimationView:view size:CGSizeMake(view.bounds.size.width, sublayerH)];
CGFloat ratio = scaleRatio * 2.0 /(self.animationView.layer.sublayers.count *0.01);
CGFloat baseValue = [self getRandRangeFloutValue:scaleRatio];
[self doLancinateAnimationKeyPath:@"transform.scale.x" ratio:ratio scaleRatio:(CGFloat)scaleRatio baseValue:baseValue duration:duration repeatCount:conut isRemoveMask:isRemove completeBlock:completeBlock];
}
- (void)lancinateAnimationView:(UIView *)view verticalScale:(CGFloat)sublayerW animationScaleRatio:(CGFloat)scaleRatio animationDuration:(CGFloat)duration repeatCount:(NSInteger)conut isRemoveMask:(BOOL)isRemove completeBlock:(completeBlock)completeBlock{
[self lancinateAnimationView:view size:CGSizeMake(sublayerW, view.bounds.size.height)];
CGFloat baseValue = [self getRandRangeFloutValue:scaleRatio];
CGFloat ratio = scaleRatio * 2.0 /(self.animationView.layer.sublayers.count *0.03);
[self doLancinateAnimationKeyPath:@"transform.scale.y" ratio:ratio scaleRatio:(CGFloat)scaleRatio baseValue:baseValue duration:duration repeatCount:conut isRemoveMask:isRemove completeBlock:completeBlock];
}
- (void)doLancinateAnimationKeyPath:(NSString *)key ratio:(CGFloat)ratio scaleRatio:(CGFloat)scaleRatio baseValue:(CGFloat)baseValue duration:(CGFloat)duration repeatCount:(NSInteger)conut isRemoveMask:(BOOL)isRemove completeBlock:(completeBlock)completeBlock{
for (CALayer *shape in self.animationView.layer.sublayers) {
@autoreleasepool {
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:key];
scaleAnimation.fromValue = @(1.0);
CGFloat resultValue = [self getRandFloutRadioValue:ratio baseValue:baseValue limitValue:scaleRatio];
baseValue = resultValue;
scaleAnimation.toValue = @(resultValue + 1.0);
scaleAnimation.duration = duration;
scaleAnimation.repeatCount = conut;
[shape addAnimation:scaleAnimation forKey:@"lancinateAnimationX"];
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (isRemove) {
[self.animationView removeFromSuperview];
self.animationView = nil;
}
if (completeBlock) {
completeBlock();
}
});
}
- (CGFloat)getRandRangeFloutValue:(CGFloat)rangeValue{
return (float)random()/(float)RAND_MAX *rangeValue *2.0 - rangeValue;;
}
- (CGFloat)getRandFloutRadioValue:(CGFloat)radioValue baseValue:(CGFloat)baseValue limitValue:(CGFloat)limitValue{
CGFloat randGradualValue = [self getRandRangeFloutValue:radioValue];
CGFloat result = baseValue + randGradualValue;
while (fabs(result) >= limitValue) {
randGradualValue = [self getRandRangeFloutValue:radioValue];
result = baseValue + randGradualValue;
}
return result;
}
- (void)lancinateAnimateDefaultModeView:(UIView *)view completeBlock:(completeBlock)completeBlock{
if (self.isAlreadlyStartAnimating) {
return;
}
self.isAlreadlyStartAnimating = YES;
CGFloat horizonScale = 2.0;
CGFloat verticalScale = 2.0;
CGFloat animationTime = 0.4;
CGFloat horizonScaleRatio = 0.048;
CGFloat verticalScaleRatio = 0.039;
[self lancinateAnimationView:view horizontalscale:horizonScale animationScaleRatio:horizonScaleRatio animationDuration:animationTime repeatCount:1 isRemoveMask:YES completeBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self lancinateAnimationView:view verticalScale:verticalScale animationScaleRatio:verticalScaleRatio animationDuration:animationTime repeatCount:1 isRemoveMask:YES completeBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self lancinateAnimationView:view horizontalscale:horizonScale animationScaleRatio:horizonScaleRatio animationDuration:animationTime repeatCount:1 isRemoveMask:YES completeBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self lancinateAnimationView:view verticalScale:verticalScale animationScaleRatio:verticalScaleRatio animationDuration:animationTime repeatCount:1 isRemoveMask:NO completeBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.isAlreadlyStartAnimating = NO;
if (completeBlock) {
completeBlock();
}
});
}];
});
}];
});
}];
});
}];
}
- (void)removeMaskView{
if (self.animationView) {
[self.animationView removeFromSuperview];
self.animationView = nil;
}
}
/// 视频相关
- (void)playToFullScreen:(NSURL *)videoURL delegate:(id<ZKRBaiWeiAdManagerPlayerDelegate>)delegate{
[self playWithPlayer:videoURL playToView:[UIApplication sharedApplication].keyWindow delegate:delegate];
}
- (void)playWithPlayer:(NSURL *)videoURL playToView:(UIView *)view delegate:(id<ZKRBaiWeiAdManagerPlayerDelegate>)delegate{
if (self.isAlreadlyStartPlaying) {
return;
}
if (!videoURL) {
NSLog(@"videoURL不能为空");
return;
}
if (!view) {
NSLog(@"view不能为空");
return;
}
if (delegate) {
_delegate = delegate;
}
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
self.player = player;
self.palyLayer = [AVPlayerLayer playerLayerWithPlayer:player];
self.palyLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.palyLayer.frame = view.bounds;
UIButton *maskBtn = [UIButton new];
_maskBtn = maskBtn;
[maskBtn addTarget:self action:@selector(touchedVideo) forControlEvents:UIControlEventTouchUpInside];
maskBtn.backgroundColor = [UIColor clearColor];
maskBtn.frame = view.bounds;
[view addSubview:maskBtn];
[view.layer addSublayer:self.palyLayer];
[player play];
self.isAlreadlyStartPlaying = YES;
if (@available(iOS 10.0, *)) {
[player addObserver:self forKeyPath:@"timeControlStatus" options:NSKeyValueObservingOptionNew context:nil];
}
__weak typeof(self)weakSelf = self;
self.listenObj = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) queue:NULL usingBlock:^(CMTime time) {
CGFloat progress = CMTimeGetSeconds(player.currentItem.currentTime) / CMTimeGetSeconds(player.currentItem.duration);
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(player:playProgress:)]) {
[weakSelf.delegate player:weakSelf.player playProgress:progress];
}
if (progress == 1.0f) {
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(playfinish:)]) {
[weakSelf.delegate playfinish:weakSelf.player];
}
}
}];
}
- (void)touchedVideo{
if (_delegate && [_delegate respondsToSelector:@selector(touchInsideVideoLayer:)]) {
[_delegate touchInsideVideoLayer:_player];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if (object == _player && [keyPath isEqualToString:@"timeControlStatus"]) {
AVPlayerTimeControlStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
if (status == AVPlayerTimeControlStatusPaused) {
_status = ZKRBaiWeiAVPlayerStatusPause;
}
if (status == AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate) {
_status = ZKRBaiWeiAVPlayerStatusReadyToPlay;
}
if (status == AVPlayerTimeControlStatusPlaying) {
_status = ZKRBaiWeiAVPlayerStatusPlaying;
}
if (_delegate && [_delegate respondsToSelector:@selector(player:playStatusChanged:)]) {
[_delegate player:_player playStatusChanged:_status];
}
}
}
- (void)playPause{
if (_player) {
[_player pause];
}
}
- (void)removePlayLayer{
[self playPause];
[_palyLayer removeFromSuperlayer];
[_player removeTimeObserver:_listenObj];
_listenObj = nil;
_player = nil;
_palyLayer = nil;
[_maskBtn removeFromSuperview];
_maskBtn = nil;
self.isAlreadlyStartPlaying = NO;
}
@end
网友评论