Ver código fonte

裁剪模块

Chris 5 anos atrás
pai
commit
b1a9a7f85a
12 arquivos alterados com 1322 adições e 3 exclusões
  1. 48 0
      RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj
  2. 1 0
      RainbowPlanet/RainbowPlanet/Macro/RainbowPlanet-Bridging-Header.h
  3. 48 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/Controller/AliyunCropViewController.h
  4. 647 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/Controller/AliyunCropViewController.m
  5. 48 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropThumbnailView.h
  6. 283 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropThumbnailView.m
  7. 36 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropViewBottomView.h
  8. 87 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropViewBottomView.m
  9. 28 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCycleProgressView.h
  10. 84 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCycleProgressView.m
  11. 7 3
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/PublishMediaPicker/Controller/KSMediaPickerController.swift
  12. 5 0
      RainbowPlanet/RainbowPlanet/Modules/PublishModule/PublishViewController.swift

+ 48 - 0
RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj

@@ -410,6 +410,10 @@
 		BD0FAA4F22C474D400DDFB37 /* AliyunCoverPickViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA4E22C474D400DDFB37 /* AliyunCoverPickViewController.m */; };
 		BD0FAA5322C4750A00DDFB37 /* AliyunCoverPickView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA5222C4750A00DDFB37 /* AliyunCoverPickView.m */; };
 		BD0FAA5622C4752C00DDFB37 /* AliyunPublishTopView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA5522C4752C00DDFB37 /* AliyunPublishTopView.m */; };
+		BD0FAA5C22C4C32E00DDFB37 /* AliyunCropViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA5A22C4C32D00DDFB37 /* AliyunCropViewController.m */; };
+		BD0FAA6322C4C35E00DDFB37 /* AliyunCropViewBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA5D22C4C35D00DDFB37 /* AliyunCropViewBottomView.m */; };
+		BD0FAA6422C4C35E00DDFB37 /* AliyunCropThumbnailView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA5F22C4C35D00DDFB37 /* AliyunCropThumbnailView.m */; };
+		BD0FAA6522C4C35E00DDFB37 /* AliyunCycleProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0FAA6122C4C35E00DDFB37 /* AliyunCycleProgressView.m */; };
 		BD108C9322A60C2100837DAB /* HGImageCompleteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C8E22A60C2100837DAB /* HGImageCompleteButton.swift */; };
 		BD108C9422A60C2100837DAB /* HGImageCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C8F22A60C2100837DAB /* HGImageCollectionViewController.swift */; };
 		BD108C9522A60C2100837DAB /* HGImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C9022A60C2100837DAB /* HGImageCollectionViewCell.swift */; };
