Commit 272712838e6e06d8bbcd70a754049f75dc69264a
1 parent
3416b8a4
提交0.0.20
Showing
2 changed files
with
82 additions
and
72 deletions
CNLiveImagePickerController.podspec
CNLiveImagePickerController/Classes/CNEditVideoController.m
| ... | ... | @@ -125,34 +125,34 @@ |
| 125 | 125 | const CGFloat W = self.width; |
| 126 | 126 | CGFloat minX = 0; |
| 127 | 127 | CGFloat maxX = W; |
| 128 | - | |
| 128 | + | |
| 129 | 129 | switch (pan.view.tag) { |
| 130 | 130 | case 0: { |
| 131 | 131 | //left视图响应 |
| 132 | 132 | maxX = rct.origin.x + rct.size.width - kItemWidth; |
| 133 | - | |
| 133 | + | |
| 134 | 134 | point.x = MAX(minX, MIN(point.x, maxX)); |
| 135 | 135 | point.y = 0; |
| 136 | - | |
| 136 | + | |
| 137 | 137 | rct.size.width -= (point.x - rct.origin.x); |
| 138 | 138 | rct.origin.x = point.x; |
| 139 | 139 | } |
| 140 | 140 | break; |
| 141 | - | |
| 141 | + | |
| 142 | 142 | case 1: |
| 143 | 143 | { |
| 144 | 144 | //right视图响应 |
| 145 | 145 | minX = rct.origin.x + kItemWidth/2; |
| 146 | 146 | maxX = W - kItemWidth/2; |
| 147 | - | |
| 147 | + | |
| 148 | 148 | point.x = MAX(minX, MIN(point.x, maxX)); |
| 149 | 149 | point.y = 0; |
| 150 | - | |
| 150 | + | |
| 151 | 151 | rct.size.width = (point.x - rct.origin.x + kItemWidth/2); |
| 152 | 152 | } |
| 153 | 153 | break; |
| 154 | 154 | } |
| 155 | - | |
| 155 | + | |
| 156 | 156 | switch (pan.state) { |
| 157 | 157 | case UIGestureRecognizerStateBegan: |
| 158 | 158 | case UIGestureRecognizerStateChanged: |
| ... | ... | @@ -160,7 +160,7 @@ |
| 160 | 160 | [self.delegate editViewValidRectChanged];//滑动响应实现 |
| 161 | 161 | } |
| 162 | 162 | break; |
| 163 | - | |
| 163 | + | |
| 164 | 164 | case UIGestureRecognizerStateEnded: |
| 165 | 165 | case UIGestureRecognizerStateCancelled: |
| 166 | 166 | self.layer.borderColor = [UIColor clearColor].CGColor; |
| ... | ... | @@ -168,12 +168,12 @@ |
| 168 | 168 | [self.delegate editViewValidRectEndChanged];//滑动结束响应实现 |
| 169 | 169 | } |
| 170 | 170 | break; |
| 171 | - | |
| 171 | + | |
| 172 | 172 | default: |
| 173 | 173 | break; |
| 174 | 174 | } |
| 175 | - | |
| 176 | - | |
| 175 | + | |
| 176 | + | |
| 177 | 177 | |
| 178 | 178 | self.validRect = rct; |
| 179 | 179 | } |
| ... | ... | @@ -252,7 +252,7 @@ |
| 252 | 252 | [_queue cancelAllOperations]; |
| 253 | 253 | [self stopTimer]; |
| 254 | 254 | [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 255 | -// NSLog(@"---- %s", __FUNCTION__); | |
| 255 | + // NSLog(@"---- %s", __FUNCTION__); | |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | - (AVAssetImageGenerator *)generator |
| ... | ... | @@ -300,29 +300,29 @@ |
| 300 | 300 | - (void)viewDidLayoutSubviews |
| 301 | 301 | { |
| 302 | 302 | [super viewDidLayoutSubviews]; |
| 303 | - | |
| 303 | + | |
| 304 | 304 | UIEdgeInsets inset = UIEdgeInsetsZero; |
| 305 | 305 | if (@available(iOS 11, *)) { |
| 306 | 306 | inset = self.view.safeAreaInsets; |
| 307 | 307 | } |
| 308 | - | |
| 308 | + | |
| 309 | 309 | self.playerLayer.frame = CGRectMake(15, inset.top>0?inset.top:30, KScreenWidth-30, KScreenHeight-160-inset.bottom); |
| 310 | - | |
| 310 | + | |
| 311 | 311 | self.editView.frame = CGRectMake((KScreenWidth-kItemWidth*10)/2, KScreenHeight-100-inset.bottom, kItemWidth*10, kItemHeight); |
| 312 | 312 | self.editView.validRect = self.editView.bounds; |
| 313 | 313 | self.collectionView.frame = CGRectMake(inset.left, KScreenHeight-100-inset.bottom, KScreenWidth-inset.left-inset.right, kItemHeight); |
| 314 | - | |
| 314 | + | |
| 315 | 315 | CGFloat leftOffset = ((KScreenWidth-kItemWidth*10)/2-inset.left); |
| 316 | 316 | CGFloat rightOffset = ((KScreenWidth-kItemWidth*10)/2-inset.right); |
| 317 | 317 | [self.collectionView setContentInset:UIEdgeInsetsMake(0, leftOffset, 0, rightOffset)]; |
| 318 | 318 | [self.collectionView setContentOffset:CGPointMake(_offsetX-leftOffset, 0)]; |
| 319 | - | |
| 319 | + | |
| 320 | 320 | CGFloat bottomViewH = 44; |
| 321 | 321 | CGFloat bottomBtnH = 30; |
| 322 | 322 | _bottomView.frame = CGRectMake(0, KScreenHeight-bottomViewH-inset.bottom, KScreenWidth, kItemHeight); |
| 323 | 323 | _cancelBtn.frame = CGRectMake(10+inset.left, 7, 60, bottomBtnH); |
| 324 | 324 | _doneBtn.frame = CGRectMake(KScreenWidth-70-inset.right, 7, 60, bottomBtnH); |
| 325 | - | |
| 325 | + | |
| 326 | 326 | |
| 327 | 327 | [self.playerLayer setBackgroundColor:[UIColor clearColor].CGColor]; |
| 328 | 328 | } |
| ... | ... | @@ -380,9 +380,9 @@ |
| 380 | 380 | [self.view addSubview:self.editView]; |
| 381 | 381 | |
| 382 | 382 | _indicatorLine = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2, kItemHeight)]; |
| 383 | - | |
| 383 | + | |
| 384 | 384 | _indicatorLine.backgroundColor = [RGBOF(0x0BBE06) colorWithAlphaComponent:.7]; |
| 385 | - | |
| 385 | + | |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | 388 | - (void)creatBottomView |
| ... | ... | @@ -398,11 +398,11 @@ |
| 398 | 398 | [_cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; |
| 399 | 399 | [_cancelBtn addTarget:self action:@selector(cancelBtn_click) forControlEvents:UIControlEventTouchUpInside]; |
| 400 | 400 | [_bottomView addSubview:_cancelBtn]; |
| 401 | - | |
| 401 | + | |
| 402 | 402 | _doneBtn = [UIButton buttonWithType:UIButtonTypeCustom]; |
| 403 | 403 | [_doneBtn setTitle:@"完成" forState:UIControlStateNormal]; |
| 404 | 404 | [_doneBtn setBackgroundColor:[UIColor clearColor]]; |
| 405 | - | |
| 405 | + | |
| 406 | 406 | [_doneBtn setTitleColor:RGBOF(0x0BBE06) forState:UIControlStateNormal]; |
| 407 | 407 | _doneBtn.titleLabel.font = [UIFont systemFontOfSize:15]; |
| 408 | 408 | _doneBtn.layer.masksToBounds = YES; |
| ... | ... | @@ -468,9 +468,9 @@ |
| 468 | 468 | AVAsset *videoAsset = [AVURLAsset assetWithURL:videoURL]; |
| 469 | 469 | _avAsset = videoAsset ; |
| 470 | 470 | [self.collectionView reloadData]; |
| 471 | - | |
| 471 | + | |
| 472 | 472 | } |
| 473 | - | |
| 473 | + | |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | #pragma mark - action |
| ... | ... | @@ -504,7 +504,7 @@ |
| 504 | 504 | { |
| 505 | 505 | [self stopTimer]; |
| 506 | 506 | |
| 507 | - | |
| 507 | + | |
| 508 | 508 | |
| 509 | 509 | TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController; |
| 510 | 510 | [_tzImagePickerVc showProgressHUD]; |
| ... | ... | @@ -548,7 +548,7 @@ |
| 548 | 548 | self->_cancelBtn.enabled = YES; |
| 549 | 549 | }); |
| 550 | 550 | } |
| 551 | - | |
| 551 | + | |
| 552 | 552 | }]; |
| 553 | 553 | } |
| 554 | 554 | #pragma mark - 截取视频 |
| ... | ... | @@ -609,7 +609,7 @@ |
| 609 | 609 | if (error) { |
| 610 | 610 | NSLog(@"保存视频出错:%@",error.localizedDescription); |
| 611 | 611 | if (completion) { |
| 612 | - completion(NO,nil); | |
| 612 | + completion(NO,nil); | |
| 613 | 613 | } |
| 614 | 614 | } else { |
| 615 | 615 | [assetLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { |
| ... | ... | @@ -631,7 +631,7 @@ |
| 631 | 631 | }]; |
| 632 | 632 | |
| 633 | 633 | } |
| 634 | - | |
| 634 | + | |
| 635 | 635 | } |
| 636 | 636 | |
| 637 | 637 | - (PHAsset *)getAssetFromlocalIdentifier:(NSString *)localIdentifier{ |
| ... | ... | @@ -961,44 +961,54 @@ static const char _CNOperationCellKey; |
| 961 | 961 | return; |
| 962 | 962 | } |
| 963 | 963 | |
| 964 | - NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ | |
| 965 | - NSInteger row = indexPath.row; | |
| 966 | - NSInteger i = row * _interval; | |
| 967 | - | |
| 968 | - CMTime time = CMTimeMake((i+0.35) * _avAsset.duration.timescale, _avAsset.duration.timescale); | |
| 969 | - | |
| 970 | - NSError *error = nil; | |
| 971 | - CGImageRef cgImg = [self.generator copyCGImageAtTime:time actualTime:NULL error:&error]; | |
| 972 | - if (!error && cgImg) { | |
| 973 | - UIImage *image = [UIImage imageWithCGImage:cgImg]; | |
| 974 | - CGImageRelease(cgImg); | |
| 975 | - if (image) { | |
| 976 | - [_imageCache setValue:image forKey:@(row).stringValue]; | |
| 977 | - } | |
| 978 | - | |
| 979 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 980 | - | |
| 981 | - NSIndexPath *nowIndexPath = [collectionView indexPathForCell:cell]; | |
| 982 | - if (row == nowIndexPath.row) { | |
| 983 | - if (image) { | |
| 984 | - [(CNEditVideoCell *)cell imageView].image = image; | |
| 985 | - } | |
| 964 | + @try { | |
| 965 | + NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ | |
| 966 | + NSInteger row = indexPath.row; | |
| 967 | + NSInteger i = row * self->_interval; | |
| 968 | + | |
| 969 | + CMTime time = CMTimeMake((i+0.35) * self->_avAsset.duration.timescale, self->_avAsset.duration.timescale); | |
| 970 | + | |
| 971 | + | |
| 972 | + NSError *error = nil; | |
| 973 | + CGImageRef cgImg = [self.generator copyCGImageAtTime:time actualTime:NULL error:&error]; | |
| 974 | + if (!error && cgImg) { | |
| 975 | + UIImage *image = [UIImage imageWithCGImage:cgImg]; | |
| 976 | + CGImageRelease(cgImg); | |
| 977 | + if (image) { | |
| 978 | + [self->_imageCache setValue:image forKey:@(row).stringValue]; | |
| 979 | + } | |
| 980 | + | |
| 981 | + dispatch_async(dispatch_get_main_queue(), ^{ | |
| 986 | 982 | |
| 987 | - } else { | |
| 988 | - UIImage *cacheImage = _imageCache[@(nowIndexPath.row).stringValue]; | |
| 989 | - if (cacheImage) { | |
| 990 | - [(CNEditVideoCell *)cell imageView].image = cacheImage; | |
| 983 | + NSIndexPath *nowIndexPath = [collectionView indexPathForCell:cell]; | |
| 984 | + if (row == nowIndexPath.row) { | |
| 985 | + if (image) { | |
| 986 | + [(CNEditVideoCell *)cell imageView].image = image; | |
| 987 | + } | |
| 988 | + | |
| 989 | + } else { | |
| 990 | + UIImage *cacheImage = self->_imageCache[@(nowIndexPath.row).stringValue]; | |
| 991 | + if (cacheImage) { | |
| 992 | + [(CNEditVideoCell *)cell imageView].image = cacheImage; | |
| 993 | + } | |
| 991 | 994 | } |
| 992 | - } | |
| 993 | - }); | |
| 994 | - [_opCache removeObjectForKey:@(row).stringValue]; | |
| 995 | - } | |
| 996 | - objc_removeAssociatedObjects(cell); | |
| 997 | - }]; | |
| 998 | - [_queue addOperation:op]; | |
| 999 | - [_opCache setValue:op forKey:@(indexPath.row).stringValue]; | |
| 995 | + }); | |
| 996 | + [self->_opCache removeObjectForKey:@(row).stringValue]; | |
| 997 | + } | |
| 998 | + objc_removeAssociatedObjects(cell); | |
| 999 | + }]; | |
| 1000 | + [_queue addOperation:op]; | |
| 1001 | + [_opCache setValue:op forKey:@(indexPath.row).stringValue]; | |
| 1002 | + | |
| 1003 | + objc_setAssociatedObject(cell, &_CNOperationCellKey, op, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
| 1004 | + | |
| 1005 | + } @catch (NSException *exception) { | |
| 1006 | + NSLog(@"获取视频预加载图片出问题"); | |
| 1007 | + } @finally { | |
| 1008 | + | |
| 1009 | + } | |
| 1010 | + | |
| 1000 | 1011 | |
| 1001 | - objc_setAssociatedObject(cell, &_CNOperationCellKey, op, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
| 1002 | 1012 | } |
| 1003 | 1013 | |
| 1004 | 1014 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath |
| ... | ... | @@ -1017,13 +1027,13 @@ static const char _CNOperationCellKey; |
| 1017 | 1027 | } |
| 1018 | 1028 | |
| 1019 | 1029 | /* |
| 1020 | -#pragma mark - Navigation | |
| 1021 | - | |
| 1022 | -// In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 1023 | -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 1024 | - // Get the new view controller using [segue destinationViewController]. | |
| 1025 | - // Pass the selected object to the new view controller. | |
| 1026 | -} | |
| 1027 | -*/ | |
| 1030 | + #pragma mark - Navigation | |
| 1031 | + | |
| 1032 | + // In a storyboard-based application, you will often want to do a little preparation before navigation | |
| 1033 | + - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | |
| 1034 | + // Get the new view controller using [segue destinationViewController]. | |
| 1035 | + // Pass the selected object to the new view controller. | |
| 1036 | + } | |
| 1037 | + */ | |
| 1028 | 1038 | |
| 1029 | 1039 | @end | ... | ... |