@@ -1069,6 +1073,14 @@
 		BD0FAA5222C4750A00DDFB37 /* AliyunCoverPickView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunCoverPickView.m; sourceTree = "<group>"; };
 		BD0FAA5422C4752C00DDFB37 /* AliyunPublishTopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AliyunPublishTopView.h; sourceTree = "<group>"; };
 		BD0FAA5522C4752C00DDFB37 /* AliyunPublishTopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunPublishTopView.m; sourceTree = "<group>"; };
+		BD0FAA5A22C4C32D00DDFB37 /* AliyunCropViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunCropViewController.m; sourceTree = "<group>"; };
+		BD0FAA5B22C4C32D00DDFB37 /* AliyunCropViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AliyunCropViewController.h; sourceTree = "<group>"; };
+		BD0FAA5D22C4C35D00DDFB37 /* AliyunCropViewBottomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunCropViewBottomView.m; sourceTree = "<group>"; };
+		BD0FAA5E22C4C35D00DDFB37 /* AliyunCycleProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AliyunCycleProgressView.h; sourceTree = "<group>"; };
+		BD0FAA5F22C4C35D00DDFB37 /* AliyunCropThumbnailView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunCropThumbnailView.m; sourceTree = "<group>"; };
+		BD0FAA6022C4C35E00DDFB37 /* AliyunCropThumbnailView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AliyunCropThumbnailView.h; sourceTree = "<group>"; };
+		BD0FAA6122C4C35E00DDFB37 /* AliyunCycleProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AliyunCycleProgressView.m; sourceTree = "<group>"; };
+		BD0FAA6222C4C35E00DDFB37 /* AliyunCropViewBottomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AliyunCropViewBottomView.h; sourceTree = "<group>"; };
 		BD108C8E22A60C2100837DAB /* HGImageCompleteButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCompleteButton.swift; sourceTree = "<group>"; };
 		BD108C8F22A60C2100837DAB /* HGImageCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCollectionViewController.swift; sourceTree = "<group>"; };
 		BD108C9022A60C2100837DAB /* HGImageCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCollectionViewCell.swift; sourceTree = "<group>"; };
@@ -4181,6 +4193,37 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		BD0FAA5722C4C2E400DDFB37 /* VideoCrop */ = {
+			isa = PBXGroup;
+			children = (
+				BD0FAA5922C4C31D00DDFB37 /* Controller */,
+				BD0FAA5822C4C31600DDFB37 /* View */,
+			);
+			path = VideoCrop;
+			sourceTree = "<group>";
+		};
+		BD0FAA5822C4C31600DDFB37 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BD0FAA6022C4C35E00DDFB37 /* AliyunCropThumbnailView.h */,
+				BD0FAA5F22C4C35D00DDFB37 /* AliyunCropThumbnailView.m */,
+				BD0FAA6222C4C35E00DDFB37 /* AliyunCropViewBottomView.h */,
+				BD0FAA5D22C4C35D00DDFB37 /* AliyunCropViewBottomView.m */,
+				BD0FAA5E22C4C35D00DDFB37 /* AliyunCycleProgressView.h */,
+				BD0FAA6122C4C35E00DDFB37 /* AliyunCycleProgressView.m */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		BD0FAA5922C4C31D00DDFB37 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BD0FAA5B22C4C32D00DDFB37 /* AliyunCropViewController.h */,
+				BD0FAA5A22C4C32D00DDFB37 /* AliyunCropViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
 		BD108C8D22A60A2000837DAB /* HGImagePicker */ = {
 			isa = PBXGroup;
 			children = (
@@ -5025,6 +5068,7 @@
 			children = (
 				BD61225022C31EED00D3F513 /* VideoRecord */,
 				BD61224F22C31EE400D3F513 /* VideoEdit */,
+				BD0FAA5722C4C2E400DDFB37 /* VideoCrop */,
 				BD0FAA4B22C474A500DDFB37 /* VideoCoverPick */,
 				BD61226222C3592C00D3F513 /* Common */,
 			);
@@ -5599,6 +5643,7 @@
 				A7D5F25A22C05D1400F8E9AF /* SwiftMoyaServiceCommunityApi.swift in Sources */,
 				A7CC75332271ABB0003C4F38 /* AddressManagerViewController.swift in Sources */,
 				A7FF158C228C911C00A85748 /* OrderRefunddetailsViewController.swift in Sources */,
+				BD0FAA6322C4C35E00DDFB37 /* AliyunCropViewBottomView.m in Sources */,
 				BD12B67D22B4EE6D00AEB10B /* KSMediaPickerItemModel.swift in Sources */,
 				A7F2D6DD22B2536F0093000B /* CardContentPicVideoCollectionViewCell.swift in Sources */,
 				A72623D922C2F8B100AEF875 /* MessageHomeOneCollectionViewCell.swift in Sources */,
@@ -5705,6 +5750,7 @@
 				A72A72D522321E2700B21995 /* ColorMacro.swift in Sources */,
 				A72A7333223256E100B21995 /* PayManager.swift in Sources */,
 				A70B2C6722887B2B00B2449F /* ProductDetailEvaluationListTableViewCell.swift in Sources */,
+				BD0FAA5C22C4C32E00DDFB37 /* AliyunCropViewController.m in Sources */,
 				BD13B6D922BA03BC008BB323 /* PublishShareBottomView.swift in Sources */,
 				BD1DC6CD228D160D00B89C57 /* OrderPurchaseModel.swift in Sources */,
 				A775CC00223774A300EBDCF8 /* ShoppingMallView.swift in Sources */,
@@ -5995,6 +6041,7 @@
 				A7284440224DFACD00F82F30 /* InfoModel.swift in Sources */,
 				A72A72B522321DE000B21995 /* Extension+UITextView.swift in Sources */,
 				BD6122FD22C36B0F00D3F513 /* AlivcBaseViewController.m in Sources */,
+				BD0FAA6522C4C35E00DDFB37 /* AliyunCycleProgressView.m in Sources */,
 				BDF47D822282B3D100941AB9 /* ShoppingCartHotSaleTableViewCell.swift in Sources */,
 				A7D5F22922BB686200F8E9AF /* BaseJSWebBaseViewController.swift in Sources */,
 				BD20F1CB2283C12000677D8E /* ShoppingCartListNoneItemCell.swift in Sources */,
@@ -6028,6 +6075,7 @@
 				A7778CDD2246121500C7C47A /* PhoneCountryAreaListMdoel.swift in Sources */,
 				A72A733522325A4B00B21995 /* AppDelegate+HandleOpen.swift in Sources */,
 				A7FF156E228C6EAE00A85748 /* OrderDeliveryModeTableViewCell.swift in Sources */,
+				BD0FAA6422C4C35E00DDFB37 /* AliyunCropThumbnailView.m in Sources */,
 				BD61230622C36C6900D3F513 /* AlivcPushBeautyParams.m in Sources */,
 				A72A72AC22321DE000B21995 /* Regex.swift in Sources */,
 				BD12B67422B4EC9700AEB10B /* KSMediaPickerController.swift in Sources */,

+ 1 - 0
RainbowPlanet/RainbowPlanet/Macro/RainbowPlanet-Bridging-Header.h

@@ -69,6 +69,7 @@
 
 
 #import "AliyunMagicCameraViewController.h"
+#import "AliyunCropViewController.h"
 #import "AliyunCoverPickViewController.h"
 
 

+ 48 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/Controller/AliyunCropViewController.h

@@ -0,0 +1,48 @@
+//
+//  AliyunCropViewController.h
+//  AliyunVideo
+//
+//  Created by dangshuai on 17/1/13.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "AliyunMediaConfig.h"
+
+@protocol AliyunCropViewControllerDelegate;
+@interface AliyunCropViewController : UIViewController
+
+/**
+ 视频配置
+ */
+@property (nonatomic, strong) AliyunMediaConfig *cutInfo;
+
+/**
+ 代理
+ */
+@property (nonatomic, weak) id<AliyunCropViewControllerDelegate> delegate;
+
+/**
+ 假裁剪,获取裁剪时间段,不真正裁剪视频
+ */
+@property (nonatomic, assign) BOOL fakeCrop;
+@end
+
+
+@protocol AliyunCropViewControllerDelegate <NSObject>
+
+/**
+ 退出了裁剪界面
+ */
+- (void)cropViewControllerExit;
+
+/**
+ 裁剪完成
+
+ @param mediaInfo 裁剪配置
+ @param controller 裁剪的试图控制器
+ */
+- (void)cropViewControllerFinish:(AliyunMediaConfig *)mediaInfo viewController:(UIViewController *)controller;
+
+
+@end

+ 647 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/Controller/AliyunCropViewController.m

@@ -0,0 +1,647 @@
+//
+//  AliyunCropViewController.m
+//  AliyunVideo
+//
+//  Created by dangshuai on 17/1/13.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import "AliyunCropViewController.h"
+#import <AVFoundation/AVFoundation.h>
+#import "AVAsset+VideoInfo.h"
+#import <AliyunVideoSDKPro/AliyunCrop.h>
+#import <AliyunVideoSDKPro/AliyunImageCrop.h>
+#import <AliyunVideoSDKPro/AliyunErrorCode.h>
+#import "AliyunCropThumbnailView.h"
+#import "AliyunCycleProgressView.h"
+#import "AliyunCropViewBottomView.h"
+#import "AliyunPathManager.h"
+#import "AVC_ShortVideo_Config.h"
+#import "MBProgressHUD+AlivcHelper.h"
+#import "AlivcMacro.h"
+
+static NSString *const PlayerItemStatus = @"_playerItem.status";
+
+typedef NS_ENUM(NSInteger, AliyunCropPlayerStatus) {
+    AliyunCropPlayerStatusPause,             // 结束或暂停
+    AliyunCropPlayerStatusPlaying,           // 播放中
+    AliyunCropPlayerStatusPlayingBeforeSeek  // 拖动之前是播放状态
+};
+
+
+@interface AliyunCropViewController ()<UIScrollViewDelegate, AliyunCropDelegate>
+
+@property (nonatomic, strong) UIScrollView *previewScrollView;
+@property (nonatomic, strong) AliyunCropThumbnailView *thumbnailView;
+@property (nonatomic, strong) AliyunCropViewBottomView *bottomView;
+@property (nonatomic, strong) UIAlertView *alertView;
+@property (nonatomic, strong) AliyunCycleProgressView *progressView;
+
+@property (nonatomic, assign) CGFloat previewHeight;
+@property (nonatomic, assign) CGFloat previewWidth;
+@property (nonatomic, assign) CGPoint preViewOffset;
+
+@property (nonatomic, strong) AVAsset *avAsset;
+@property (nonatomic, strong) AVPlayerItem *playerItem;
+@property (nonatomic, strong) AVPlayer *avPlayer;
+@property (nonatomic, strong) AVPlayerLayer *avPlayerLayer;
+@property (nonatomic, strong) id timeObserver;
+@property (nonatomic, assign) CMTime currentTime;
+
+@property (nonatomic, assign) CGFloat destRatio;
+@property (nonatomic, assign) CGFloat orgVideoRatio;
+@property (nonatomic, assign) CGSize originalMediaSize;
+
+@property (nonatomic, strong) AliyunCrop *cutPanel;
+@property (nonatomic, assign) BOOL shouldStartCut;
+@property (nonatomic, assign) BOOL hasError;
+@property (nonatomic, assign) BOOL isCancel;
+@property (nonatomic, assign) AliyunCropPlayerStatus playerStatus;
+@property (nonatomic, assign) AliyunMediaCutMode cutMode;
+
+@property (nonatomic, assign) BOOL KVOHasRemoved;
+
+@property (nonatomic, strong) CALayer *stillImageLayer;
+@property (nonatomic, strong) UIImage *stillImage;
+
+
+@end
+
+@implementation AliyunCropViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    _cutMode = _cutInfo.cutMode;
+    if (!_cutInfo.phAsset) {
+        [self addNotification];
+    }
+    [self setupSubViews];
+    
+    if (_cutInfo.phAsset) {//是图片资源
+        if (_cutInfo.phImage) {
+            _originalMediaSize = CGSizeMake(_cutInfo.phImage.size.width, _cutInfo.phImage.size.height);
+            _destRatio = _cutInfo.outputSize.width / _cutInfo.outputSize.height;
+            _orgVideoRatio = _originalMediaSize.width / _originalMediaSize.height;
+        }else {
+            _originalMediaSize = CGSizeMake(_cutInfo.phAsset.pixelWidth, _cutInfo.phAsset.pixelHeight);
+            _destRatio = _cutInfo.outputSize.width / _cutInfo.outputSize.height;
+            _orgVideoRatio = _originalMediaSize.width / _originalMediaSize.height;
+        }
+        [self setupStillImageLayer];
+    } else {
+        NSURL *sourceURL = [NSURL fileURLWithPath:_cutInfo.sourcePath];
+        _avAsset = [AVAsset assetWithURL:sourceURL];
+        _originalMediaSize = [_avAsset avAssetNaturalSize];
+        _destRatio = _cutInfo.outputSize.width / _cutInfo.outputSize.height;
+        _orgVideoRatio = _originalMediaSize.width / _originalMediaSize.height;
+        [self setAVPlayer];
+        _thumbnailView.avAsset = _avAsset;
+    }
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
+        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
+    }
+}
+// 支持设备自动旋转
+- (BOOL)shouldAutorotate
+{
+    return YES;
+}
+
+// 支持竖屏显示
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations
+{
+    return UIInterfaceOrientationMaskPortrait;
+}
+- (void)setupSubViews {
+    
+    self.view.backgroundColor = [AliyunIConfig config].backgroundColor;
+    self.automaticallyAdjustsScrollViewInsets = NO;
+    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(previewTapGesture)];
+    self.previewScrollView = [[UIScrollView alloc] init];
+    self.previewScrollView.bounces = NO;
+    
+    self.previewScrollView.frame = CGRectMake(0, SafeTop+44, ScreenWidth, SizeHeight(426));
+    self.previewScrollView.backgroundColor = _cutInfo.backgroundColor ? :[UIColor blackColor];
+    self.previewScrollView.delegate = self;
+    [self.view addSubview:self.previewScrollView];
+    [self.previewScrollView addGestureRecognizer:tapGesture];
+    
+    if (!_cutInfo.phAsset) {
+        self.thumbnailView = [[AliyunCropThumbnailView alloc] initWithFrame:CGRectMake(0, ScreenHeight - 40 - ScreenWidth/8.0 - 12 - SafeBottom, ScreenWidth, ScreenWidth / 8 + 12) withCutInfo:_cutInfo];
+        self.thumbnailView.delegate = (id<AliyunCutThumbnailViewDelegate>)self;
+        [self.view addSubview:self.thumbnailView];
+    }
+    
+    self.bottomView = [[AliyunCropViewBottomView alloc] initWithFrame:CGRectMake(0, ScreenHeight - 40 - SafeBottom, ScreenWidth, 40)];
+    self.bottomView.delegate = (id<AliyunCropViewBottomViewDelegate>)self;
+    [self.view addSubview:self.bottomView];
+    
+    if (!_cutInfo.phAsset) {
+        self.progressView = [[AliyunCycleProgressView alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
+        self.progressView.backgroundColor = [UIColor clearColor];
+        self.progressView.center = self.view.center;
+        self.progressView.progressColor = RGBToColor(230, 60, 91);
+        self.progressView.progressBackgroundColor = RGBToColor(160, 168, 183);
+        [self.view addSubview:self.progressView];
+    }
+}
+
+- (void)setAVPlayer {
+    _playerItem = [AVPlayerItem playerItemWithAsset:_avAsset];
+    [self addObserver:self forKeyPath:PlayerItemStatus options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
+    _avPlayer = [AVPlayer playerWithPlayerItem:_playerItem];
+    _avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_avPlayer];
+    [_previewScrollView.layer addSublayer:_avPlayerLayer];
+}
+
+- (void)setupStillImageLayer {
+    _stillImageLayer = [CALayer layer];
+    [_previewScrollView.layer addSublayer:_stillImageLayer];
+    if (_cutInfo.phImage) {
+        _stillImage = _cutInfo.phImage;
+        _stillImageLayer.contents =  (__bridge id _Nullable)(_stillImage.CGImage);
+    }else {
+        PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
+        requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
+        requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
+        requestOptions.synchronous = YES;
+        requestOptions.networkAccessAllowed = YES;//打开网络获取iCloud的图片的功能
+        [[PHImageManager defaultManager] requestImageForAsset:_cutInfo.phAsset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
+            if (result.imageOrientation == UIImageOrientationUp)  { //fix:iOS8下图片会旋转的问题
+                _stillImage = result;
+                _stillImageLayer.contents = (__bridge id _Nullable)(result.CGImage);
+            } else {
+                UIGraphicsBeginImageContextWithOptions(result.size, NO, result.scale);
+                [result drawInRect:(CGRect){0, 0, result.size}];
+                UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
+                UIGraphicsEndImageContext();
+                _stillImage = normalizedImage;
+                _stillImageLayer.contents = (__bridge id _Nullable)(normalizedImage.CGImage);
+            }
+        }];
+    }
+    
+}
+
+- (void)destoryAVPlayer {
+    if (self.avPlayer) {
+        self.avPlayer = nil;
+        self.avPlayerLayer = nil;
+    }
+}
+
+- (void)viewDidLayoutSubviews {
+    [super viewDidLayoutSubviews];
+    
+    [self cropViewFitRect];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+}
+
+- (void)cropViewFitRect {
+    
+    _previewHeight = ScreenWidth / _destRatio;
+    
+    CGRect frame = _previewScrollView.frame;
+    frame.size.height = _previewHeight;
+    if (_destRatio == 9.0/16.0) {
+        frame.origin.y = SafeTop;
+    }
+    _previewScrollView.frame = frame;
+    _previewScrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
+    if (_cutInfo.cutMode == AliyunMediaCutModeScaleAspectCut) {
+        
+        [self.bottomView.ratioButton setImage:[AliyunImage imageNamed:@"cut_ratio"] forState:0];
+        [self fitModeCut];
+    } else {
+        
+        [self.bottomView.ratioButton setImage:[AliyunImage imageNamed:@"normal"] forState:0];
+        [self fitModeFill];
+    }
+}
+
+- (void)fitModeCut {
+    if (_orgVideoRatio > _destRatio) {
+        _previewScrollView.contentSize = CGSizeMake(_previewHeight * _orgVideoRatio, _previewHeight);
+        if (_cutInfo.phAsset) {
+            _stillImageLayer.frame = CGRectMake(0, 0, _previewHeight * _orgVideoRatio, _previewHeight);
+        } else {
+            _avPlayerLayer.frame = CGRectMake(0, 0, _previewHeight * _orgVideoRatio, _previewHeight);
+        }
+        [_previewScrollView setContentOffset:CGPointMake((_previewHeight *_orgVideoRatio - ScreenWidth)/2.0, 0)];
+    } else {
+        _previewScrollView.contentSize = CGSizeMake(ScreenWidth, ScreenWidth / _orgVideoRatio);
+        if (_cutInfo.phAsset) {
+            _stillImageLayer.frame = CGRectMake(0, 0, ScreenWidth, ScreenWidth / _orgVideoRatio);
+        } else {
+            _avPlayerLayer.frame = CGRectMake(0, 0, ScreenWidth, ScreenWidth / _orgVideoRatio);
+        }
+        
+        [_previewScrollView setContentOffset:CGPointMake(0, (ScreenWidth / _orgVideoRatio - _previewHeight) / 2.0)];
+    }
+    _preViewOffset = _previewScrollView.contentOffset;
+}
+
+- (void)fitModeFill {
+    _previewScrollView.contentSize = CGSizeMake(0, 0);
+    
+    if (_cutInfo.phAsset) {
+        
+        if (_orgVideoRatio > _destRatio) {
+            //上下黑
+            CGFloat top = (CGRectGetHeight(_previewScrollView.bounds) - ScreenWidth / _orgVideoRatio) / 2;
+            _stillImageLayer.frame = CGRectMake(0, top, ScreenWidth, ScreenWidth / _orgVideoRatio);
+            
+        } else {
+            //左右黑
+            CGFloat left = (CGRectGetWidth(_previewScrollView.bounds) - CGRectGetHeight(_previewScrollView.bounds) * _orgVideoRatio) / 2;
+            _stillImageLayer.frame = CGRectMake(left, 0, _orgVideoRatio * CGRectGetHeight(_previewScrollView.bounds) , CGRectGetHeight(_previewScrollView.bounds));
+        }
+        
+    } else {
+        _avPlayerLayer.frame = _previewScrollView.bounds;
+    }
+}
+
+- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
+    _preViewOffset = scrollView.contentOffset;
+    if (_shouldStartCut) {
+        [self didStartClip];
+        _shouldStartCut = NO;
+    }
+}
+
+- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
+    _preViewOffset = scrollView.contentOffset;
+}
+
+#pragma mark - AliyunCropDelegate
+
+- (void)cropTaskOnProgress:(float)progress {
+    NSLog(@"~~~~~progress:%@", @(progress));
+    if (_isCancel) {
+        return;
+    } else {
+        self.progressView.progress = progress;
+    }
+}
+
+- (void)cropOnError:(int)error {
+    NSLog(@"~~~~~~~crop error:%@", @(error));
+    //裁剪退后台,sdk会报-314或者-310.这个是正常的,不需要弹窗
+    if (_isCancel || error == -314 || error == -310 || error == ERROR_TRANS_BACKGROUND) {
+        _isCancel = NO;
+    } else {
+        _hasError = YES;
+        NSString *err = [NSString stringWithFormat:@"错误码: %d",error];
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"裁剪失败" message:err delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
+        [alert show];
+        self.thumbnailView.userInteractionEnabled = YES;
+        self.bottomView.cropButton.userInteractionEnabled = YES;
+        self.bottomView.ratioButton.userInteractionEnabled = YES;
+        [self destoryAVPlayer];
+        [self setAVPlayer];
+ 
+    }
+    self.progressView.progress = 0;
+    _bottomView.cropButton.enabled =YES;
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
+    [_cutPanel cancel];
+    _alertView = nil;
+    _hasError = YES;
+}
+
+- (void)cropTaskOnComplete {
+    NSLog(@"TestLog, %@:%@", @"log_crop_complete_time", @([NSDate date].timeIntervalSince1970));
+    self.progressView.progress = 0;
+    if (_isCancel) {
+        _isCancel = NO;
+    } else {
+        [_alertView dismissWithClickedButtonIndex:0 animated:YES];
+        _alertView = nil;
+        if (_hasError) {
+            _hasError = NO;
+            return;
+        }
+        _cutInfo.endTime = _cutInfo.endTime - _cutInfo.startTime;
+        _cutInfo.startTime = 0;
+        if (self.delegate) {
+            [self.delegate cropViewControllerFinish:self.cutInfo viewController:self];
+        }
+    }
+    _bottomView.cropButton.enabled =YES;
+}
+
+- (void)cropTaskOnCancel {
+    self.progressView.progress = 0;
+    _bottomView.cropButton.enabled =YES;
+    _bottomView.ratioButton.enabled = YES;
+    NSLog(@"cancel");
+}
+
+#pragma mark ---
+- (void)photoCrop {
+    AliyunImageCrop *imageCrop = [[AliyunImageCrop alloc] init];
+    imageCrop.originImage = _stillImage;
+    imageCrop.cropMode = (AliyunImageCropMode)_cutInfo.cutMode;
+    imageCrop.outputSize = _cutInfo.outputSize;
+    imageCrop.fillBackgroundColor = _cutInfo.backgroundColor;
+    
+    if (_cutInfo.cutMode == 1) {
+        imageCrop.cropRect = [self configureReservationRect];
+    }
+    
+    UIImage *image = [imageCrop generateImage];
+    
+    self.cutInfo.phImage = image;
+    
+   
+    NSString *tmpPhotoPath = [[[AliyunPathManager compositionRootDir] stringByAppendingPathComponent:[AliyunPathManager randomString] ] stringByAppendingPathExtension:@"jpg"];
+    NSData *imageData = UIImageJPEGRepresentation(image, 1);
+    [imageData writeToFile:tmpPhotoPath atomically:YES];
+    self.cutInfo.sourcePath = tmpPhotoPath;
+    
+    if (self.delegate) {
+        [self.delegate cropViewControllerFinish:self.cutInfo viewController:self];
+    }
+}
+
+- (void)didStartClip {
+    
+    [self pauseVideo];
+    self.thumbnailView.userInteractionEnabled = NO;
+    if (_previewScrollView.isDragging) {
+        _shouldStartCut = YES;
+        return;
+    }
+
+    if (_cutPanel) {
+        [_cutPanel cancel];
+    }
+    _cutPanel = [[AliyunCrop alloc] init];
+    _cutPanel.delegate = (id<AliyunCropDelegate>)self;
+//    _cutPanel.inputPath = tmp32Path;
+//    _cutPanel.outputPath = mp32Path;
+    _cutPanel.inputPath = _cutInfo.sourcePath;
+    _cutPanel.outputPath = _cutInfo.outputPath;
+
+    _cutPanel.outputSize = _cutInfo.outputSize;
+    _cutPanel.fps = _cutInfo.fps;
+    _cutPanel.gop = _cutInfo.gop;
+    _cutPanel.bitrate = _cutInfo.bitrate;
+    _cutPanel.videoQuality = (AliyunVideoQuality)_cutInfo.videoQuality;
+
+    if (_cutInfo.cutMode == 1) {
+        _cutPanel.rect = [self evenRect:[self configureReservationRect]];
+    }
+    _cutPanel.cropMode = (AliyunCropCutMode)_cutInfo.cutMode;
+    
+    _cutPanel.startTime = _cutInfo.startTime;
+    _cutPanel.endTime = _cutInfo.endTime;
+    
+//    _cutPanel.startTime = 0;
+//    _cutPanel.endTime = 5;
+    
+    _cutPanel.fadeDuration = 0;
+    _cutPanel.gop = _cutInfo.gop;
+    _cutPanel.fps = _cutInfo.fps;
+    _cutPanel.videoQuality = (AliyunVideoQuality)_cutInfo.videoQuality;
+    if (_cutInfo.encodeMode == AliyunEncodeModeHardH264) {
+        _cutPanel.encodeMode = 1;
+    }else if (_cutInfo.encodeMode == AliyunEncodeModeSoftFFmpeg) {
+        _cutPanel.encodeMode = 0;
+    }
+    NSLog(@"裁剪编码方式:%d",_cutPanel.encodeMode);
+    _cutPanel.fillBackgroundColor = _cutInfo.backgroundColor;
+    _cutPanel.useHW = _cutInfo.gpuCrop;
+    
+    NSLog(@"TestLog, %@:%@", @"log_crop_start_time", @([NSDate date].timeIntervalSince1970));
+
+    int res =[_cutPanel startCrop];
+    if (res == -100002){
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [MBProgressHUD showWarningMessage:@"当前视频格式不支持" inView:[UIApplication sharedApplication].keyWindow];
+        });
+    }else if (res == -100003){
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [MBProgressHUD showWarningMessage:@"当前视频格式不支持" inView:[UIApplication sharedApplication].keyWindow];
+        });
+    }else if (res <0){
+        _isCancel =NO;
+        [self cropOnError:res];
+    }
+    _isCancel = NO;
+    
+}
+//裁剪必须为偶数
+- (CGRect)evenRect:(CGRect)rect {
+    return CGRectMake((int)rect.origin.x / 2 * 2, (int)rect.origin.y / 2 * 2, (int)rect.size.width / 2 * 2, (int)rect.size.height / 2 * 2);
+}
+
+
+- (CGRect)configureReservationRect {
+    CGFloat x = 0, y = 0, w = 0, h = 0;
+    y = _preViewOffset.y;
+    if (_orgVideoRatio > _destRatio) {
+        if (_preViewOffset.x == 0 || _previewScrollView.contentSize.width == 0 ||_originalMediaSize.width == 0) {
+            x = 0;
+        } else {
+            x = _preViewOffset.x / _previewScrollView.contentSize.width * _originalMediaSize.width;
+        }
+        h = _originalMediaSize.height;
+        w = h * _destRatio;
+    } else {
+        if (_preViewOffset.y == 0 || _previewScrollView.contentSize.height == 0 ||_originalMediaSize.height == 0) {
+            y = 0;
+        } else {
+            y = _preViewOffset.y / _previewScrollView.contentSize.height * _originalMediaSize.height;
+        }
+        w = _originalMediaSize.width;
+        h = _originalMediaSize.width / _destRatio;
+    }
+    if (!y) {
+        y = 0;
+    }
+    return CGRectMake(x, y, w, h);
+}
+
+- (void)didStopCut {
+    _isCancel = YES;
+    self.progressView.progress = 0;
+    self.thumbnailView.userInteractionEnabled = YES;
+    self.bottomView.cropButton.enabled = YES;
+    self.bottomView.ratioButton.enabled = YES;
+    [_cutPanel cancel];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
+    if ([keyPath isEqualToString:PlayerItemStatus]) {
+        AVPlayerItemStatus status = _playerItem.status;
+        if (status == AVPlayerItemStatusReadyToPlay) {
+            _cutInfo.sourceDuration = [_playerItem.asset avAssetVideoTrackDuration];
+            if (_cutInfo.endTime == 0) {
+                _cutInfo.startTime = 0.0;
+                _cutInfo.endTime = _cutInfo.sourceDuration;
+            }
+            _playerStatus = AliyunCropPlayerStatusPlayingBeforeSeek;
+            [self playVideo];
+            [_thumbnailView loadThumbnailData];
+            [self removeObserver:self forKeyPath:PlayerItemStatus];
+            _KVOHasRemoved = YES;
+        }else if (status == AVPlayerItemStatusFailed){
+            NSLog(@"系统播放器无法播放视频=== %@",keyPath);
+        }
+    }
+}
+
+- (void)previewTapGesture {
+    if (_playerStatus == AliyunCropPlayerStatusPlaying) {
+        [self pauseVideo];
+    } else {
+        [self playVideo];
+    }
+}
+
+- (void)playVideo {
+    
+    if (_playerStatus == AliyunCropPlayerStatusPlayingBeforeSeek) {
+        [_avPlayer seekToTime:CMTimeMake(_cutInfo.startTime * 1000, 1000) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
+    }
+    
+    [_avPlayer play];
+    _playerStatus = AliyunCropPlayerStatusPlaying;
+    
+    if (_timeObserver) return;
+    __weak typeof(self) weakSelf = self;
+    _timeObserver = [_avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 10)
+                                                            queue:dispatch_get_main_queue()
+                                                       usingBlock:^(CMTime time) {
+                                                           
+                                                           __strong typeof(self) strong = weakSelf;
+                                                           CGFloat crt = CMTimeGetSeconds(time);
+                                                           
+                                                           if (strong.cutInfo.sourceDuration) {
+                                                               [strong.thumbnailView updateProgressViewWithProgress:crt/strong.cutInfo.sourceDuration];
+                                                           }
+                                                       }];
+}
+
+- (void)pauseVideo {
+    if (_playerStatus == AliyunCropPlayerStatusPlaying) {
+        _playerStatus = AliyunCropPlayerStatusPause;
+        [_avPlayer pause];
+        [_avPlayer removeTimeObserver:_timeObserver];
+        _timeObserver = nil;
+    }
+}
+
+- (void)cutBarDidMovedToTime:(CGFloat)time {
+    if (_playerItem.status == AVPlayerItemStatusReadyToPlay) {
+        [_avPlayer seekToTime:CMTimeMake(time * 1000, 1000) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
+        if (_playerStatus == AliyunCropPlayerStatusPlaying) {
+            [_avPlayer pause];
+            _playerStatus = AliyunCropPlayerStatusPlayingBeforeSeek;
+        }
+    }
+}
+
+- (void)cutBarTouchesDidEnd {
+    _playerItem.forwardPlaybackEndTime = CMTimeMake(_cutInfo.endTime * 1000, 1000);
+    if (_playerStatus == AliyunCropPlayerStatusPlayingBeforeSeek) {
+        [self playVideo];
+    }
+}
+
+- (void)playerItemDidReachEnd:(NSNotification *)notification {
+    [_avPlayer pause];
+    AVPlayerItem *p = [notification object];
+    [p seekToTime:CMTimeMake(_cutInfo.startTime * 1000, 1000) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
+    [_avPlayer play];
+    _playerStatus = AliyunCropPlayerStatusPlaying;
+}
+
+#pragma mark - Notification
+
+- (void)addNotification {
+   
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(applicationDidEnterBackground:)
+                                                 name:UIApplicationWillResignActiveNotification
+                                               object:[UIApplication sharedApplication]];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(applicationDidBecomeActive:)
+                                                 name:UIApplicationWillEnterForegroundNotification object:nil];
+    
+    _avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(playerItemDidReachEnd:)
+                                                 name:AVPlayerItemDidPlayToEndTimeNotification
+                                               object:_avPlayer.currentItem];
+}
+
+- (void)applicationDidEnterBackground:(NSNotification *)notification {
+    NSLog(@"applicationDidEnterBackground");
+    [self didStopCut];
+    [self pauseVideo];
+}
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification {
+    [self playVideo];
+}
+
+#pragma mark - Actions
+- (void)onClickBackButton {
+    [self pauseVideo];
+    [self didStopCut];
+//    [_delegate cropViewControllerExit];
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+- (void)onClickRatioButton {
+    _cutInfo.cutMode = !_cutInfo.cutMode;
+    [self cropViewFitRect];
+}
+
+
+- (void)onClickCropButton {
+    NSLog(@"点击了裁剪按钮");
+    if (_cutInfo.phAsset) {
+        [self photoCrop];
+    } else {
+        [self didStartClip];
+    }
+}
+
+
+- (void)viewWillDisappear:(BOOL)animated {
+    [self pauseVideo];
+    self.cutInfo.cutMode = _cutMode;
+    [super viewWillDisappear:animated];
+}
+
+- (void)dealloc {
+    NSLog(@"dealloc-------->AliyunCropViewController");
+    if (!_cutInfo.phAsset) {
+        if (_timeObserver) {
+            [_avPlayer removeTimeObserver:_timeObserver];
+        }
+        
+        if (!_KVOHasRemoved) {
+            [self removeObserver:self forKeyPath:PlayerItemStatus];
+        }
+        [[NSNotificationCenter defaultCenter] removeObserver:self];
+    }
+    
+}
+
+@end

+ 48 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropThumbnailView.h

@@ -0,0 +1,48 @@
+//
+//  AliyunVideo
+//
+//  Created by dangshuai on 17/1/14.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "AliyunMediaConfig.h"
+
+@class AVAsset;
+@protocol AliyunCutThumbnailViewDelegate <NSObject>
+
+- (void)cutBarDidMovedToTime:(CGFloat)time;
+
+- (void)cutBarTouchesDidEnd;
+@end
+
+@interface AliyunCropThumbnailView : UIView
+
+/**
+ 代理
+ */
+@property (nonatomic, weak) id<AliyunCutThumbnailViewDelegate> delegate;
+
+@property (nonatomic, strong) AVAsset *avAsset;
+
+/**
+ 初始化方法
+
+ @param frame frame
+ @param cutInfo 视频资源
+ @return 实例化对象
+ */
+- (instancetype)initWithFrame:(CGRect)frame withCutInfo:(AliyunMediaConfig *)cutInfo;
+
+/**
+ 加载缩略图资源
+ */
+- (void)loadThumbnailData;
+
+/**
+ 更新进度
+
+ @param progress 进度
+ */
+- (void)updateProgressViewWithProgress:(CGFloat)progress;
+@end

+ 283 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropThumbnailView.m

@@ -0,0 +1,283 @@
+//
+//  AliyunCropThumbnailView.m
+//  AliyunVideo
+//
+//  Created by dangshuai on 17/1/14.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import "AliyunCropThumbnailView.h"
+#import <AVFoundation/AVFoundation.h>
+#import "AliyunMediaConfig.h"
+#import "AVC_ShortVideo_Config.h"
+#import "AlivcMacro.h"
+
+@interface AliyunCropThumbnailView ()
+@property (nonatomic, strong) UICollectionView *collectionView;
+@property (nonatomic, strong) UILabel *durationLabel;
+@property (nonatomic, strong) AVAssetImageGenerator *imageGenerator;
+
+@property (nonatomic, strong) NSMutableArray *imagesArray;
+@property (nonatomic, strong) AliyunMediaConfig *cutInfo;
+@property (nonatomic, strong) UIImageView *imageViewLeft;
+@property (nonatomic, strong) UIImageView *imageViewLeftMask;
+@property (nonatomic, strong) UIImageView *imageViewRight;
+@property (nonatomic, strong) UIImageView *imageViewRightMask;
+@property (nonatomic, strong) UIImageView *imageViewBackground;
+@property (nonatomic, strong) UIImageView *imageViewSelected;
+@property (nonatomic, strong) UIImageView *progressView;
+
+@property (nonatomic, strong) UIImageView *topLineView;
+@property (nonatomic, strong) UIImageView *underLineView;
+
+@property (nonatomic, assign) int imageViewWith;
+@end
+
+@implementation AliyunCropThumbnailView
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder {
+    self = [super initWithCoder:aDecoder];
+    if (self) {
+        
+    }
+    return self;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame withCutInfo:(AliyunMediaConfig *)cutInfo{
+    self = [super initWithFrame:frame];
+    if (self) {
+        _cutInfo = cutInfo;
+        _imagesArray = [NSMutableArray arrayWithCapacity:8];
+        [self setupCollectionView];
+        [self setupSubviews];
+    }
+    return self;
+}
+
+- (void)setupCollectionView {
+    UICollectionViewFlowLayout *followLayout = [[UICollectionViewFlowLayout alloc] init];
+    followLayout.itemSize = CGSizeMake(ScreenWidth / 8.0 , ScreenWidth / 8.0);
+    followLayout.minimumLineSpacing = 0;
+    followLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+    
+    _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 12, ScreenWidth, ScreenWidth / 8.0) collectionViewLayout:followLayout];
+    _collectionView.dataSource = (id<UICollectionViewDataSource>)self;
+    [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
+    [self addSubview:_collectionView];
+}
+
+- (void)setupSubviews {
+    
+    _progressView = [[UIImageView alloc] initWithImage:[AliyunImage imageNamed:@"progress"]];
+    _progressView.bounds = CGRectMake(0, 0, ScreenWidth / 8.0, ScreenWidth / 8.0);
+    _progressView.center = CGPointMake(0, CGRectGetMidY(self.bounds) + 6);
+    [self addSubview:_progressView];
+    
+    _durationLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, ScreenWidth - 200, 12)];
+    _durationLabel.textColor = RGBToColor(240, 84, 135);
+    _durationLabel.textAlignment = 1;
+    _durationLabel.font = [UIFont systemFontOfSize:12];
+    [self addSubview:_durationLabel];
+    
+    _imageViewWith = ScreenWidth / 8.0 * 0.35;
+    _imageViewLeft = [[UIImageView alloc] initWithImage:[AliyunImage imageNamed:@"cut_bar_left"]];
+    _imageViewLeft.frame = CGRectMake(0, 12, _imageViewWith, ScreenWidth / 8.0);
+    _imageViewLeft.userInteractionEnabled = YES;
+    _imageViewRight = [[UIImageView alloc] initWithImage:[AliyunImage imageNamed:@"cut_bar_right"]];
+    _imageViewRight.frame = CGRectMake(ScreenWidth - _imageViewWith, 12, _imageViewWith, ScreenWidth / 8.0);
+    _imageViewRight.userInteractionEnabled = YES;
+    
+    
+    _topLineView = [[UIImageView alloc]initWithFrame:CGRectMake(_imageViewWith - 3 , 12, ScreenWidth - _imageViewWith *2 + 6, 3)];
+    _topLineView.backgroundColor = [AliyunIConfig config].cutTopLineColor;
+    
+    _underLineView = [[UIImageView alloc]initWithFrame:CGRectMake(_imageViewWith - 3, _imageViewLeft.frame.size.height + 12 - 3  , ScreenWidth - _imageViewWith *2 + 6, 3)];
+    _underLineView.backgroundColor = [AliyunIConfig config].cutBottomLineColor;
+    
+    [self addSubview:_topLineView];
+    [self addSubview:_underLineView];
+    
+    [self addSubview:_imageViewLeft];
+    [self addSubview:_imageViewRight];
+    
+
+    _imageViewLeftMask = [[UIImageView alloc]initWithFrame:CGRectMake(0, 12, 0, _imageViewLeft.frame.size.height)];
+    _imageViewRightMask = [[UIImageView alloc]initWithFrame:CGRectMake(CGRectGetMaxX(_imageViewRight.frame), 12, 0, _imageViewLeft.frame.size.height)];
+    
+    _imageViewLeftMask.backgroundColor = [AliyunIConfig config].backgroundColor;
+    _imageViewLeftMask.alpha = 0.8;
+    _imageViewRightMask.backgroundColor = [AliyunIConfig config].backgroundColor;
+    _imageViewRightMask.alpha = 0.8;
+    
+    [self addSubview:_imageViewLeftMask];
+    [self addSubview:_imageViewRightMask];
+
+    _imageViewBackground = [[UIImageView alloc] initWithImage:[AliyunImage imageNamed:@"paster_time_edit_slider_bg"]];
+    _imageViewBackground.frame = CGRectMake(CGRectGetMaxX(_imageViewLeft.frame), CGRectGetMinY(_imageViewLeft.frame), CGRectGetMinX(_imageViewRight.frame) - CGRectGetMaxX(_imageViewLeft.frame), ScreenWidth / 8.0);
+    [self addSubview:_imageViewBackground];
+    
+}
+
+- (void)loadThumbnailData {
+    
+    _durationLabel.text = [NSString stringWithFormat:@"%.2f",_cutInfo.endTime - _cutInfo.startTime];
+    CMTime startTime = kCMTimeZero;
+    NSMutableArray *array = [NSMutableArray array];
+//    CMTime addTime = CMTimeMake(1000,1000);
+    CGFloat d = _cutInfo.sourceDuration / 7.0;
+    int intd = d * 100;
+    float fd = intd / 100.0;
+    CMTime addTime = CMTimeMakeWithSeconds(fd, 1000);
+    
+    CMTime endTime = CMTimeMakeWithSeconds(_cutInfo.sourceDuration, 1000);
+    
+    while (CMTIME_COMPARE_INLINE(startTime, <=, endTime)) {
+        [array addObject:[NSValue valueWithCMTime:startTime]];
+        startTime = CMTimeAdd(startTime, addTime);
+    }
+    
+    // 第一帧取第0.1s   规避有些视频并不是从第0s开始的
+    array[0] = [NSValue valueWithCMTime:CMTimeMakeWithSeconds(0.1, 1000)];
+    
+    __block int index = 0;
+    [self.imageGenerator generateCGImagesAsynchronouslyForTimes:array completionHandler:^(CMTime requestedTime, CGImageRef  _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
+        
+        if (result == AVAssetImageGeneratorSucceeded) {
+            UIImage *img = [[UIImage alloc] initWithCGImage:image];
+            dispatch_sync(dispatch_get_main_queue(), ^{
+                [_imagesArray addObject:img];
+                NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];
+                [_collectionView insertItemsAtIndexPaths:@[indexPath]];
+                index++;
+            });
+        }
+    }];
+}
+
+- (void)updateProgressViewWithProgress:(CGFloat)progress {
+    CGPoint center = _progressView.center;
+    
+    CGFloat newX = progress *ScreenWidth;
+    if (newX < center.x ) {
+        center.x = newX;
+
+        _progressView.center = center;
+    }else{
+        center.x = newX;
+
+        [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
+            _progressView.center = center;
+        } completion:nil];
+    }
+    
+}
+
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+    return _imagesArray.count;
+}
+
+- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
+    UIImage *image = _imagesArray[indexPath.row];
+    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
+    imageView.frame = cell.contentView.bounds;
+    imageView.contentMode = UIViewContentModeScaleAspectFill;
+    imageView.clipsToBounds = YES;
+    [cell.contentView addSubview:imageView];
+    return cell;
+}
+
+- (AVAssetImageGenerator *)imageGenerator {
+    if (!_imageGenerator) {
+        _imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:_avAsset];
+        _imageGenerator.appliesPreferredTrackTransform = YES;
+        _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+        _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+        _imageGenerator.maximumSize = CGSizeMake(320, 320);
+    }
+    return _imageGenerator;
+}
+
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    UITouch *touch = (UITouch *)[touches anyObject];
+    CGPoint point = [touch locationInView:self];
+    CGRect adjustLeftRespondRect = _imageViewLeft.frame;
+    CGRect adjustRightRespondRect = _imageViewRight.frame;
+    if (CGRectContainsPoint(adjustLeftRespondRect, point)) {
+        _imageViewSelected = _imageViewLeft;
+    } else if (CGRectContainsPoint(adjustRightRespondRect, point)) {
+        _imageViewSelected = _imageViewRight;
+    } else {
+        _imageViewSelected = nil;
+    }
+    
+}
+
+- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    if (!_imageViewSelected) return;
+    _progressView.hidden = YES;
+    UITouch *touch = (UITouch *)[touches anyObject];
+    CGPoint lp = [touch locationInView:self];
+    CGPoint pp = [touch previousLocationInView:self];
+    CGFloat offset = lp.x - pp.x;
+    CGFloat time = offset/(ScreenWidth - 2 * _imageViewWith) * _cutInfo.sourceDuration;
+    if (_imageViewSelected == _imageViewLeft) {
+        CGFloat left = _cutInfo.startTime + time;
+        if (0 < left && left < _cutInfo.endTime - _cutInfo.minDuration) {
+            CGRect frame = _imageViewLeft.frame;
+            frame.origin.x += offset;
+            _imageViewLeft.frame = frame;
+            
+            CGRect maskFrame = _imageViewLeftMask.frame;
+            maskFrame.size.width = frame.origin.x;
+            _imageViewLeftMask.frame = maskFrame;
+            
+            _cutInfo.startTime = left;
+            _imageViewBackground.frame = CGRectMake(CGRectGetMaxX(_imageViewLeft.frame), CGRectGetMinY(_imageViewLeft.frame), CGRectGetMinX(_imageViewRight.frame) - CGRectGetMaxX(_imageViewLeft.frame), ScreenWidth / 8.0);
+            _durationLabel.text = [NSString stringWithFormat:@"%.2f",_cutInfo.endTime - _cutInfo.startTime];
+            if ([_delegate respondsToSelector:@selector(cutBarDidMovedToTime:)]) {
+                [_delegate cutBarDidMovedToTime:left];
+            }
+        }
+    } else if (_imageViewSelected == _imageViewRight) {
+        CGFloat right = _cutInfo.endTime + time;
+        if (_cutInfo.startTime + _cutInfo.minDuration < right && right < _cutInfo.sourceDuration) {
+            _cutInfo.endTime = right;
+            CGRect frame = _imageViewRight.frame;
+            frame.origin.x += offset;
+            _imageViewRight.frame = frame;
+            
+            CGRect maskFrame = _imageViewRightMask.frame;
+            maskFrame.origin.x = frame.origin.x + frame.size.width;
+            maskFrame.size.width = ScreenWidth - maskFrame.origin.x;
+            _imageViewRightMask.frame = maskFrame;
+            _imageViewBackground.frame = CGRectMake(CGRectGetMaxX(_imageViewLeft.frame), CGRectGetMinY(_imageViewLeft.frame), CGRectGetMinX(_imageViewRight.frame) - CGRectGetMaxX(_imageViewLeft.frame), ScreenWidth / 8.0);
+            _durationLabel.text = [NSString stringWithFormat:@"%.2f", _cutInfo.endTime - _cutInfo.startTime];
+            if ([_delegate respondsToSelector:@selector(cutBarDidMovedToTime:)]) {
+                [_delegate cutBarDidMovedToTime:right];
+            }
+        }
+    }
+    
+    CGRect upFrame = _topLineView.frame;
+    CGRect downFrame = _underLineView.frame;
+    
+    upFrame.origin.x = CGRectGetMaxX(_imageViewLeft.frame) - 3;
+    downFrame.origin.x = upFrame.origin.x;
+    
+    upFrame.size.width = CGRectGetMinX(_imageViewRight.frame) - CGRectGetMaxX(_imageViewLeft.frame) + 6;
+    downFrame.size.width = upFrame.size.width;
+    
+    _topLineView.frame = upFrame;
+    _underLineView.frame = downFrame;
+}
+
+- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
+    _imageViewSelected = nil;
+    _progressView.hidden = NO;
+    if ([_delegate respondsToSelector:@selector(cutBarTouchesDidEnd)]) {
+        [_delegate cutBarTouchesDidEnd];
+    }
+}
+
+@end

+ 36 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropViewBottomView.h

@@ -0,0 +1,36 @@
+//
+//  AliyunCropViewBottomView.h
+//  AliyunVideo
+//
+//  Created by TripleL on 17/5/4.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@protocol AliyunCropViewBottomViewDelegate <NSObject>
+
+- (void)onClickBackButton;
+- (void)onClickRatioButton;
+- (void)onClickCropButton;
+
+@end
+
+@interface AliyunCropViewBottomView : UIView
+
+/**
+ 裁剪模式切换按钮
+ */
+@property (nonatomic, strong) UIButton *ratioButton;
+
+/**
+ 确定按钮
+ */
+@property (nonatomic, strong) UIButton *cropButton;
+
+/**
+ 代理
+ */
+@property (nonatomic, weak) id<AliyunCropViewBottomViewDelegate> delegate;
+
+@end

+ 87 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCropViewBottomView.m

@@ -0,0 +1,87 @@
+//
+//  AliyunCropViewBottomView.m
+//  AliyunVideo
+//
+//  Created by TripleL on 17/5/4.
+//  Copyright (C) 2010-2017 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import "AliyunCropViewBottomView.h"
+#import "AVC_ShortVideo_Config.h"
+
+@interface AliyunCropViewBottomView ()
+
+@property (nonatomic, strong) UIButton *backButton;
+
+@end
+
+@implementation AliyunCropViewBottomView
+
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        [self setupSubViews];
+    }
+    return self;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self) {
+        [self setupSubViews];
+    }
+    return self;
+}
+
+- (void)setupSubViews {
+    
+    CGFloat height = CGRectGetHeight(self.frame);
+    CGFloat width = CGRectGetWidth(self.frame);
+    self.backButton = [self buttonWithRect:(CGRectMake(0, 0, height, height)) image:[AliyunImage imageNamed:@"cancel"] action:@selector(backButtonAction)];
+    [self addSubview:self.backButton];
+    
+    self.ratioButton = [self buttonWithRect:(CGRectMake(0, 0, height, height)) image:[AliyunImage imageNamed:@"cut_ratio"] action:@selector(ratioButtonAction)];
+    self.ratioButton.center = CGPointMake(width / 2, height / 2);
+    [self addSubview:self.ratioButton];
+    
+    self.cropButton = [self buttonWithRect:(CGRectMake(width - height, 0, height, height)) image:[AliyunImage imageNamed:@"check"] action:@selector(cropButtonAction)];
+    [self addSubview:self.cropButton];
+}
+
+
+- (UIButton *)buttonWithRect:(CGRect)rect image:(UIImage *)image action:(SEL)sel
+{
+    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
+    button.frame = rect;
+    [button setImage:image forState:UIControlStateNormal];
+    [button addTarget:self action:sel forControlEvents:UIControlEventTouchUpInside];
+    [self addSubview:button];
+    return button;
+}
+
+- (void)backButtonAction {
+    
+    if (self.delegate) {
+        [self.delegate onClickBackButton];
+    }
+}
+
+- (void)ratioButtonAction {
+    if (self.delegate) {
+        [self.delegate onClickRatioButton];
+    }
+}
+
+- (void)cropButtonAction {
+    self.cropButton.enabled = NO;
+    self.ratioButton.enabled = NO;
+    if (self.delegate) {
+        [self.delegate onClickCropButton];
+    }
+}
+
+
+@end

+ 28 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCycleProgressView.h

@@ -0,0 +1,28 @@
+//
+//  AliyunCycleProgressView.h
+//  qusdk
+//
+//  Created by TripleL on 17/5/9.
+//  Copyright © 2017年 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface AliyunCycleProgressView : UIView
+
+/**
+ 背景颜色
+ */
+@property (nonatomic, strong) UIColor *progressBackgroundColor;
+
+/**
+ 选中颜色
+ */
+@property (nonatomic, strong) UIColor *progressColor;
+
+/**
+ 选中的区域
+ */
+@property (nonatomic, assign) CGFloat progress;
+
+@end

+ 84 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/AliyunVideo/AlivcShortVideo/ShortVideoFile/VideoCrop/View/AliyunCycleProgressView.m

@@ -0,0 +1,84 @@
+//
+//  AliyunCycleProgressView.m
+//
+//  Created by TripleL on 17/5/9.
+//  Copyright © 2017年 Alibaba Group Holding Limited. All rights reserved.
+//
+
+#import "AliyunCycleProgressView.h"
+
+#define ProgressWidth 3
+#define Radius self.frame.size.width / 2
+
+@interface AliyunCycleProgressView ()
+{
+    
+    CAShapeLayer *arcLayer;
+    UILabel *label;
+    NSTimer *progressTimer;
+}
+@property (nonatomic,assign)CGFloat i;
+
+@end
+
+@implementation AliyunCycleProgressView
+
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        [self setHidden:YES];
+    }
+    return self;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self) {
+        [self setHidden:YES];
+    }
+    return self;
+}
+
+
+- (void)drawRect:(CGRect)rect {
+    
+    int radius = rect.size.height / 2 - 5;
+    int x = rect.origin.x + rect.size.width / 2;
+    int y = rect.origin.y + rect.size.height / 2;
+    
+    // 底层色
+    CGContextRef ctx1 = UIGraphicsGetCurrentContext();
+    [self.progressBackgroundColor set];
+    CGContextSetLineWidth(ctx1, 3);
+    CGContextSetLineCap(ctx1, 1);
+    CGFloat to1 = - M_PI * 0.5 + M_PI * 2 + 0.05;
+    CGContextAddArc(ctx1, x, y, radius, - M_PI * 0.5, to1, 1);
+    CGContextStrokePath(ctx1);
+    
+    // 上层色
+    CGContextRef ctx2 = UIGraphicsGetCurrentContext();
+    [self.progressColor set];
+    CGContextSetLineWidth(ctx2, 3);
+    CGContextSetLineCap(ctx2, 1);
+    CGFloat to2 = - M_PI * 0.5 + (1 - self.progress) * (-M_PI * 2);
+    CGContextAddArc(ctx2, x, y, radius, - M_PI * 0.5, to2, 0);
+    CGContextStrokePath(ctx2);
+}
+
+
+- (void)setProgress:(CGFloat)progress {
+    _progress =progress;
+    [self setNeedsDisplay];
+    if (_progress <= 0) {
+        [self setHidden:YES];
+    } else {
+        [self setHidden:NO];
+    }
+}
+
+
+
+@end

+ 7 - 3
RainbowPlanet/RainbowPlanet/Modules/PublishModule/PublishMediaPicker/Controller/KSMediaPickerController.swift

@@ -28,6 +28,9 @@ open class KSMediaPickerController: UIViewController, UICollectionViewDelegate,
     typealias DismissClosure = () -> Void
     var dismissClosure: DismissClosure?
     
+    typealias CropClosure = (_ vItemMdl: KSMediaPickerItemModel) -> Void
+    var cropClosure: CropClosure?
+    
     @objc public enum mediaType : Int {
         case all        = 0
         case picture    = 1
@@ -161,9 +164,10 @@ open class KSMediaPickerController: UIViewController, UICollectionViewDelegate,
     @objc private func _didClick(nextButton: UIButton) {
         (view as! KSMediaPickerView).previewView.saveCurrentState()
         if _currentSingleType == .video {
-            let cropVc = PublishCutVideoController()
-            cropVc.videoItemModel = _selectedAssetArray.firstObject as? KSMediaPickerItemModel
-            self.navigationController?.pushViewController(cropVc, animated: true)
+            if let cropClosure = self.cropClosure {
+                let vItemModel: KSMediaPickerItemModel = _selectedAssetArray.firstObject as! KSMediaPickerItemModel
+                cropClosure(vItemModel)
+            }
             
         } else {
             print("----图片选择完成,传递_selectedAssetArray")

+ 5 - 0
RainbowPlanet/RainbowPlanet/Modules/PublishModule/PublishViewController.swift

@@ -210,6 +210,11 @@ extension PublishViewController :JXSegmentedListContainerViewDataSource {
                 [weak self] in
                 self?.dismiss(animated: true, completion: nil)
             }
+            mediaVc.cropClosure = {
+                [weak self] (vItemModel) in
+                print("----vItemModel: \(vItemModel)")
+                
+            }
             return mediaVc
         case 1:
             let videoVc = AliyunMagicCameraViewController()