Commit fe93196ed6469bcb793793da1fd9fa97b2f84697

Authored by 梁星国
1 parent 411de330

提交建库

Showing 48 changed files with 110 additions and 3372 deletions
.gitignore
1 -*~ 1 +# OS X
2 .DS_Store 2 .DS_Store
  3 +
  4 +# Xcode
3 build/ 5 build/
4 Products/ 6 Products/
5 -*.xcuserstate  
6 -*.xcworkspace  
7 -xcuserdata  
8 -*.lock  
9 -Pods 7 +*.pbxuser
  8 +!default.pbxuser
  9 +*.mode1v3
  10 +!default.mode1v3
  11 +*.mode2v3
  12 +!default.mode2v3
  13 +*.perspectivev3
  14 +!default.perspectivev3
  15 +xcuserdata/
  16 +*.xccheckout
  17 +profile
  18 +*.moved-aside
  19 +DerivedData
  20 +*.hmap
  21 +*.ipa
  22 +
  23 +# Bundler
  24 +.bundle
  25 +
  26 +# Add this line if you want to avoid checking in source code from Carthage dependencies.
  27 +# Carthage/Checkouts
  28 +
  29 +Carthage/Build
  30 +
  31 +# We recommend against adding the Pods directory to your .gitignore. However
  32 +# you should judge for yourself, the pros and cons are mentioned at:
  33 +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
  34 +#
  35 +# Note: if you ignore the Pods directory, make sure to uncomment
  36 +# `pod install` in .travis.yml
  37 +#
  38 +# Pods/
10 \ No newline at end of file 39 \ No newline at end of file
CNLiveAVCamera.podspec
@@ -8,29 +8,29 @@ @@ -8,29 +8,29 @@
8 8
9 Pod::Spec.new do |s| 9 Pod::Spec.new do |s|
10 s.name = 'CNLiveAVCamera' 10 s.name = 'CNLiveAVCamera'
11 - s.version = '0.1.1'  
12 - s.summary = '常用相机' 11 + s.version = '0.1.0'
  12 + s.summary = 'A short description of CNLiveAVCamera.'
  13 +
  14 +# This description is used to generate tags and improve search results.
  15 +# * Think: What does it do? Why did you write it? What is the focus?
  16 +# * Try to keep it short, snappy and to the point.
  17 +# * Write the description between the DESC delimiters below.
  18 +# * Finally, don't worry about the indent, CocoaPods strips it!
13 19
14 s.description = <<-DESC 20 s.description = <<-DESC
15 TODO: Add long description of the pod here. 21 TODO: Add long description of the pod here.
16 DESC 22 DESC
17 23
18 - s.homepage = 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRepos.git' 24 + s.homepage = 'https://github.com/jyyjkt/CNLiveAVCamera'
19 # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 25 # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
20 s.license = { :type => 'MIT', :file => 'LICENSE' } 26 s.license = { :type => 'MIT', :file => 'LICENSE' }
21 s.author = { 'jyyjkt' => 'jyyjkt@qq.com' } 27 s.author = { 'jyyjkt' => 'jyyjkt@qq.com' }
22 - s.source = { :git => 'http://bj.gitlab.cnlive.com/ios-team/CNLiveAVCamera.git', :tag => s.version.to_s } 28 + s.source = { :git => 'https://github.com/jyyjkt/CNLiveAVCamera.git', :tag => s.version.to_s }
23 # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' 29 # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
24 30
25 - s.ios.deployment_target = '9.0' 31 + s.ios.deployment_target = '8.0'
26 32
27 - s.source_files = 'CNLiveAVCamera/Classes/XFAVCamera/*.{h,m}'  
28 -  
29 - # s.resource_bundles = {  
30 - # 'CNLiveAVCamera' => ['CNLiveAVCamera/Assets/Media.xcassets']  
31 - #}  
32 - s.frameworks = 'UIKit', 'Photos'  
33 - s.dependency 'Masonry', '~> 1.0.2' 33 + s.source_files = 'CNLiveAVCamera/Classes/**/*'
34 34
35 # s.resource_bundles = { 35 # s.resource_bundles = {
36 # 'CNLiveAVCamera' => ['CNLiveAVCamera/Assets/*.png'] 36 # 'CNLiveAVCamera' => ['CNLiveAVCamera/Assets/*.png']
CNLiveAVCamera/Assets/Media.xcassets/Contents.json deleted 100644 → 0
1 -{  
2 - "info" : {  
3 - "version" : 1,  
4 - "author" : "xcode"  
5 - }  
6 -}  
7 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/fb_chongpai.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "fb_chongpai.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "fb_chongpai@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "fb_chongpai@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/fb_chongpai.imageset/fb_chongpai.png deleted 100644 → 0

1.98 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_chongpai.imageset/fb_chongpai@2x.png deleted 100644 → 0

3.38 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_chongpai.imageset/fb_chongpai@3x.png deleted 100644 → 0

4.87 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_quxiaoxia.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "fb_quxiaoxia.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "fb_quxiaoxia@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "fb_quxiaoxia@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/fb_quxiaoxia.imageset/fb_quxiaoxia.png deleted 100644 → 0

1.26 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_quxiaoxia.imageset/fb_quxiaoxia@2x.png deleted 100644 → 0

1.68 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_quxiaoxia.imageset/fb_quxiaoxia@3x.png deleted 100644 → 0

1.96 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_wancheng.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "fb_wancheng.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "fb_wancheng@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "fb_wancheng@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/fb_wancheng.imageset/fb_wancheng.png deleted 100644 → 0

1.97 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_wancheng.imageset/fb_wancheng@2x.png deleted 100644 → 0

3.46 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_wancheng.imageset/fb_wancheng@3x.png deleted 100644 → 0

5.08 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_xiangji.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "fb_xiangji.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "fb_xiangji@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "fb_xiangji@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/fb_xiangji.imageset/fb_xiangji.png deleted 100644 → 0

1.32 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_xiangji.imageset/fb_xiangji@2x.png deleted 100644 → 0

1.68 KB

CNLiveAVCamera/Assets/Media.xcassets/fb_xiangji.imageset/fb_xiangji@3x.png deleted 100644 → 0

2.27 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "gz_shoudian.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "gz_shoudian@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "gz_shoudian@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian.imageset/gz_shoudian.png deleted 100644 → 0

1.11 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian.imageset/gz_shoudian@2x.png deleted 100644 → 0

1.29 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian.imageset/gz_shoudian@3x.png deleted 100644 → 0

1.41 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian2.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "filename" : "gz_shoudian2.png",  
6 - "scale" : "1x"  
7 - },  
8 - {  
9 - "idiom" : "universal",  
10 - "filename" : "gz_shoudian2@2x.png",  
11 - "scale" : "2x"  
12 - },  
13 - {  
14 - "idiom" : "universal",  
15 - "filename" : "gz_shoudian2@3x.png",  
16 - "scale" : "3x"  
17 - }  
18 - ],  
19 - "info" : {  
20 - "version" : 1,  
21 - "author" : "xcode"  
22 - }  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian2.imageset/gz_shoudian2.png deleted 100644 → 0

1.13 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian2.imageset/gz_shoudian2@2x.png deleted 100644 → 0

1.34 KB

CNLiveAVCamera/Assets/Media.xcassets/gz_shoudian2.imageset/gz_shoudian2@3x.png deleted 100644 → 0

1.52 KB

CNLiveAVCamera/Assets/Media.xcassets/sight_video_focus.imageset/Contents.json deleted 100644 → 0
1 -{  
2 - "images" : [  
3 - {  
4 - "idiom" : "universal",  
5 - "scale" : "1x"  
6 - },  
7 - {  
8 - "idiom" : "universal",  
9 - "filename" : "sight_video_focus@2x.png",  
10 - "scale" : "2x"  
11 - },  
12 - {  
13 - "idiom" : "universal",  
14 - "filename" : "sight_video_focus@3x.png",  
15 - "scale" : "3x"  
16 - }  
17 - ],  
18 - "info" : {  
19 - "version" : 1,  
20 - "author" : "xcode"  
21 - }  
22 -}  
23 \ No newline at end of file 0 \ No newline at end of file
CNLiveAVCamera/Assets/Media.xcassets/sight_video_focus.imageset/sight_video_focus@2x.png deleted 100644 → 0

3.02 KB

CNLiveAVCamera/Assets/Media.xcassets/sight_video_focus.imageset/sight_video_focus@3x.png deleted 100644 → 0

3.36 KB

CNLiveAVCamera/Classes/ReplaceMe.m 0 → 100644
CNLiveAVCamera/Classes/XFAVCamera/NSBundle+CNLiveXFCamera.h deleted 100644 → 0
1 -//  
2 -// NSBundle+CNLiveXFCamera.h  
3 -// CNLiveAVCamera  
4 -//  
5 -// Created by 梁星国 on 2018/12/8.  
6 -//  
7 -  
8 -#import <Foundation/Foundation.h>  
9 -  
10 -NS_ASSUME_NONNULL_BEGIN  
11 -  
12 -@interface NSBundle (CNLiveXFCamera)  
13 -  
14 -  
15 -/**  
16 - 取得相机包bundle  
17 -  
18 - @return 返回bundle  
19 - */  
20 -+ (NSBundle *)xf_imageBundle;  
21 -  
22 -/**  
23 - 取得Bundle  
24 -  
25 - @param cls 包中类名  
26 - @param package 包  
27 - @param bundleName bundle名  
28 - @return 返回bundle  
29 - */  
30 -+ (NSBundle *)xf_imageBundleWithCls:(id)cls package:(NSString *)package bundleName:(NSString *)bundleName;  
31 -  
32 -@end  
33 -  
34 -NS_ASSUME_NONNULL_END  
35 -  
36 -NS_ASSUME_NONNULL_BEGIN  
37 -  
38 -@interface UIImage (CNLiveXFCamera)  
39 -  
40 -  
41 -/**  
42 - 从bundle中取图片  
43 -  
44 - @param imageName 图片名  
45 - @return 图片  
46 - */  
47 -+ (UIImage *)imageFromBundle:(NSString *)imageName;  
48 -  
49 -@end  
50 -  
51 -NS_ASSUME_NONNULL_END  
CNLiveAVCamera/Classes/XFAVCamera/NSBundle+CNLiveXFCamera.m deleted 100644 → 0
1 -//  
2 -// NSBundle+CNLiveXFCamera.m  
3 -// CNLiveAVCamera  
4 -//  
5 -// Created by 梁星国 on 2018/12/8.  
6 -//  
7 -  
8 -#import "NSBundle+CNLiveXFCamera.h"  
9 -#import "XFCameraController.h"  
10 -  
11 -@implementation NSBundle (CNLiveXFCamera)  
12 -  
13 -/**  
14 - 取得相机包bundle  
15 -  
16 - @return 返回bundle  
17 - */  
18 -+ (NSBundle *)xf_imageBundle {  
19 -  
20 - return [NSBundle xf_imageBundleWithCls:[XFCameraController class] package:@"CNLiveAVCamera.framework" bundleName:@"XFAVCamera"];  
21 -}  
22 -  
23 -  
24 -/**  
25 - 取得Bundle  
26 -  
27 - @param cls 包中类名  
28 - @param package 包  
29 - @param bundleName bundle名  
30 - @return 返回bundle  
31 - */  
32 -+ (NSBundle *)xf_imageBundleWithCls:(id)cls package:(NSString *)package bundleName:(NSString *)bundleName {  
33 -  
34 - NSString *resource = [NSString stringWithFormat:@"%@/%@",package,bundleName];  
35 - NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:@"bundle"];  
36 - if (!path) {  
37 - resource = [NSString stringWithFormat:@"%@",bundleName];  
38 - path = [[NSBundle mainBundle] pathForResource:resource ofType:@"bundle"];  
39 - if (!path) {  
40 - NSBundle *bundle = [NSBundle bundleForClass:[cls class]];  
41 - NSURL *url = [bundle URLForResource:bundleName withExtension:@"bundle"];  
42 - if (url) {  
43 - path = url.path;  
44 - }else {  
45 - path = nil;  
46 - }  
47 - }  
48 - }  
49 - if (path.length <= 0 || !path) {  
50 - return [NSBundle mainBundle];  
51 -  
52 - }else {  
53 - return [NSBundle bundleWithPath:path];  
54 - }  
55 -}  
56 -  
57 -  
58 -  
59 -@end  
60 -  
61 -  
62 -@implementation UIImage (CNLiveXFCamera)  
63 -  
64 -  
65 -/**  
66 - 从bundle中取图片  
67 -  
68 - @param imageName 图片名  
69 - @return 图片  
70 - */  
71 -+ (UIImage *)imageFromBundle:(NSString *)imageName{  
72 -// NSBundle *bundle = [NSBundle xf_imageBundle];  
73 - NSLog(@"进入了取得图片");  
74 -// NSString *path = [[NSBundle mainBundle] pathForResource:@"CNLiveAVCamera.framework/XFAVCamera" ofType:@"bundle"];  
75 -// if (!path) {  
76 -// return [UIImage new];  
77 -// }  
78 -// NSBundle *bundle = [NSBundle bundleWithPath:path];  
79 -// if (!bundle) {  
80 -// NSLog(@"没有bundle");  
81 -// return [UIImage new];  
82 -// }  
83 -// NSString *name = [NSString stringWithFormat:@"%@",imageName];  
84 -// NSLog(@"输出图片name = %@",name);  
85 -// name = [name stringByAppendingString:@"@2x"];  
86 -// NSString *imagePath = [bundle pathForResource:name ofType:@"png"];  
87 -// if (!imagePath) {  
88 -// name = [name stringByReplacingOccurrencesOfString:@"@2x" withString:@"@3x"];  
89 -// imagePath = [bundle pathForResource:name ofType:@"png"];  
90 -// }  
91 -// UIImage *image = [UIImage imageWithContentsOfFile:imagePath];  
92 - return [UIImage new];  
93 -}  
94 -  
95 -  
96 -@end  
CNLiveAVCamera/Classes/XFAVCamera/XFCameraButton.h deleted 100644 → 0
1 -//  
2 -// XFCameraButton.h  
3 -//  
4 -//  
5 -// Created by xf-ling on 2017/6/1.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import <UIKit/UIKit.h>  
10 -  
11 -typedef void(^TapEventBlock)(UITapGestureRecognizer *tapGestureRecognizer);  
12 -typedef void(^LongPressEventBlock)(UILongPressGestureRecognizer *longPressGestureRecognizer);  
13 -  
14 -@interface XFCameraButton : UIView  
15 -  
16 -/**  
17 - * 设置进度条的录制视频时长百分比 = 当前录制时间 / 最大录制时间  
18 - */  
19 -@property (nonatomic, assign) CGFloat progressPercentage;  
20 -  
21 -+ (instancetype)defaultCameraButton;  
22 -  
23 -/**  
24 - * 配置点击事件  
25 - */  
26 -- (void)configureTapCameraButtonEventWithBlock:(TapEventBlock)tapEventBlock;  
27 -  
28 -/**  
29 - * 配置按压事件  
30 - */  
31 -- (void)configureLongPressCameraButtonEventWithBlock:(LongPressEventBlock)longPressEventBlock;  
32 -  
33 -/**  
34 - * 开始录制前的准备动画  
35 - */  
36 -- (void)startShootAnimationWithDuration:(NSTimeInterval)duration;  
37 -  
38 -/**  
39 - * 结束摄影动画  
40 - */  
41 -- (void)stopShootAnimation;  
42 -  
43 -@end  
CNLiveAVCamera/Classes/XFAVCamera/XFCameraButton.m deleted 100644 → 0
1 -//  
2 -// XFCameraButton.m  
3 -//  
4 -//  
5 -// Created by xf-ling on 2017/6/1.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import "XFCameraButton.h"  
10 -  
11 -// 默认按钮大小  
12 -#define CAMERABUTTONWIDTH 75  
13 -#define TOUCHVIEWWIDTH 55  
14 -  
15 -// 录制时按钮的缩放比  
16 -#define SHOOTCAMERABUTTONSCALE 1.6f  
17 -#define SHOOTTOUCHVIEWSCALE 0.5f  
18 -  
19 -// 录制按钮动画轨道宽度  
20 -#define PROGRESSLINEWIDTH 3  
21 -  
22 -#ifndef CAMERA_RGB  
23 -#define CAMERA_RGB(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]  
24 -#endif  
25 -  
26 -@interface XFCameraButton ()  
27 -  
28 -@property (weak, nonatomic) UIView *touchView;  
29 -@property (strong, nonatomic) CAShapeLayer *trackLayer;  
30 -@property (strong, nonatomic) CAShapeLayer *progressLayer;  
31 -  
32 -@property (copy, nonatomic) TapEventBlock tapEventBlock;  
33 -@property (copy, nonatomic) LongPressEventBlock longPressEventBlock;  
34 -  
35 -@end  
36 -  
37 -@implementation XFCameraButton  
38 -  
39 -#pragma mark - 工厂方法  
40 -  
41 -+ (instancetype)defaultCameraButton  
42 -{  
43 - // 设置camera view  
44 - XFCameraButton *cameraButton = [[XFCameraButton alloc] initWithFrame:CGRectMake(0, 0, CAMERABUTTONWIDTH, CAMERABUTTONWIDTH)];  
45 - [cameraButton.layer setCornerRadius:(CAMERABUTTONWIDTH / 2)];  
46 - cameraButton.backgroundColor = [UIColor whiteColor];//[UIColor colorWithRed:225/255.0f green:225/255.0f blue:230/255.0f alpha:1.0f];  
47 -  
48 - // 设置camera view的点击按钮  
49 - CGFloat touchViewX = (CAMERABUTTONWIDTH - TOUCHVIEWWIDTH) / 2;  
50 - CGFloat touchViewY = (CAMERABUTTONWIDTH - TOUCHVIEWWIDTH) / 2;  
51 - UIView *touchView = [[UIView alloc] initWithFrame:CGRectMake(touchViewX, touchViewY, TOUCHVIEWWIDTH, TOUCHVIEWWIDTH)];  
52 - cameraButton.touchView = touchView;  
53 - [cameraButton addSubview:touchView];  
54 - [cameraButton.touchView.layer setCornerRadius:(cameraButton.touchView.bounds.size.width / 2)];  
55 - touchView.backgroundColor = CAMERA_RGB(255, 163, 0, 1);  
56 -  
57 - [cameraButton initCircleAnimationLayer];  
58 -  
59 - return cameraButton;  
60 -}  
61 -  
62 -  
63 -#pragma mark - 点击事件与长按事件  
64 -  
65 -/**  
66 - * 配置点击事件  
67 - */  
68 -- (void)configureTapCameraButtonEventWithBlock:(TapEventBlock)tapEventBlock  
69 -{  
70 - self.tapEventBlock = tapEventBlock;  
71 -  
72 - UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapCameraButtonEvent:)];  
73 -  
74 - [self.touchView addGestureRecognizer:tapGestureRecognizer];  
75 -}  
76 -  
77 -- (void)tapCameraButtonEvent:(UITapGestureRecognizer *)tapGestureRecognizer  
78 -{  
79 - if (self.tapEventBlock)  
80 - {  
81 - self.tapEventBlock(tapGestureRecognizer);  
82 - }  
83 -}  
84 -  
85 -/**  
86 - * 配置按压事件  
87 - */  
88 -- (void)configureLongPressCameraButtonEventWithBlock:(LongPressEventBlock)longPressEventBlock  
89 -{  
90 - self.longPressEventBlock = longPressEventBlock;  
91 -  
92 - UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressCameraButtonEvent:)];  
93 -  
94 - [self.touchView addGestureRecognizer:longPressGestureRecognizer];  
95 -}  
96 -  
97 -- (void)longPressCameraButtonEvent:(UILongPressGestureRecognizer *)longPressGestureRecognizer  
98 -{  
99 - if (self.longPressEventBlock)  
100 - {  
101 - self.longPressEventBlock(longPressGestureRecognizer);  
102 - }  
103 -}  
104 -  
105 -#pragma mark - 录制视频按钮动画  
106 -  
107 -// 初始化按钮路径  
108 -- (void)initCircleAnimationLayer  
109 -{  
110 - float centerX = self.bounds.size.width / 2.0;  
111 - float centerY = self.bounds.size.height / 2.0;  
112 - //半径  
113 - float radius = (self.bounds.size.width - PROGRESSLINEWIDTH) / 2.0;  
114 -  
115 - //创建贝塞尔路径  
116 - UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(centerX, centerY) radius:radius startAngle:(-0.5f * M_PI) endAngle:(1.5f * M_PI) clockwise:YES];  
117 -  
118 - //添加背景圆环  
119 - CAShapeLayer *backLayer = [CAShapeLayer layer];  
120 - backLayer.frame = self.bounds;  
121 - backLayer.fillColor = [[UIColor clearColor] CGColor];  
122 - backLayer.strokeColor = CAMERA_RGB(242, 242, 242,1).CGColor;//[RGB(225, 225, 230, 1.0f) CGColor];  
123 - backLayer.lineWidth = PROGRESSLINEWIDTH;  
124 - backLayer.path = [path CGPath];  
125 - backLayer.strokeEnd = 1;  
126 - [self.layer addSublayer:backLayer];  
127 -  
128 - //创建进度layer  
129 - _progressLayer = [CAShapeLayer layer];  
130 - _progressLayer.frame = self.bounds;  
131 - _progressLayer.fillColor = [[UIColor clearColor] CGColor];  
132 - //指定path的渲染颜色  
133 - _progressLayer.strokeColor = [[UIColor blackColor] CGColor];  
134 - _progressLayer.lineCap = kCALineCapSquare;//kCALineCapRound;  
135 - _progressLayer.lineWidth = PROGRESSLINEWIDTH;  
136 - _progressLayer.path = [path CGPath];  
137 - _progressLayer.strokeEnd = 0;  
138 -  
139 - //设置渐变颜色  
140 - CAGradientLayer *gradientLayer = [CAGradientLayer layer];  
141 - gradientLayer.frame = self.bounds;  
142 -  
143 - // 渐变颜色  
144 - [gradientLayer setColors:[NSArray arrayWithObjects:(id)[CAMERA_RGB(255, 163, 0,1) CGColor], (id)[CAMERA_RGB(255, 163, 0, 1) CGColor], nil]];//RGB(76, 192, 29, 1.0f) [RGB(76, 192, 29, 1.0f) CGColor]  
145 -// [gradientLayer setColors:[NSArray arrayWithObjects:(id)[RGB(28, 178, 29, 1.0f) CGColor], (id)[RGB(255, 203, 0, 1.0f) CGColor], nil]];  
146 -  
147 - gradientLayer.startPoint = CGPointMake(0, 0);  
148 - gradientLayer.endPoint = CGPointMake(0, 1);  
149 - [gradientLayer setMask:_progressLayer]; //用progressLayer来截取渐变层  
150 - [self.layer addSublayer:gradientLayer];  
151 -  
152 -}  
153 -  
154 -// 设置按钮百分比  
155 -- (void)setProgressPercentage:(CGFloat)progressPercentage  
156 -{  
157 - _progressPercentage = progressPercentage;  
158 - _progressLayer.strokeEnd = progressPercentage;  
159 - [_progressLayer removeAllAnimations];  
160 -}  
161 -  
162 -/**  
163 - * 开始录制前的准备动画  
164 - */  
165 -- (void)startShootAnimationWithDuration:(NSTimeInterval)duration  
166 -{  
167 - __weak typeof(self) weakSelf = self;  
168 -  
169 - [UIView animateWithDuration:duration animations:^{  
170 -  
171 - weakSelf.transform = CGAffineTransformMakeScale(SHOOTCAMERABUTTONSCALE, SHOOTCAMERABUTTONSCALE);  
172 - weakSelf.touchView.transform = CGAffineTransformMakeScale(SHOOTTOUCHVIEWSCALE, SHOOTTOUCHVIEWSCALE);  
173 -  
174 - } completion:^(BOOL finished) {  
175 - // nothing  
176 - }];  
177 -}  
178 -  
179 -/**  
180 - * 结束摄影动画  
181 - */  
182 -- (void)stopShootAnimation  
183 -{  
184 - self.transform = CGAffineTransformIdentity;  
185 - self.touchView.transform = CGAffineTransformIdentity;  
186 -}  
187 -  
188 -  
189 -@end  
190 -  
191 -  
192 -  
193 -  
194 -  
195 -  
196 -  
197 -  
198 -  
199 -  
CNLiveAVCamera/Classes/XFAVCamera/XFCameraController.h deleted 100644 → 0
1 -//  
2 -// QXCameraController.h  
3 -//  
4 -//  
5 -// Created by xf-ling on 2017/6/1.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import <UIKit/UIKit.h>  
10 -#import <Photos/Photos.h>  
11 -  
12 -@interface UIControl (CameraEventInterval)  
13 -  
14 -@property (nonatomic, assign) NSTimeInterval camera_cs_acceptEventInterval; // 重复点击的间隔  
15 -  
16 -@property (nonatomic, assign) NSTimeInterval camera_cs_acceptEventTime;  
17 -  
18 -@end  
19 -  
20 -  
21 -typedef void(^TakePhotosCompletionBlock)(UIImage *image, NSError *error);  
22 -typedef void(^ShootCompletionBlock)(NSURL *videoUrl, CGFloat videoTimeLength, UIImage *thumbnailImage, NSError *error);  
23 -  
24 -//zx  
25 -typedef void(^ZXShootCompletionBlock)(PHAsset *asset,NSURL *videoUrl, CGFloat videoTimeLength, UIImage *thumbnailImage, NSError *error);  
26 -  
27 -@interface XFCameraController : UIViewController  
28 -  
29 -/**  
30 - * 拍照完成后的Block回调  
31 - */  
32 -@property (copy, nonatomic) TakePhotosCompletionBlock takePhotosCompletionBlock;  
33 -  
34 -/**  
35 - * 拍摄完成后的Block回调  
36 - */  
37 -@property (copy, nonatomic) ShootCompletionBlock shootCompletionBlock;  
38 -  
39 -/**  
40 - * zx拍摄完成后的Block回调  
41 - */  
42 -@property (copy, nonatomic) ZXShootCompletionBlock zxshootCompletionBlock;  
43 -  
44 -/**  
45 - * 自定义APP相册名字,如果为空则默认为APP的名字  
46 - */  
47 -@property (strong, nonatomic) NSString *assetCollectionName;  
48 -  
49 -/**  
50 - * 视频文件保存文件夹,如果没有定义,默认在document/video文件夹下面  
51 - */  
52 -@property (strong, nonatomic) NSString *videoFilePath;  
53 -  
54 -  
55 -//zx 当前是否可以拍摄视频 BOOL  
56 -@property (nonatomic ,assign) BOOL isCanShootVideo;  
57 -  
58 -//zl__会话ID,用于存储拍摄的视频  
59 -@property (nonatomic ,strong) NSString *conversationId;  
60 -  
61 -@end  
CNLiveAVCamera/Classes/XFAVCamera/XFCameraController.m deleted 100644 → 0
1 -//  
2 -// QXCameraController.m  
3 -//  
4 -//  
5 -// Created by xf-ling on 2017/6/1.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import "XFCameraController.h"  
10 -#import <AVFoundation/AVFoundation.h>  
11 -#import <AssetsLibrary/AssetsLibrary.h>  
12 -#import "XFCameraButton.h"  
13 -#import "XFPhotoLibraryManager.h"  
14 -#import <Photos/Photos.h>  
15 -#import <CoreMotion/CoreMotion.h>  
16 -#import <Masonry/Masonry.h>  
17 -#import <objc/runtime.h>  
18 -#import <UIKit/UIKit.h>  
19 -#import "NSBundle+CNLiveXFCamera.h"  
20 -  
21 -  
22 -#ifndef kCameraScreenWidth  
23 -#define kCameraScreenWidth [UIScreen mainScreen].bounds.size.width  
24 -#endif  
25 -#ifndef kCameraScreenHeight  
26 -#define kCameraScreenHeight [UIScreen mainScreen].bounds.size.height  
27 -#endif  
28 -  
29 -#define SafeViewBottomHeight (kCameraScreenHeight == 812.0 ? 34.0 : 0.0)  
30 -#define VIDEO_FILEPATH @"video"  
31 -#define TIMER_INTERVAL 0.01f //定时器记录视频间隔  
32 -#define VIDEO_RECORDER_MAX_TIME 15.0f //视频最大时长 (单位/秒)  
33 -#define VIDEO_RECORDER_MIN_TIME 2.0f //最短视频时长 (单位/秒)  
34 -#define START_VIDEO_ANIMATION_DURATION 0.3f //录制视频前的动画时间  
35 -  
36 -#define CAMERA_IS_IPhoneX_All (CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(375, 812)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(812, 375)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(414, 896)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(896, 414)))  
37 -  
38 -#define kCameraStatusHeight (int)[UIApplication sharedApplication].statusBarFrame.size.height //x44 非x20  
39 -#define kCameraNavigationBarHeight ((int)[UIApplication sharedApplication].statusBarFrame.size.height+44) //x88 非x64  
40 -#define kCameraVerticalNaviBarHeight ((CAMERA_IS_IPhoneX_All > 0) ? 88 : 44)  
41 -#define kCameraVerticalTabBarTotalHeight ((CAMERA_IS_IPhoneX_All > 0) ? 83 : 49)  
42 -#define kCameraVerticalBottomSafeHeight ((CAMERA_IS_IPhoneX_All > 0) ? 34 : 0)  
43 -#define kCameraVerticalStatusHeight ((CAMERA_IS_IPhoneX_All > 0) ? 44 : 20)  
44 -#define kCameraVerticalTopHeight ((CAMERA_IS_IPhoneX_All > 0) ? 24 : 0)  
45 -#define kCameraHorizontalTopNaviBarHeight 32  
46 -#define kCameraHorizontalBottomHeight ((CAMERA_IS_IPhoneX_All > 0) ? 21 : 0)  
47 -#define kCameraHorizontalLeftHeight ((CAMERA_IS_IPhoneX_All > 0) ? 44 : 0)  
48 -#define kCameraHorizontalRightHeight ((CAMERA_IS_IPhoneX_All > 0) ? 44 : 0)  
49 -#define kCameraHorizontalTopHeight ((CAMERA_IS_IPhoneX_All > 0) ? 24 : 0)  
50 -  
51 -#define CameraImageMake(img) [UIImage imageNamed:img inBundle:nil compatibleWithTraitCollection:nil]  
52 -  
53 -@implementation UIControl (CNEventInterval)  
54 -  
55 -static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";  
56 -- (NSTimeInterval)camera_cs_acceptEventInterval {  
57 - return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];  
58 -}  
59 -  
60 -- (void)setCamera_cs_acceptEventInterval:(NSTimeInterval)camera_cs_acceptEventInterval {  
61 - objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(camera_cs_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
62 -}  
63 -  
64 -static const char *UIControl_acceptEventTime = "UIControl_acceptEventTime";  
65 -  
66 -- (NSTimeInterval)camera_cs_acceptEventTime {  
67 - return [objc_getAssociatedObject(self, UIControl_acceptEventTime) doubleValue];  
68 -}  
69 -  
70 -- (void)setCamera_cs_acceptEventTime:(NSTimeInterval)camera_cs_acceptEventTime {  
71 - objc_setAssociatedObject(self, UIControl_acceptEventTime, @(camera_cs_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
72 -}  
73 -  
74 -  
75 -// 在load时执行hook  
76 -+ (void)load {  
77 - Method before = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));  
78 - Method after = class_getInstanceMethod(self, @selector(cs_sendAction:to:forEvent:));  
79 - method_exchangeImplementations(before, after);  
80 -}  
81 -  
82 -- (void)cs_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {  
83 - if ([NSDate date].timeIntervalSince1970 - self.camera_cs_acceptEventTime < self.camera_cs_acceptEventInterval) {  
84 - return;  
85 - }  
86 - if (self.camera_cs_acceptEventInterval > 0) {  
87 - self.camera_cs_acceptEventTime = [NSDate date].timeIntervalSince1970;  
88 - }  
89 -  
90 - [self cs_sendAction:action to:target forEvent:event];  
91 -}  
92 -  
93 -@end  
94 -  
95 -  
96 -typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);  
97 -  
98 -@interface XFCameraController() <AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate, UIGestureRecognizerDelegate>  
99 -{  
100 - BOOL _isPicOrVideo;//已经拍照或者录制视频标识,进入后台时不dismiss  
101 -}  
102 -@property (nonatomic ,assign) BOOL isAlertShow;  
103 -@property (nonatomic, strong) dispatch_queue_t videoQueue;  
104 -  
105 -@property (strong, nonatomic) AVCaptureSession *captureSession; //负责输入和输出设备之间的数据传递  
106 -  
107 -@property (nonatomic, strong) AVCaptureDeviceInput *videoInput; //视频输入  
108 -@property (nonatomic, strong) AVCaptureDeviceInput *audioInput; //声音输入  
109 -@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput;  
110 -@property (nonatomic, strong) AVCaptureAudioDataOutput *audioOutput;  
111 -  
112 -@property (strong, nonatomic) AVCaptureStillImageOutput *captureStillImageOutput; //照片输出流  
113 -  
114 -@property (nonatomic, strong) AVAssetWriter *assetWriter;  
115 -@property (nonatomic, strong) AVAssetWriterInput *assetWriterVideoInput;  
116 -@property (nonatomic, strong) AVAssetWriterInput *assetWriterAudioInput;  
117 -@property (nonatomic, strong) NSDictionary *videoCompressionSettings;  
118 -@property (nonatomic, strong) NSDictionary *audioCompressionSettings;  
119 -@property (nonatomic, assign) BOOL canWrite;  
120 -  
121 -@property (strong, nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer; //预览图层  
122 -  
123 -@property (nonatomic, strong) NSTimer *timer; //记录录制时间  
124 -  
125 -@property (nonatomic, strong) UIButton *rotateCameraButton;  
126 -@property (nonatomic, strong) UIButton *flashButton;  
127 -@property (nonatomic, strong) UIButton *takeButton; //拍摄按钮  
128 -@property (nonatomic, strong) UIButton *closeButton;  
129 -@property (nonatomic, strong) UILabel *tipLabel;  
130 -@property (strong, nonatomic) XFCameraButton *cameraButton; //拍摄按钮  
131 -  
132 -@property (nonatomic, strong) UIImageView *focusImageView; //聚焦视图  
133 -@property (assign, nonatomic) Boolean isFocusing; //镜头正在聚焦  
134 -@property (assign, nonatomic) Boolean isTakingPhoto; //正在拍摄照片 lxg  
135 -@property (assign, nonatomic) Boolean isShooting; //正在拍摄  
136 -@property (assign, nonatomic) Boolean isRotatingCamera; //正在旋转摄像头  
137 -  
138 -//捏合缩放摄像头  
139 -@property (nonatomic,assign) CGFloat beginGestureScale; //记录开始的缩放比例  
140 -@property (nonatomic,assign) CGFloat effectiveScale; //最后的缩放比例  
141 -  
142 -// 拍照摄像后的预览模块  
143 -@property (nonatomic, strong) UIButton *cancelButton;  
144 -@property (nonatomic, strong) UIButton *confirmButton;  
145 -@property (strong, nonatomic) UIView *photoPreviewContainerView; //相片预览ContainerView  
146 -@property (strong, nonatomic) UIImageView *photoPreviewImageView; //相片预览ImageView  
147 -@property (strong, nonatomic) UIView *videoPreviewContainerView; //视频预览View  
148 -@property (strong, nonatomic) NSURL *videoURL; //视频文件地址  
149 -@property (strong, nonatomic) AVPlayerLayer *playerLayer;  
150 -@property (strong, nonatomic) AVPlayer *player;  
151 -@property (strong, nonatomic) AVPlayerItem *playerItem;  
152 -@property (assign, nonatomic) CGFloat currentVideoTimeLength; //当前小视频总时长  
153 -  
154 -@property (assign, nonatomic) UIDeviceOrientation shootingOrientation; //拍摄中的手机方向  
155 -@property (strong, nonatomic) CMMotionManager *motionManager;  
156 -  
157 -@end  
158 -  
159 -@implementation XFCameraController{  
160 -  
161 - CGFloat timeLength; //时间长度  
162 -  
163 -}  
164 -  
165 -#pragma mark - 控制器方法  
166 -  
167 -- (void)viewDidLoad  
168 -{  
169 - [super viewDidLoad];  
170 - self.view.backgroundColor = [UIColor blackColor];  
171 -  
172 - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enterBackgroundNotification) name:UIApplicationDidEnterBackgroundNotification object:nil];  
173 -  
174 - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];  
175 -  
176 - // 隐藏状态栏  
177 - // [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];  
178 - [UIApplication sharedApplication].statusBarHidden = YES;  
179 -  
180 - _isFocusing = NO;  
181 - _isTakingPhoto = NO;  
182 - _isShooting = NO;  
183 - _isRotatingCamera = NO;  
184 - _canWrite = NO;  
185 - _beginGestureScale = 1.0f;  
186 - _effectiveScale = 1.0f;  
187 -  
188 - [self.view addSubview:self.rotateCameraButton];  
189 - [self.view addSubview:self.flashButton];  
190 - [self.view addSubview:self.takeButton];  
191 - [self.view addSubview:self.closeButton];  
192 - [self.view addSubview:self.tipLabel];  
193 - [self.view addSubview:self.focusImageView];  
194 - [self.view addSubview:self.cancelButton];  
195 - [self.view addSubview:self.confirmButton];  
196 -  
197 - CGFloat rotateOffest = CAMERA_IS_IPhoneX_All ? kCameraNavigationBarHeight : 20 ;  
198 - [self.rotateCameraButton mas_makeConstraints:^(MASConstraintMaker *make) {  
199 - make.width.mas_equalTo(50);  
200 - make.height.mas_equalTo(30);  
201 - make.top.mas_equalTo(self.view.mas_top).mas_offset(rotateOffest);  
202 - make.right.mas_equalTo(self.view.mas_right).mas_offset(-15);  
203 - }];  
204 -  
205 - [self.flashButton mas_makeConstraints:^(MASConstraintMaker *make) {  
206 - make.width.mas_equalTo(50);  
207 - make.height.mas_equalTo(30);  
208 - make.top.mas_equalTo(self.view.mas_top).mas_offset(rotateOffest);  
209 - make.right.mas_equalTo(self.rotateCameraButton.mas_left);  
210 - }];  
211 -  
212 - //拍摄按钮  
213 - CGFloat bottom = CAMERA_IS_IPhoneX_All ? -55-kCameraVerticalBottomSafeHeight : -20;  
214 - [self.takeButton mas_makeConstraints:^(MASConstraintMaker *make) {  
215 - make.width.mas_equalTo(120);  
216 - make.height.mas_equalTo(120);  
217 - make.centerX.mas_equalTo(self.view.mas_centerX);  
218 - make.bottom.mas_equalTo(self.view.mas_bottom).mas_offset(bottom);  
219 - }];  
220 -  
221 - [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {  
222 - make.width.mas_equalTo(60);  
223 - make.height.mas_equalTo(30);  
224 - make.centerY.mas_equalTo(self.takeButton.mas_centerY);  
225 - make.right.mas_equalTo(self.takeButton.mas_left).mas_offset(-20);  
226 - }];  
227 -  
228 - [self.tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {  
229 - make.centerX.mas_equalTo(self.view.mas_centerX);  
230 - make.bottom.mas_equalTo(self.takeButton.mas_top).mas_offset(-20);  
231 - }];  
232 -  
233 - [self.focusImageView mas_makeConstraints:^(MASConstraintMaker *make) {  
234 - make.width.mas_equalTo(60);  
235 - make.height.mas_equalTo(60);  
236 - make.centerX.mas_equalTo(self.view.mas_centerX);  
237 - make.centerY.mas_equalTo(self.view.mas_centerY);  
238 - }];  
239 -  
240 - [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {  
241 - make.width.mas_equalTo(60);  
242 - make.height.mas_equalTo(60);  
243 - make.left.mas_equalTo(self.view.mas_left).mas_offset(40);  
244 - make.bottom.mas_equalTo(self.view.mas_bottom).mas_offset(-60-kCameraVerticalBottomSafeHeight);  
245 - }];  
246 -  
247 - [self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) {  
248 - make.width.mas_equalTo(60);  
249 - make.height.mas_equalTo(60);  
250 - make.right.mas_equalTo(self.view.mas_right).mas_offset(-40);  
251 - make.bottom.mas_equalTo(self.cancelButton.mas_bottom);  
252 - }];  
253 -  
254 -}  
255 -  
256 -- (void)viewWillAppear:(BOOL)animated  
257 -{  
258 - [super viewWillAppear:animated];  
259 -  
260 - AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];  
261 - if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)  
262 - {  
263 - [self requestAuthorizationForVideo];  
264 - }  
265 -  
266 - //判断用户是否允许访问麦克风权限  
267 - authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];  
268 - if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)  
269 - {  
270 - [self requestAuthorizationForVideo];  
271 - }  
272 - [self requestAuthorizationForPhotoLibrary];  
273 -  
274 - [self initAVCaptureSession];  
275 -  
276 - [self configDefaultUIDisplay];  
277 -  
278 - [self addTapGenstureRecognizerForCamera];  
279 -  
280 -}  
281 -  
282 -- (void)viewDidAppear:(BOOL)animated  
283 -{  
284 - [super viewDidAppear:animated];  
285 -  
286 - [self startSession];  
287 -  
288 - [self setFocusCursorWithPoint:self.view.center];  
289 -  
290 - if (self.isCanShootVideo)  
291 - {  
292 - self.tipLabel.text = @"点击拍照,长按摄像";  
293 - }else  
294 - {  
295 - self.tipLabel.text = @"点击拍照,不可摄像";  
296 - }  
297 -  
298 - [self tipLabelAnimation];  
299 -  
300 -}  
301 -  
302 -- (void)viewWillDisappear:(BOOL)animated  
303 -{  
304 - [super viewWillDisappear:animated];  
305 -  
306 - [self setCaptureVideoPreviewLayerTransformWithScale:1.0f];  
307 -  
308 - // 显示状态栏  
309 - // [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];  
310 - [UIApplication sharedApplication].statusBarHidden = YES;  
311 -}  
312 -  
313 -- (BOOL)prefersStatusBarHidden  
314 -{  
315 - return YES;  
316 -}  
317 -  
318 -- (void)viewDidDisappear:(BOOL)animated  
319 -{  
320 - [super viewDidDisappear:animated];  
321 -  
322 - [self stopSession];  
323 -  
324 - [self stopUpdateAccelerometer];  
325 -}  
326 -  
327 -#pragma mark - 释放  
328 -- (void)dealloc  
329 -{  
330 - NSLog(@"XFCameraController 释放了");  
331 - [[NSNotificationCenter defaultCenter] removeObserver:self];  
332 -}  
333 -  
334 -- (void)didReceiveMemoryWarning  
335 -{  
336 - [super didReceiveMemoryWarning];  
337 -}  
338 -  
339 -#pragma mark - 控件方法  
340 -  
341 -/**  
342 - * 关闭当前界面  
343 - */  
344 -- (void)closeBtnFunc  
345 -{  
346 - [self dismissViewControllerAnimated:YES completion:nil];  
347 -}  
348 -  
349 -/**  
350 - * 切换前后摄像头  
351 - */  
352 -- (void)rotateCameraBtnFunc:(UIButton *)btn  
353 -{  
354 - btn.selected = !btn.selected;  
355 - if (btn.selected) {  
356 - self.flashButton.hidden = YES;  
357 - } else {  
358 - self.flashButton.hidden = NO;  
359 - }  
360 - _isRotatingCamera = YES;  
361 -  
362 - AVCaptureDevice *currentDevice = [self.videoInput device];  
363 - AVCaptureDevicePosition currentPosition = [currentDevice position];  
364 -  
365 - AVCaptureDevice *toChangeDevice;  
366 - AVCaptureDevicePosition toChangePosition = AVCaptureDevicePositionFront;  
367 - if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront)  
368 - {  
369 - toChangePosition = AVCaptureDevicePositionBack;  
370 - }  
371 - toChangeDevice = [self getCameraDeviceWithPosition:toChangePosition];  
372 -  
373 - //获得要调整的设备输入对象  
374 - AVCaptureDeviceInput *toChangeDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:toChangeDevice error:nil];  
375 -  
376 - //改变会话的配置前一定要先开启配置,配置完成后提交配置改变  
377 - [self.captureSession beginConfiguration];  
378 - //移除原有输入对象  
379 - [self.captureSession removeInput:self.videoInput];  
380 - //添加新的输入对象  
381 - if ([self.captureSession canAddInput:toChangeDeviceInput])  
382 - {  
383 - [self.captureSession addInput:toChangeDeviceInput];  
384 - self.videoInput = toChangeDeviceInput;  
385 - }  
386 -  
387 - //提交会话配置  
388 - [self.captureSession commitConfiguration];  
389 -  
390 - _isRotatingCamera = NO;  
391 -}  
392 -  
393 -- (void)flashBtnFunc:(UIButton *)btn  
394 -{  
395 - btn.selected = !btn.selected;  
396 -#pragma mark - TODO: 更改是否打开手电筒  
397 - if (btn.selected)  
398 - {  
399 -// [SGQRCodeHelperTool SG_openFlashlight];  
400 - }else  
401 - {  
402 -// [SGQRCodeHelperTool SG_CloseFlashlight];  
403 - }  
404 -}  
405 -  
406 -- (void)cancelBtnfunc  
407 -{  
408 - _isTakingPhoto = NO;  
409 - [self removePlayerItemNotification];  
410 -  
411 - [self startAnimationGroup];  
412 -}  
413 -  
414 -/**  
415 - * 确认按钮并返回代理  
416 - */  
417 -- (void)confirmBtnFunc  
418 -{  
419 -  
420 - if (self.playerLayer) {  
421 - self.playerLayer.hidden = YES;  
422 - }  
423 -  
424 - if (self.captureVideoPreviewLayer) {  
425 - self.captureVideoPreviewLayer.hidden = NO;  
426 - }  
427 -  
428 - __weak typeof(self) weakSelf = self;  
429 - if (self.photoPreviewImageView)  
430 - {  
431 - UIImage *finalImage = [self cutImageWithView:self.photoPreviewImageView];  
432 -  
433 - // [XFPhotoLibraryManager savePhotoWithImage:finalImage andAssetCollectionName:self.assetCollectionName withCompletion:^(UIImage *image, NSError *error) {  
434 - //  
435 - if (self.takePhotosCompletionBlock)  
436 - {  
437 - // if (error)  
438 - // {  
439 - // NSLog(@"保存照片失败!");  
440 - // weakSelf.takePhotosCompletionBlock(nil, error);  
441 - // }  
442 - // else  
443 - // {  
444 - // NSLog(@"保存照片成功!");  
445 - weakSelf.takePhotosCompletionBlock(finalImage, nil);  
446 - // }  
447 - }  
448 -  
449 - // }];  
450 -  
451 - self.confirmButton.userInteractionEnabled = NO;  
452 -  
453 - }  
454 - else  
455 - {  
456 - [self.player.currentItem cancelPendingSeeks];  
457 - [self.player.currentItem.asset cancelLoading];  
458 - [self.player pause];  
459 -  
460 - _playerItem = nil;  
461 - [self.player replaceCurrentItemWithPlayerItem:nil];  
462 - self.player = nil;  
463 -  
464 - [_playerLayer removeFromSuperlayer];  
465 - _playerLayer = nil;  
466 -  
467 - [weakSelf cropWithVideoUrlStr:weakSelf.videoURL start:0 end:weakSelf.currentVideoTimeLength completion:^(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess) {  
468 -  
469 - if (isSuccess)  
470 - {  
471 -  
472 - [XFPhotoLibraryManager zx_saveVideoWithVideoUrl:outputURL andAssetCollectionName:nil withCompletion:^(PHAsset *asset, NSURL *videoUrl, NSError *error) {  
473 - if (weakSelf.zxshootCompletionBlock)  
474 - {  
475 - if (error)  
476 - {  
477 - NSLog(@"保存视频失败!");  
478 - weakSelf.zxshootCompletionBlock(asset,nil, 0, nil, error);  
479 - }  
480 - else  
481 - {  
482 - NSLog(@"保存视频成功!");  
483 -  
484 - // 获取视频的第一帧图片  
485 - UIImage *image = [weakSelf thumbnailImageRequestWithVideoUrl:videoUrl andTime:0.01f];  
486 -  
487 -  
488 - weakSelf.zxshootCompletionBlock(asset,videoUrl, videoDuration, image, nil);  
489 -  
490 - [[NSFileManager defaultManager] removeItemAtURL:weakSelf.videoURL error:nil];  
491 - weakSelf.videoURL = nil;  
492 - }  
493 - }  
494 -  
495 - weakSelf.confirmButton.userInteractionEnabled = NO;  
496 - }];  
497 -  
498 - // [XFPhotoLibraryManager saveVideoWithVideoUrl:outputURL andAssetCollectionName:nil withCompletion:^(NSURL *videoUrl, NSError *error) {  
499 - //  
500 - // if (self.shootCompletionBlock)  
501 - // {  
502 - // if (error)  
503 - // {  
504 - // NSLog(@"保存视频失败!");  
505 - // weakSelf.shootCompletionBlock(nil, 0, nil, error);  
506 - // }  
507 - // else  
508 - // {  
509 - // NSLog(@"保存视频成功!");  
510 - //  
511 - // // 获取视频的第一帧图片  
512 - // UIImage *image = [weakSelf thumbnailImageRequestWithVideoUrl:videoUrl andTime:0.01f];  
513 - //  
514 - // weakSelf.shootCompletionBlock(videoUrl, videoDuration, image, nil);  
515 - //  
516 - // [[NSFileManager defaultManager] removeItemAtURL:weakSelf.videoURL error:nil];  
517 - // weakSelf.videoURL = nil;  
518 - // }  
519 - // }  
520 - //  
521 - // weakSelf.confirmButton.userInteractionEnabled = NO;  
522 - //  
523 - // }];  
524 - }  
525 - else  
526 - {  
527 - NSLog(@"保存视频失败!");  
528 - [[NSFileManager defaultManager] removeItemAtURL:weakSelf.videoURL error:nil];  
529 - weakSelf.videoURL = nil;  
530 - [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];  
531 - }  
532 - }];  
533 - }  
534 -}  
535 -  
536 -#pragma mark - 懒加载  
537 -- (AVCaptureSession *)captureSession  
538 -{  
539 - if (_captureSession == nil)  
540 - {  
541 - _captureSession = [[AVCaptureSession alloc] init];  
542 -  
543 - if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh])  
544 - {  
545 - _captureSession.sessionPreset = AVCaptureSessionPresetHigh;  
546 - }  
547 - }  
548 -  
549 - return _captureSession;  
550 -}  
551 -  
552 -- (dispatch_queue_t)videoQueue  
553 -{  
554 - if (!_videoQueue)  
555 - {  
556 - _videoQueue = dispatch_get_main_queue();  
557 - }  
558 -  
559 - return _videoQueue;  
560 -}  
561 -  
562 -- (CMMotionManager *)motionManager  
563 -{  
564 - if (!_motionManager)  
565 - {  
566 - _motionManager = [[CMMotionManager alloc] init];  
567 - }  
568 - return _motionManager;  
569 -}  
570 -  
571 -- (UIButton *)rotateCameraButton  
572 -{  
573 - if (!_rotateCameraButton)  
574 - {  
575 - _rotateCameraButton = [[UIButton alloc] init];  
576 - [_rotateCameraButton setImage:[UIImage imageFromBundle:@"fb_xiangji"] forState:UIControlStateNormal];  
577 - [_rotateCameraButton addTarget:self action:@selector(rotateCameraBtnFunc:) forControlEvents:UIControlEventTouchUpInside];  
578 - }  
579 - return _rotateCameraButton;  
580 -}  
581 -  
582 -- (UIButton *)flashButton  
583 -{  
584 - if (!_flashButton)  
585 - {  
586 - _flashButton = [[UIButton alloc] init];  
587 - [_flashButton setImage:[UIImage imageFromBundle:@"gz_shoudian"] forState:UIControlStateNormal];  
588 - [_flashButton setImage:[UIImage imageFromBundle:@"gz_shoudian2"] forState:UIControlStateSelected];  
589 - [_flashButton addTarget:self action:@selector(flashBtnFunc:) forControlEvents:UIControlEventTouchUpInside];  
590 - }  
591 - return _flashButton;  
592 -}  
593 -  
594 -//拍摄按钮  
595 -- (UIButton *)takeButton  
596 -{  
597 - if (!_takeButton)  
598 - {  
599 - _takeButton = [[UIButton alloc] init];  
600 - }  
601 -  
602 - return _takeButton;  
603 -}  
604 -  
605 -- (UIButton *)closeButton  
606 -{  
607 - if (!_closeButton)  
608 - {  
609 - _closeButton = [[UIButton alloc] init];  
610 - [_closeButton setImage:[UIImage imageFromBundle:@"fb_quxiaoxia"] forState:UIControlStateNormal];  
611 - [_closeButton addTarget:self action:@selector(closeBtnFunc) forControlEvents:UIControlEventTouchUpInside];  
612 - }  
613 - return _closeButton;  
614 -}  
615 -  
616 -- (UILabel *)tipLabel  
617 -{  
618 - if (!_tipLabel)  
619 - {  
620 - _tipLabel = [[UILabel alloc] init];  
621 - _tipLabel.font = [UIFont systemFontOfSize:14];  
622 - _tipLabel.textColor = [UIColor whiteColor];  
623 - }  
624 - return _tipLabel;  
625 -}  
626 -  
627 -- (UIImageView *)focusImageView  
628 -{  
629 - if (!_focusImageView)  
630 - {  
631 - _focusImageView = [[UIImageView alloc] init];  
632 - _focusImageView.image = [UIImage imageFromBundle:@"sight_video_focus"];  
633 - }  
634 - return _focusImageView;  
635 -}  
636 -  
637 -// 拍照摄像后的预览模块  
638 -- (UIButton *)cancelButton  
639 -{  
640 - if (!_cancelButton)  
641 - {  
642 - _cancelButton = [[UIButton alloc] init];  
643 - [_cancelButton setImage:[UIImage imageFromBundle:@"fb_chongpai"] forState:UIControlStateNormal];  
644 - [_cancelButton addTarget:self action:@selector(cancelBtnfunc) forControlEvents:UIControlEventTouchUpInside];  
645 - }  
646 - return _cancelButton;  
647 -}  
648 -  
649 -// 拍照摄像后的预览模块  
650 -- (UIButton *)confirmButton  
651 -{  
652 - if (!_confirmButton)  
653 - {  
654 - _confirmButton = [[UIButton alloc] init];  
655 - [_confirmButton setImage:[UIImage imageFromBundle:@"fb_wancheng"] forState:UIControlStateNormal];  
656 - [_confirmButton addTarget:self action:@selector(confirmBtnFunc) forControlEvents:UIControlEventTouchUpInside];  
657 - _confirmButton.camera_cs_acceptEventInterval = 2.0f;  
658 -  
659 - }  
660 - return _confirmButton;  
661 -}  
662 -  
663 -#pragma mark - 私有方法  
664 -  
665 -/**  
666 - * 初始化AVCapture会话  
667 - */  
668 -- (void)initAVCaptureSession  
669 -{  
670 - //1、添加 "视频" 与 "音频" 输入流到session  
671 - [self setupVideo];  
672 -  
673 - [self setupAudio];  
674 -  
675 - //2、添加图片,movie输出流到session  
676 - [self setupCaptureStillImageOutput];  
677 -  
678 - //3、创建视频预览层,用于实时展示摄像头状态  
679 - [self setupCaptureVideoPreviewLayer];  
680 -  
681 - //设置静音状态也可播放声音  
682 - AVAudioSession *audioSession = [AVAudioSession sharedInstance];  
683 - [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];  
684 -}  
685 -  
686 -/**  
687 - * 设置视频输入  
688 - */  
689 -- (void)setupVideo  
690 -{  
691 - AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];  
692 - if (!captureDevice)  
693 - {  
694 - NSLog(@"取得后置摄像头时出现问题.");  
695 -  
696 - return;  
697 - }  
698 -  
699 - NSError *error = nil;  
700 - self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];  
701 - if (error)  
702 - {  
703 - NSLog(@"取得设备输入videoInput对象时出错,错误原因:%@", error);  
704 -  
705 - return;  
706 - }  
707 -  
708 - //3、将设备输出添加到会话中  
709 - if ([self.captureSession canAddInput:self.videoInput])  
710 - {  
711 - [self.captureSession addInput:self.videoInput];  
712 - }  
713 -  
714 - self.videoOutput = [[AVCaptureVideoDataOutput alloc] init];  
715 - self.videoOutput.alwaysDiscardsLateVideoFrames = YES; //立即丢弃旧帧,节省内存,默认YES  
716 - [self.videoOutput setSampleBufferDelegate:self queue:self.videoQueue];  
717 - if ([self.captureSession canAddOutput:self.videoOutput])  
718 - {  
719 - [self.captureSession addOutput:self.videoOutput];  
720 - }  
721 -}  
722 -  
723 -/**  
724 - * 设置音频录入  
725 - */  
726 -- (void)setupAudio  
727 -{  
728 - NSError *error = nil;  
729 - self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio] error:&error];  
730 - if (error)  
731 - {  
732 - NSLog(@"取得设备输入audioInput对象时出错,错误原因:%@", error);  
733 -  
734 - return;  
735 - }  
736 - if ([self.captureSession canAddInput:self.audioInput])  
737 - {  
738 - [self.captureSession addInput:self.audioInput];  
739 - }  
740 -  
741 - self.audioOutput = [[AVCaptureAudioDataOutput alloc] init];  
742 - [self.audioOutput setSampleBufferDelegate:self queue:self.videoQueue];  
743 - if([self.captureSession canAddOutput:self.audioOutput])  
744 - {  
745 - [self.captureSession addOutput:self.audioOutput];  
746 - }  
747 -}  
748 -  
749 -/**  
750 - * 设置图片输出  
751 - */  
752 -- (void)setupCaptureStillImageOutput  
753 -{  
754 - self.captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init];  
755 - NSDictionary *outputSettings = @{  
756 - AVVideoCodecKey:AVVideoCodecJPEG  
757 - };  
758 - [_captureStillImageOutput setOutputSettings:outputSettings];  
759 -  
760 - if ([self.captureSession canAddOutput:_captureStillImageOutput])  
761 - {  
762 - [self.captureSession addOutput:_captureStillImageOutput];  
763 - }  
764 -}  
765 -  
766 -/**  
767 - * 设置预览layer  
768 - */  
769 -- (void)setupCaptureVideoPreviewLayer  
770 -{  
771 - _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];  
772 -  
773 - CALayer *layer = self.view.layer;  
774 -  
775 - _captureVideoPreviewLayer.frame = CGRectMake(0, 0, kCameraScreenWidth, kCameraScreenHeight);  
776 -  
777 - CGFloat centerY = self.view.frame.origin.y + self.view.frame.size.height * 0.5;  
778 - CGRect frame = _captureVideoPreviewLayer.frame;  
779 - frame.origin.y = centerY - frame.size.height * 0.5;  
780 - _captureVideoPreviewLayer.frame = frame;  
781 -  
782 - _captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspect; //填充模式  
783 -  
784 - [layer addSublayer:_captureVideoPreviewLayer];  
785 -}  
786 -  
787 -/**  
788 - * 开启会话  
789 - */  
790 -- (void)startSession  
791 -{  
792 - if (![self.captureSession isRunning])  
793 - {  
794 - [self.captureSession startRunning];  
795 - }  
796 -}  
797 -  
798 -/**  
799 - * 停止会话  
800 - */  
801 -- (void)stopSession  
802 -{  
803 - if ([self.captureSession isRunning])  
804 - {  
805 - [self.captureSession stopRunning];  
806 - }  
807 -}  
808 -  
809 -/**  
810 - * 开始拍照录像动画组合  
811 - */  
812 -- (void)startAnimationGroup  
813 -{  
814 - [self configDefaultUIDisplay];  
815 -  
816 - [self setFocusCursorWithPoint:self.view.center];  
817 -  
818 -  
819 -  
820 - [self tipLabelAnimation];  
821 -}  
822 -  
823 -/**  
824 - * 配置默认UI信息  
825 - */  
826 -- (void)configDefaultUIDisplay  
827 -{  
828 - _isPicOrVideo = NO;  
829 - if (self.photoPreviewImageView)//图片设置置空  
830 - {  
831 - [self.photoPreviewImageView removeFromSuperview];  
832 - [self.photoPreviewContainerView removeFromSuperview];  
833 - self.photoPreviewImageView = nil;  
834 - self.photoPreviewContainerView = nil;  
835 - }  
836 - if (self.playerLayer)//视频设置置空  
837 - {  
838 - [self.player pause];  
839 - self.player = nil;  
840 - self.playerItem = nil;  
841 - self.playerLayer.hidden = YES;  
842 - [self.playerLayer removeFromSuperlayer];  
843 - self.playerLayer = nil;  
844 - self.cameraButton.progressPercentage = 0.0f;  
845 - self.videoPreviewContainerView = nil;  
846 - [[NSFileManager defaultManager] removeItemAtURL:self.videoURL error:nil];  
847 - self.videoURL = nil;  
848 - }  
849 - if (self.captureVideoPreviewLayer) {  
850 - self.captureVideoPreviewLayer.hidden = NO;  
851 - }  
852 -  
853 - //更改  
854 - if (_captureVideoPreviewLayer.superlayer == self.view.layer) {  
855 - [_captureVideoPreviewLayer removeFromSuperlayer];  
856 - [self.view.layer insertSublayer:_captureVideoPreviewLayer atIndex:(unsigned)self.view.layer.sublayers.count];  
857 - }  
858 -  
859 - [self.view bringSubviewToFront:self.rotateCameraButton];  
860 - [self.view bringSubviewToFront:self.flashButton];  
861 - [self.view bringSubviewToFront:self.closeButton];  
862 - [self.rotateCameraButton setHidden:NO];  
863 - [self.flashButton setHidden:NO];  
864 - [self.closeButton setHidden:NO];  
865 -  
866 -  
867 - [self.view bringSubviewToFront:self.tipLabel];  
868 - [self.tipLabel setAlpha:0];  
869 -  
870 - [self.cancelButton setHidden:YES];  
871 - [self.confirmButton setHidden:YES];  
872 -  
873 - // 设置拍照按钮  
874 - if (_cameraButton == nil)  
875 - {  
876 - XFCameraButton *cameraButton = [XFCameraButton defaultCameraButton];  
877 - _cameraButton = cameraButton;  
878 -  
879 - [self.view addSubview:cameraButton];  
880 - CGFloat cameraBtnX = (kCameraScreenWidth - cameraButton.bounds.size.width) / 2;  
881 -  
882 - CGFloat bottom = CAMERA_IS_IPhoneX_All ? 90 + SafeViewBottomHeight : 20+30;  
883 -  
884 - CGFloat cameraBtnY = kCameraScreenHeight - cameraButton.bounds.size.height - bottom; //距离底部60  
885 - cameraButton.frame = CGRectMake(cameraBtnX, cameraBtnY, cameraButton.bounds.size.width, cameraButton.bounds.size.height);  
886 - [self.view bringSubviewToFront:cameraButton];  
887 -  
888 - // 设置拍照按钮点击事件  
889 - __weak typeof(self) weakSelf = self;  
890 - // 配置拍照方法  
891 - [cameraButton configureTapCameraButtonEventWithBlock:^(UITapGestureRecognizer *tapGestureRecognizer) {  
892 - if (self->_isTakingPhoto) {  
893 - return;  
894 - }  
895 - [weakSelf requestAuthCamera];  
896 - [weakSelf takePhotos:tapGestureRecognizer];  
897 -  
898 - }];  
899 - if (self.isCanShootVideo) {  
900 - // 配置拍摄方法  
901 - [cameraButton configureLongPressCameraButtonEventWithBlock:^(UILongPressGestureRecognizer *longPressGestureRecognizer) {  
902 - [weakSelf requestAuthorizationForVideo];  
903 - [weakSelf longPressCameraButtonFunc:longPressGestureRecognizer];  
904 - }];  
905 - }  
906 - }  
907 - [self.cameraButton setHidden:NO];  
908 - [self.view bringSubviewToFront:self.cameraButton];  
909 -  
910 - [self setCaptureVideoPreviewLayerTransformWithScale:1.0f];  
911 -  
912 - // 对焦imageView  
913 - [self.view bringSubviewToFront:self.focusImageView];  
914 - [self.focusImageView setAlpha:0];  
915 -  
916 - // 监听屏幕方向  
917 - [self startUpdateAccelerometer];  
918 -}  
919 -  
920 -/**  
921 - * 提示语动画  
922 - */  
923 -- (void)tipLabelAnimation  
924 -{  
925 - [self.view bringSubviewToFront:self.tipLabel];  
926 -  
927 - __weak typeof(self) weakSelf = self;  
928 - [UIView animateWithDuration:1.0f delay:0.5f options:UIViewAnimationOptionCurveEaseInOut animations:^{  
929 -  
930 - [weakSelf.tipLabel setAlpha:1];  
931 -  
932 - } completion:^(BOOL finished) {  
933 -  
934 - [UIView animateWithDuration:1.0f delay:3.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{  
935 -  
936 - [weakSelf.tipLabel setAlpha:0];  
937 -  
938 - } completion:nil];  
939 -  
940 - }];  
941 -}  
942 -  
943 -/**  
944 - * 取得指定位置的摄像头  
945 - *  
946 - * @param position 摄像头位置  
947 - *  
948 - * @return 摄像头设备  
949 - */  
950 -- (AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position  
951 -{  
952 - NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];  
953 - for (AVCaptureDevice *camera in cameras)  
954 - {  
955 - if ([camera position] == position)  
956 - {  
957 - return camera;  
958 - }  
959 - }  
960 - return nil;  
961 -}  
962 -  
963 -/**  
964 - * 改变设备属性的统一操作方法  
965 - *  
966 - * @param propertyChange 属性改变操作  
967 - */  
968 -- (void)changeDeviceProperty:(PropertyChangeBlock)propertyChange  
969 -{  
970 - AVCaptureDevice *captureDevice = [self.videoInput device];  
971 - NSError *error;  
972 -  
973 - //注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁  
974 - if ([captureDevice lockForConfiguration:&error])  
975 - {  
976 - propertyChange(captureDevice);  
977 - [captureDevice unlockForConfiguration];  
978 - }  
979 - else  
980 - {  
981 - NSLog(@"设置设备属性过程发生错误,错误信息:%@",error.localizedDescription);  
982 - }  
983 -}  
984 -  
985 -#pragma mark - 拍照功能  
986 -  
987 -/**  
988 - * 拍照方法  
989 - */  
990 -- (void)takePhotos:(UITapGestureRecognizer *)tapGestureRecognizer  
991 -{  
992 -  
993 - __weak typeof(self) weakSelf = self;  
994 - // 请求相机权限  
995 - AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];  
996 - if (videoAuthStatus != AVAuthorizationStatusAuthorized)  
997 - {  
998 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
999 -  
1000 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
1001 - if (appName == nil)  
1002 - {  
1003 - appName = @"APP";  
1004 - }  
1005 - NSString *message = [NSString stringWithFormat:@"请在iPhone的“设置-隐私”选项中,允许%@访问你的相册,相机和麦克风。", appName];  
1006 -  
1007 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];//无法拍摄  
1008 -  
1009 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
1010 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
1011 - }];  
1012 -  
1013 - [alertController addAction:okAction];  
1014 - [self presentViewController:alertController animated:YES completion:nil];  
1015 -  
1016 - return;  
1017 - }  
1018 -  
1019 - // 请求麦克风权限  
1020 - AVAuthorizationStatus audioAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];  
1021 - if (audioAuthStatus != AVAuthorizationStatusAuthorized)  
1022 - {  
1023 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
1024 -  
1025 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
1026 - if (appName == nil)  
1027 - {  
1028 - appName = @"APP";  
1029 - }  
1030 - NSString *message = [NSString stringWithFormat:@"请在iPhone的“设置-隐私“选项中,允许%@访问你的相册,相机和麦克风。", appName];//[NSString stringWithFormat:@"请在iPhone的““设置-隐私””选项中, 允许%@访问你的麦克风?", appName];  
1031 -  
1032 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];  
1033 -  
1034 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
1035 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
1036 - }];  
1037 -  
1038 - [alertController addAction:okAction];  
1039 -  
1040 - [self presentViewController:alertController animated:YES completion:nil];  
1041 -  
1042 - return;  
1043 - }  
1044 -  
1045 - _isTakingPhoto = YES;  
1046 - //根据设备输出获得连接  
1047 - AVCaptureConnection *captureConnection = [self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo];  
1048 -  
1049 - [captureConnection setVideoScaleAndCropFactor:self.effectiveScale];  
1050 -  
1051 - //根据连接取得设备输出的数据  
1052 - [self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {  
1053 - if (imageDataSampleBuffer)  
1054 - {  
1055 - NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];  
1056 - UIImage *image = [UIImage imageWithData:imageData];  
1057 -  
1058 - [self previewPhotoWithImage:image];  
1059 -  
1060 - self->_isTakingPhoto = YES;  
1061 - }else{  
1062 - self->_isTakingPhoto = NO;  
1063 - }  
1064 -  
1065 - }];  
1066 -}  
1067 -  
1068 -/**  
1069 - * 预览图片  
1070 - */  
1071 -- (void)previewPhotoWithImage:(UIImage *)image  
1072 -{  
1073 - [self stopUpdateAccelerometer];  
1074 -  
1075 - [self.cameraButton setHidden:YES];  
1076 - [self.closeButton setHidden:YES];  
1077 - [self.rotateCameraButton setHidden:YES];  
1078 - [self.flashButton setHidden:YES];  
1079 -  
1080 - UIImage *finalImage = nil;  
1081 - if (self.shootingOrientation == UIDeviceOrientationLandscapeRight)  
1082 - {  
1083 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationDown];  
1084 - }  
1085 - else if (self.shootingOrientation == UIDeviceOrientationLandscapeLeft)  
1086 - {  
1087 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationUp];  
1088 - }  
1089 - else if (self.shootingOrientation == UIDeviceOrientationPortraitUpsideDown)  
1090 - {  
1091 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationLeft];  
1092 - }  
1093 - else  
1094 - {  
1095 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationRight];  
1096 - }  
1097 -  
1098 - self.photoPreviewImageView = [[UIImageView alloc] init];  
1099 - float videoRatio = finalImage.size.width / finalImage.size.height;  
1100 - if (self.shootingOrientation == UIDeviceOrientationLandscapeRight || self.shootingOrientation == UIDeviceOrientationLandscapeLeft)  
1101 - {  
1102 - CGFloat height = kCameraScreenWidth * videoRatio;  
1103 - CGFloat y = (kCameraScreenHeight - height) / 2;  
1104 - [self.photoPreviewImageView setFrame:CGRectMake(0, y, kCameraScreenWidth, height)];  
1105 - }  
1106 - else  
1107 - {  
1108 - if (CAMERA_IS_IPhoneX_All) {  
1109 - [self.photoPreviewImageView setFrame:CGRectMake(0, 0, kCameraScreenWidth, 667)];  
1110 - CGFloat centerY = self.view.frame.origin.y + self.view.frame.size.height * 0.5;  
1111 - CGRect frame = _captureVideoPreviewLayer.frame;  
1112 - frame.origin.y = centerY - frame.size.height * 0.5;  
1113 - self.photoPreviewImageView.frame = frame;  
1114 - }else  
1115 - {  
1116 - [self.photoPreviewImageView setFrame:CGRectMake(0, 0, kCameraScreenWidth, kCameraScreenHeight)];  
1117 - }  
1118 - }  
1119 - self.photoPreviewImageView.image = finalImage;  
1120 -  
1121 - self.photoPreviewContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kCameraScreenWidth, kCameraScreenHeight)];  
1122 - self.photoPreviewContainerView.backgroundColor = [UIColor blackColor];  
1123 - [self.photoPreviewContainerView addSubview:self.photoPreviewImageView];  
1124 - [self.view addSubview:self.photoPreviewContainerView];  
1125 - [self.view bringSubviewToFront:self.photoPreviewImageView];  
1126 - [self.view bringSubviewToFront:self.cancelButton];  
1127 - [self.view bringSubviewToFront:self.confirmButton];  
1128 - [self.cancelButton setHidden:NO];  
1129 - [self.confirmButton setHidden:NO];  
1130 -  
1131 - _isPicOrVideo = YES;  
1132 -}  
1133 -  
1134 -- (UIImage *)cutImageWithView:(UIView *)view  
1135 -{  
1136 - UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0);  
1137 - [view.layer renderInContext:UIGraphicsGetCurrentContext()];  
1138 - UIImage *image = UIGraphicsGetImageFromCurrentImageContext();  
1139 - UIGraphicsEndImageContext();  
1140 -  
1141 - return image;  
1142 -}  
1143 -  
1144 -#pragma mark - 视频录制  
1145 -  
1146 -/**  
1147 - * 录制视频方法  
1148 - */  
1149 -- (void)longPressCameraButtonFunc:(UILongPressGestureRecognizer *)sender  
1150 -{  
1151 - AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];  
1152 - if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)  
1153 - {  
1154 - return;  
1155 - }  
1156 -  
1157 - //判断用户是否允许访问麦克风权限  
1158 - authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];  
1159 - if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)  
1160 - {  
1161 - return;  
1162 - }  
1163 -  
1164 - switch (sender.state) {  
1165 - case UIGestureRecognizerStateBegan:  
1166 - [self startVideoRecorder];  
1167 - break;  
1168 - case UIGestureRecognizerStateCancelled:  
1169 - [self stopVideoRecorder];  
1170 - break;  
1171 - case UIGestureRecognizerStateEnded:  
1172 - [self stopVideoRecorder];  
1173 - break;  
1174 - case UIGestureRecognizerStateFailed:  
1175 - [self stopVideoRecorder];  
1176 - break;  
1177 - default:  
1178 - break;  
1179 - }  
1180 -  
1181 -}  
1182 -  
1183 -/**  
1184 - * 开始录制视频  
1185 - */  
1186 -- (void)startVideoRecorder  
1187 -{  
1188 - _isShooting = YES;  
1189 -  
1190 - [self stopUpdateAccelerometer];  
1191 -  
1192 - [self setCaptureVideoPreviewLayerTransformWithScale:1.0f];  
1193 -  
1194 - [self.cameraButton startShootAnimationWithDuration:START_VIDEO_ANIMATION_DURATION];  
1195 -  
1196 - __weak typeof(self) weakSelf = self;  
1197 - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(START_VIDEO_ANIMATION_DURATION * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{  
1198 -  
1199 - NSURL *url = [NSURL fileURLWithPath:[weakSelf createVideoFilePath]];  
1200 - self.videoURL = url;  
1201 -  
1202 - [self setUpWriter];  
1203 -  
1204 - [weakSelf timerFired];  
1205 -  
1206 - });  
1207 -}  
1208 -  
1209 -/**  
1210 - * 结束录制视频  
1211 - */  
1212 -- (void)stopVideoRecorder  
1213 -{  
1214 - if (_isShooting)  
1215 - {  
1216 - _isShooting = NO;  
1217 - self.cameraButton.progressPercentage = 0.0f;  
1218 - [self.cameraButton stopShootAnimation];  
1219 - [self timerStop];  
1220 -  
1221 - __weak __typeof(self)weakSelf = self;  
1222 - if(_assetWriter && _assetWriter.status == AVAssetWriterStatusWriting)  
1223 - {  
1224 - // dispatch_async(self.videoQueue, ^{  
1225 - [_assetWriter finishWritingWithCompletionHandler:^{  
1226 - weakSelf.canWrite = NO;  
1227 - weakSelf.assetWriter = nil;  
1228 - weakSelf.assetWriterAudioInput = nil;  
1229 - weakSelf.assetWriterVideoInput = nil;  
1230 - }];  
1231 - // });  
1232 - }  
1233 -  
1234 - if (timeLength < VIDEO_RECORDER_MIN_TIME)  
1235 - {  
1236 - return;  
1237 - }  
1238 -  
1239 - [self.cameraButton setHidden:YES];  
1240 -  
1241 - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{  
1242 -  
1243 - [weakSelf previewVideoAfterShoot];  
1244 -  
1245 - });  
1246 - }  
1247 - else  
1248 - {  
1249 - // nothing  
1250 - }  
1251 -}  
1252 -  
1253 -/**  
1254 - * 设置写入视频属性  
1255 - */  
1256 -- (void)setUpWriter  
1257 -{  
1258 - if (self.videoURL == nil)  
1259 - {  
1260 - return;  
1261 - }  
1262 -  
1263 - self.assetWriter = [AVAssetWriter assetWriterWithURL:self.videoURL fileType:AVFileTypeMPEG4 error:nil];  
1264 - //写入视频大小  
1265 - NSInteger numPixels = kCameraScreenWidth * kCameraScreenHeight;  
1266 - //每像素比特  
1267 - CGFloat bitsPerPixel = 16.0;  
1268 - NSInteger bitsPerSecond = numPixels * bitsPerPixel;  
1269 -  
1270 - // 码率和帧率设置  
1271 - NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey : @(bitsPerSecond),  
1272 - AVVideoExpectedSourceFrameRateKey : @(30),  
1273 - AVVideoMaxKeyFrameIntervalKey : @(30),  
1274 - AVVideoProfileLevelKey : AVVideoProfileLevelH264BaselineAutoLevel };  
1275 -  
1276 - //视频属性  
1277 - CGFloat videoWidthKey = kCameraScreenHeight;  
1278 - if (CAMERA_IS_IPhoneX_All) {  
1279 - videoWidthKey = 667;  
1280 - }  
1281 - self.videoCompressionSettings = @{ AVVideoCodecKey : AVVideoCodecH264,  
1282 - AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill,  
1283 - AVVideoWidthKey : @(videoWidthKey * 2),  
1284 - AVVideoHeightKey : @(kCameraScreenWidth * 2),  
1285 - AVVideoCompressionPropertiesKey : compressionProperties };  
1286 - _assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:self.videoCompressionSettings];  
1287 - //expectsMediaDataInRealTime 必须设为yes,需要从capture session 实时获取数据  
1288 - _assetWriterVideoInput.expectsMediaDataInRealTime = YES;  
1289 -  
1290 - if (self.shootingOrientation == UIDeviceOrientationLandscapeRight)  
1291 - {  
1292 - _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI);  
1293 - }  
1294 - else if (self.shootingOrientation == UIDeviceOrientationLandscapeLeft)  
1295 - {  
1296 - _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(0);  
1297 - }  
1298 - else if (self.shootingOrientation == UIDeviceOrientationPortraitUpsideDown)  
1299 - {  
1300 - _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI + (M_PI / 2.0));  
1301 - }  
1302 - else  
1303 - {  
1304 - _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI / 2.0);  
1305 - }  
1306 -  
1307 - // 音频设置  
1308 - self.audioCompressionSettings = @{ AVEncoderBitRatePerChannelKey : @(28000),  
1309 - AVFormatIDKey : @(kAudioFormatMPEG4AAC),  
1310 - AVNumberOfChannelsKey : @(1),  
1311 - AVSampleRateKey : @(22050) };  
1312 -  
1313 - _assetWriterAudioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:self.audioCompressionSettings];  
1314 - _assetWriterAudioInput.expectsMediaDataInRealTime = YES;  
1315 -  
1316 - if ([_assetWriter canAddInput:_assetWriterVideoInput])  
1317 - {  
1318 - [_assetWriter addInput:_assetWriterVideoInput];  
1319 - }  
1320 - else  
1321 - {  
1322 - NSLog(@"AssetWriter videoInput append Failed");  
1323 - }  
1324 -  
1325 - if ([_assetWriter canAddInput:_assetWriterAudioInput])  
1326 - {  
1327 - [_assetWriter addInput:_assetWriterAudioInput];  
1328 - }  
1329 - else  
1330 - {  
1331 - NSLog(@"AssetWriter audioInput Append Failed");  
1332 - }  
1333 -  
1334 - _canWrite = NO;  
1335 -}  
1336 -  
1337 -- (NSString *)createVideoFilePath  
1338 -{  
1339 - // 创建视频文件的存储路径  
1340 - NSString *filePath = [self createVideoFolderPath];  
1341 - if (filePath == nil)  
1342 - {  
1343 - return nil;  
1344 - }  
1345 -  
1346 - NSString *videoType = @".mp4";  
1347 - NSString *videoDestDateString = [self createFileNamePrefix];  
1348 - NSString *videoFileName = [videoDestDateString stringByAppendingString:videoType];  
1349 -  
1350 - NSUInteger idx = 1;  
1351 - /*We only allow 10000 same file name*/  
1352 - NSString *finalPath = [NSString stringWithFormat:@"%@/fileType=videoType_%@", filePath, videoFileName];  
1353 -  
1354 - while (idx % 10000 && [[NSFileManager defaultManager] fileExistsAtPath:finalPath])  
1355 - {  
1356 - finalPath = [NSString stringWithFormat:@"%@/%@_(%lu)%@", filePath, videoDestDateString, (unsigned long)idx++, videoType];  
1357 - }  
1358 -  
1359 - return finalPath;  
1360 -}  
1361 -  
1362 -- (NSString *)createVideoFolderPath  
1363 -{  
1364 -#pragma mark - TODO: 路径参数配置 写个新属性  
1365 -// if (self.conversationId) {  
1366 -// return [CNTools newChatFilePathByUserId:self.conversationId];  
1367 -// }  
1368 -// return [CNTools chatFilePathByUserId:[IMAPlatform sharedInstance].host.userId];  
1369 -//  
1370 - NSFileManager *fileManager = [NSFileManager defaultManager];  
1371 - NSString *homePath = NSHomeDirectory();  
1372 -  
1373 - NSString *tmpFilePath;  
1374 -  
1375 - if (homePath.length > 0)  
1376 - {  
1377 - NSString *documentPath = [homePath stringByAppendingString:@"/Documents"];  
1378 - if ([fileManager fileExistsAtPath:documentPath isDirectory:NULL] == YES)  
1379 - {  
1380 - BOOL success = NO;  
1381 -  
1382 - NSArray *paths = [fileManager contentsOfDirectoryAtPath:documentPath error:nil];  
1383 -  
1384 - //offline file folder  
1385 - tmpFilePath = [documentPath stringByAppendingString:[NSString stringWithFormat:@"/%@", VIDEO_FILEPATH]];  
1386 - if ([paths containsObject:VIDEO_FILEPATH] == NO)  
1387 - {  
1388 - success = [fileManager createDirectoryAtPath:tmpFilePath withIntermediateDirectories:YES attributes:nil error:nil];  
1389 - if (!success)  
1390 - {  
1391 - tmpFilePath = nil;  
1392 - }  
1393 - }  
1394 - return tmpFilePath;  
1395 - }  
1396 - }  
1397 -  
1398 - return false;  
1399 -}  
1400 -  
1401 -/**  
1402 - * 创建文件名  
1403 - *  
1404 - */  
1405 -- (NSString *)createFileNamePrefix  
1406 -{  
1407 - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];  
1408 - [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];  
1409 -  
1410 - NSString *destDateString = [dateFormatter stringFromDate:[NSDate date]];  
1411 - destDateString = [destDateString stringByReplacingOccurrencesOfString:@" " withString:@"-"];  
1412 - destDateString = [destDateString stringByReplacingOccurrencesOfString:@"+" withString:@"-"];  
1413 - destDateString = [destDateString stringByReplacingOccurrencesOfString:@":" withString:@"-"];  
1414 -  
1415 - return destDateString;  
1416 -}  
1417 -  
1418 -/**  
1419 - * 开启定时器  
1420 - */  
1421 -- (void)timerFired  
1422 -{  
1423 - timeLength = 0;  
1424 - self.timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(timerRecord) userInfo:nil repeats:YES];  
1425 -}  
1426 -  
1427 -/**  
1428 - * 绿色转圈百分比计算  
1429 - */  
1430 -- (void)timerRecord  
1431 -{  
1432 - if (!_isShooting)  
1433 - {  
1434 - [self timerStop];  
1435 - return ;  
1436 - }  
1437 -  
1438 - // 时间大于VIDEO_RECORDER_MAX_TIME则停止录制  
1439 - if (timeLength > VIDEO_RECORDER_MAX_TIME)  
1440 - {  
1441 - [self stopVideoRecorder];  
1442 - }  
1443 -  
1444 - timeLength += TIMER_INTERVAL;  
1445 -  
1446 - // NSLog(@"%lf", timeLength / VIDEO_RECORDER_MAX_TIME);  
1447 -  
1448 - self.cameraButton.progressPercentage = timeLength / VIDEO_RECORDER_MAX_TIME;  
1449 -  
1450 -}  
1451 -  
1452 -/**  
1453 - * 停止定时器  
1454 - */  
1455 -- (void)timerStop  
1456 -{  
1457 - if ([self.timer isValid])  
1458 - {  
1459 - [self.timer invalidate];  
1460 - self.timer = nil;  
1461 - }  
1462 -}  
1463 -  
1464 -/**  
1465 - * 预览录制的视频  
1466 - */  
1467 -- (void)previewVideoAfterShoot  
1468 -{  
1469 - if (self.videoURL == nil || self.playerLayer != nil)  
1470 - {  
1471 - return;  
1472 - }  
1473 -  
1474 - _isPicOrVideo = YES;  
1475 -  
1476 - AVURLAsset *asset = [AVURLAsset assetWithURL:self.videoURL];  
1477 -  
1478 - //获取视频总时长  
1479 - Float64 duration = CMTimeGetSeconds(asset.duration);  
1480 -  
1481 - self.currentVideoTimeLength = duration;  
1482 -  
1483 -// // 初始化AVPlayer  
1484 -// self.videoPreviewContainerView = [[UIView alloc] init];  
1485 -//  
1486 -// self.videoPreviewContainerView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);  
1487 -// self.videoPreviewContainerView.backgroundColor = [UIColor blackColor];  
1488 -  
1489 - self.playerItem = [AVPlayerItem playerItemWithAsset:asset];  
1490 - self.player = [[AVPlayer alloc] initWithPlayerItem:_playerItem];  
1491 - self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];  
1492 - self.playerLayer.frame = CGRectMake(0, 0, kCameraScreenWidth, kCameraScreenHeight);  
1493 - self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;  
1494 - self.playerLayer.hidden = NO;  
1495 -  
1496 - [self.view.layer addSublayer:self.playerLayer];  
1497 -  
1498 - // 其余UI布局设置  
1499 -// [self.view addSubview:self.videoPreviewContainerView];  
1500 -// [self.view bringSubviewToFront:self.videoPreviewContainerView];  
1501 -  
1502 -// [self.view.layer qmui_bringSublayerToFront:self.playerLayer];  
1503 - //更改  
1504 - if (self.playerLayer.superlayer == self.view.layer) {  
1505 - [self.playerLayer removeFromSuperlayer];  
1506 - [self.view.layer insertSublayer:self.playerLayer atIndex:(unsigned)self.view.layer.sublayers.count];  
1507 - }  
1508 -  
1509 - self.captureVideoPreviewLayer.hidden = YES;  
1510 - [self.view bringSubviewToFront:self.cancelButton];  
1511 - [self.view bringSubviewToFront:self.confirmButton];  
1512 - [self.cameraButton setHidden:YES];  
1513 - [self.closeButton setHidden:YES];  
1514 - [self.rotateCameraButton setHidden:YES];  
1515 - [self.flashButton setHidden:YES];  
1516 - [self.cancelButton setHidden:NO];  
1517 - [self.confirmButton setHidden:NO];  
1518 - self.captureVideoPreviewLayer.hidden = YES;  
1519 -  
1520 - // 重复播放预览视频  
1521 - [self addNotificationWithPlayerItem];  
1522 -  
1523 - // 开始播放  
1524 - [self.player play];  
1525 -}  
1526 -  
1527 -/**  
1528 - * 截取指定时间的视频缩略图  
1529 - *  
1530 - * @param timeBySecond 时间点,单位:s  
1531 - */  
1532 -- (UIImage *)thumbnailImageRequestWithVideoUrl:(NSURL *)videoUrl andTime:(CGFloat)timeBySecond  
1533 -{  
1534 - if (self.videoURL == nil)  
1535 - {  
1536 - return nil;  
1537 - }  
1538 -  
1539 - AVURLAsset *urlAsset = [AVURLAsset assetWithURL:videoUrl];  
1540 -  
1541 - //根据AVURLAsset创建AVAssetImageGenerator  
1542 - AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:urlAsset];  
1543 - /*截图  
1544 - * requestTime:缩略图创建时间  
1545 - * actualTime:缩略图实际生成的时间  
1546 - */  
1547 - NSError *error = nil;  
1548 - CMTime requestTime = CMTimeMakeWithSeconds(timeBySecond, 10); //CMTime是表示电影时间信息的结构体,第一个参数表示是视频第几秒,第二个参数表示每秒帧数.(如果要活的某一秒的第几帧可以使用CMTimeMake方法)  
1549 - CMTime actualTime;  
1550 - CGImageRef cgImage = [imageGenerator copyCGImageAtTime:requestTime actualTime:&actualTime error:&error];  
1551 - if(error)  
1552 - {  
1553 - NSLog(@"截取视频缩略图时发生错误,错误信息:%@", error.localizedDescription);  
1554 - return nil;  
1555 - }  
1556 -  
1557 - CMTimeShow(actualTime);  
1558 - UIImage *image = [UIImage imageWithCGImage:cgImage];  
1559 - CGImageRelease(cgImage);  
1560 -  
1561 - UIImage *finalImage = nil;  
1562 - if (self.shootingOrientation == UIDeviceOrientationLandscapeRight)  
1563 - {  
1564 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationDown];  
1565 - }  
1566 - else if (self.shootingOrientation == UIDeviceOrientationLandscapeLeft)  
1567 - {  
1568 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationUp];  
1569 - }  
1570 - else if (self.shootingOrientation == UIDeviceOrientationPortraitUpsideDown)  
1571 - {  
1572 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationLeft];  
1573 - }  
1574 - else  
1575 - {  
1576 - finalImage = [self rotateImage:image withOrientation:UIImageOrientationRight];  
1577 - }  
1578 -  
1579 - return finalImage;  
1580 -}  
1581 -  
1582 -/**  
1583 - * 图片旋转  
1584 - */  
1585 -- (UIImage *)rotateImage:(UIImage *)image withOrientation:(UIImageOrientation)orientation  
1586 -{  
1587 - long double rotate = 0.0;  
1588 - CGRect rect;  
1589 - float translateX = 0;  
1590 - float translateY = 0;  
1591 - float scaleX = 1.0;  
1592 - float scaleY = 1.0;  
1593 -  
1594 - switch (orientation)  
1595 - {  
1596 - case UIImageOrientationLeft:  
1597 - rotate = M_PI_2;  
1598 - rect = CGRectMake(0, 0, image.size.height, image.size.width);  
1599 - translateX = 0;  
1600 - translateY = -rect.size.width;  
1601 - scaleY = rect.size.width/rect.size.height;  
1602 - scaleX = rect.size.height/rect.size.width;  
1603 - break;  
1604 - case UIImageOrientationRight:  
1605 - rotate = 3 * M_PI_2;  
1606 - rect = CGRectMake(0, 0, image.size.height, image.size.width);  
1607 - translateX = -rect.size.height;  
1608 - translateY = 0;  
1609 - scaleY = rect.size.width/rect.size.height;  
1610 - scaleX = rect.size.height/rect.size.width;  
1611 - break;  
1612 - case UIImageOrientationDown:  
1613 - rotate = M_PI;  
1614 - rect = CGRectMake(0, 0, image.size.width, image.size.height);  
1615 - translateX = -rect.size.width;  
1616 - translateY = -rect.size.height;  
1617 - break;  
1618 - default:  
1619 - rotate = 0.0;  
1620 - rect = CGRectMake(0, 0, image.size.width, image.size.height);  
1621 - translateX = 0;  
1622 - translateY = 0;  
1623 - break;  
1624 - }  
1625 -  
1626 - UIGraphicsBeginImageContext(rect.size);  
1627 - CGContextRef context = UIGraphicsGetCurrentContext();  
1628 - //做CTM变换  
1629 - CGContextTranslateCTM(context, 0.0, rect.size.height);  
1630 - CGContextScaleCTM(context, 1.0, -1.0);  
1631 - CGContextRotateCTM(context, rotate);  
1632 - CGContextTranslateCTM(context, translateX, translateY);  
1633 -  
1634 - CGContextScaleCTM(context, scaleX, scaleY);  
1635 - //绘制图片  
1636 - CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);  
1637 -  
1638 - UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();  
1639 -  
1640 - return newPic;  
1641 -}  
1642 -  
1643 -#pragma mark - 截取视频方法  
1644 -  
1645 -- (void)cropWithVideoUrlStr:(NSURL *)videoUrl start:(CGFloat)startTime end:(CGFloat)endTime completion:(void (^)(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess))completionHandle  
1646 -{  
1647 - AVURLAsset *asset =[[AVURLAsset alloc] initWithURL:videoUrl options:nil];  
1648 -  
1649 - //获取视频总时长  
1650 - Float64 duration = CMTimeGetSeconds(asset.duration);  
1651 -  
1652 - if (duration > VIDEO_RECORDER_MAX_TIME)  
1653 - {  
1654 - duration = VIDEO_RECORDER_MAX_TIME;  
1655 - }  
1656 -  
1657 - startTime = 0;  
1658 - endTime = duration;  
1659 -  
1660 - NSString *outputFilePath = [self createVideoFilePath];  
1661 - NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];  
1662 -  
1663 - NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];  
1664 - if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality])  
1665 - {  
1666 -  
1667 - AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]  
1668 - initWithAsset:asset presetName:AVAssetExportPresetPassthrough];  
1669 -  
1670 - NSURL *outputURL = outputFileUrl;  
1671 -  
1672 - exportSession.outputURL = outputURL;  
1673 - exportSession.outputFileType = AVFileTypeMPEG4;  
1674 - exportSession.shouldOptimizeForNetworkUse = YES;  
1675 -  
1676 - CMTime start = CMTimeMakeWithSeconds(startTime, asset.duration.timescale);  
1677 - CMTime duration = CMTimeMakeWithSeconds(endTime - startTime,asset.duration.timescale);  
1678 - CMTimeRange range = CMTimeRangeMake(start, duration);  
1679 - exportSession.timeRange = range;  
1680 -  
1681 - [exportSession exportAsynchronouslyWithCompletionHandler:^{  
1682 - switch ([exportSession status]) {  
1683 - case AVAssetExportSessionStatusFailed:  
1684 - {  
1685 - NSLog(@"合成失败:%@", [[exportSession error] description]);  
1686 - completionHandle(outputURL, endTime, NO);  
1687 - }  
1688 - break;  
1689 - case AVAssetExportSessionStatusCancelled:  
1690 - {  
1691 - completionHandle(outputURL, endTime, NO);  
1692 - }  
1693 - break;  
1694 - case AVAssetExportSessionStatusCompleted:  
1695 - {  
1696 - completionHandle(outputURL, endTime, YES);  
1697 - }  
1698 - break;  
1699 - default:  
1700 - {  
1701 - completionHandle(outputURL, endTime, NO);  
1702 - } break;  
1703 - }  
1704 - }];  
1705 - }  
1706 -}  
1707 -  
1708 -#pragma mark - 预览视频通知  
1709 -/**  
1710 - * 添加播放器通知  
1711 - */  
1712 --(void)addNotificationWithPlayerItem  
1713 -{  
1714 - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playVideoFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];  
1715 -}  
1716 -  
1717 --(void)removePlayerItemNotification  
1718 -{  
1719 - [[NSNotificationCenter defaultCenter] removeObserver:self];  
1720 -}  
1721 -  
1722 -/**  
1723 - * 播放完成通知  
1724 - *  
1725 - * @param notification 通知对象  
1726 - */  
1727 --(void)playVideoFinished:(NSNotification *)notification  
1728 -{  
1729 - // NSLog(@"视频播放完成.");  
1730 -  
1731 - // 播放完成后重复播放  
1732 - // 跳到最新的时间点开始播放  
1733 - [self.player seekToTime:CMTimeMake(0, 1)];  
1734 - [self.player play];  
1735 -}  
1736 -  
1737 -#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate AVCaptureAudioDataOutputSampleBufferDelegate  
1738 -  
1739 -- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection  
1740 -{  
1741 - if (_isRotatingCamera)  
1742 - {  
1743 - return;  
1744 - }  
1745 -  
1746 - @autoreleasepool  
1747 - {  
1748 - //视频  
1749 - if (connection == [self.videoOutput connectionWithMediaType:AVMediaTypeVideo])  
1750 - {  
1751 - @synchronized(self)  
1752 - {  
1753 - if (_isShooting)  
1754 - {  
1755 - [self appendSampleBuffer:sampleBuffer ofMediaType:AVMediaTypeVideo];  
1756 - }  
1757 - }  
1758 - }  
1759 -  
1760 - //音频  
1761 - if (connection == [self.audioOutput connectionWithMediaType:AVMediaTypeAudio])  
1762 - {  
1763 - @synchronized(self)  
1764 - {  
1765 - if (_isShooting)  
1766 - {  
1767 - [self appendSampleBuffer:sampleBuffer ofMediaType:AVMediaTypeAudio];  
1768 - }  
1769 - }  
1770 - }  
1771 - }  
1772 -}  
1773 -  
1774 -  
1775 -/**  
1776 - * 开始写入数据  
1777 - */  
1778 -- (void)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer ofMediaType:(NSString *)mediaType  
1779 -{  
1780 - if (sampleBuffer == NULL)  
1781 - {  
1782 - NSLog(@"empty sampleBuffer");  
1783 - return;  
1784 - }  
1785 -  
1786 - // CFRetain(sampleBuffer);  
1787 - // dispatch_async(self.videoQueue, ^{  
1788 - @autoreleasepool  
1789 - {  
1790 - if (!self.canWrite && mediaType == AVMediaTypeVideo)  
1791 - {  
1792 - [self.assetWriter startWriting];  
1793 - [self.assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];  
1794 - self.canWrite = YES;  
1795 - }  
1796 -  
1797 - //写入视频数据  
1798 - if (mediaType == AVMediaTypeVideo)  
1799 - {  
1800 - if (self.assetWriterVideoInput.readyForMoreMediaData)  
1801 - {  
1802 - BOOL success = [self.assetWriterVideoInput appendSampleBuffer:sampleBuffer];  
1803 - if (!success)  
1804 - {  
1805 - @synchronized (self)  
1806 - {  
1807 - [self stopVideoRecorder];  
1808 - }  
1809 - }  
1810 - }  
1811 - }  
1812 -  
1813 - //写入音频数据  
1814 - if (mediaType == AVMediaTypeAudio)  
1815 - {  
1816 - if (self.assetWriterAudioInput.readyForMoreMediaData)  
1817 - {  
1818 - BOOL success = [self.assetWriterAudioInput appendSampleBuffer:sampleBuffer];  
1819 - if (!success)  
1820 - {  
1821 - @synchronized (self)  
1822 - {  
1823 - [self stopVideoRecorder];  
1824 - }  
1825 - }  
1826 - }  
1827 - }  
1828 -  
1829 - // CFRelease(sampleBuffer);  
1830 - }  
1831 - // });  
1832 -}  
1833 -  
1834 -#pragma mark - 摄像头聚焦,与缩放  
1835 -  
1836 -/**  
1837 - * 添加点按手势  
1838 - */  
1839 -- (void)addTapGenstureRecognizerForCamera  
1840 -{  
1841 - UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];  
1842 -  
1843 - pinchGesture.delegate = self;  
1844 -  
1845 - [self.view addGestureRecognizer:pinchGesture];  
1846 -}  
1847 -  
1848 -/**  
1849 - * 点击屏幕,聚焦事件  
1850 - */  
1851 -- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event  
1852 -{  
1853 - // 不聚焦的情况:聚焦中,旋转摄像头中,查看录制的视频中,查看照片中  
1854 - if (_isFocusing || touches.count == 0 || _isRotatingCamera || _videoPreviewContainerView || _photoPreviewImageView)  
1855 - {  
1856 - return;  
1857 - }  
1858 -  
1859 - UITouch *touch = nil;  
1860 -  
1861 - for (UITouch *t in touches)  
1862 - {  
1863 - touch = t;  
1864 - break;  
1865 - }  
1866 -  
1867 - CGPoint point = [touch locationInView:self.view];;  
1868 -  
1869 - if (point.y > CGRectGetMaxY(self.tipLabel.frame))  
1870 - {  
1871 - return;  
1872 - }  
1873 -  
1874 - [self setFocusCursorWithPoint:point];  
1875 -}  
1876 -  
1877 -/**  
1878 - * 设置聚焦光标位置  
1879 - *  
1880 - * @param point 光标位置  
1881 - */  
1882 -- (void)setFocusCursorWithPoint:(CGPoint)point  
1883 -{  
1884 - self.isFocusing = YES;  
1885 -  
1886 - self.focusImageView.center = point;  
1887 - self.focusImageView.transform = CGAffineTransformMakeScale(1.5, 1.5);  
1888 - self.focusImageView.alpha = 1;  
1889 -  
1890 - //将UI坐标转化为摄像头坐标  
1891 - CGPoint cameraPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point];  
1892 - [self focusWithPoint:cameraPoint];  
1893 -  
1894 - __weak typeof(self) weakSelf = self;  
1895 - [UIView animateWithDuration:1.0 animations:^{  
1896 -  
1897 - weakSelf.focusImageView.transform = CGAffineTransformIdentity;  
1898 -  
1899 - } completion:^(BOOL finished) {  
1900 -  
1901 - weakSelf.focusImageView.alpha = 0;  
1902 - weakSelf.isFocusing = NO;  
1903 -  
1904 - }];  
1905 -}  
1906 -  
1907 -/**  
1908 - * 设置聚焦点  
1909 - *  
1910 - * @param point 聚焦点  
1911 - */  
1912 --(void)focusWithPoint:(CGPoint)point  
1913 -{  
1914 - [self changeDeviceProperty:^(AVCaptureDevice *captureDevice)  
1915 - {  
1916 - // 聚焦  
1917 - if ([captureDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus])  
1918 - {  
1919 - [captureDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];  
1920 - }  
1921 - if ([captureDevice isFocusPointOfInterestSupported])  
1922 - {  
1923 - [captureDevice setFocusPointOfInterest:point];  
1924 - }  
1925 - // 曝光  
1926 - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure])  
1927 - {  
1928 - [captureDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];  
1929 - }  
1930 - if ([captureDevice isExposurePointOfInterestSupported])  
1931 - {  
1932 - [captureDevice setExposurePointOfInterest:point];  
1933 - }  
1934 - }];  
1935 -}  
1936 -  
1937 -- (void)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer  
1938 -{  
1939 - if (_isShooting)  
1940 - {  
1941 - return;  
1942 - }  
1943 -  
1944 - BOOL allTouchesAreOnTheCaptureVideoPreviewLayer = YES;  
1945 -  
1946 - NSUInteger numTouches = [recognizer numberOfTouches], i;  
1947 - for ( i = 0; i < numTouches; ++i)  
1948 - {  
1949 - CGPoint location = [recognizer locationOfTouch:i inView:self.view];  
1950 - CGPoint convertedLocation = [self.captureVideoPreviewLayer convertPoint:location fromLayer:self.captureVideoPreviewLayer.superlayer];  
1951 - if (![self.captureVideoPreviewLayer containsPoint:convertedLocation])  
1952 - {  
1953 - allTouchesAreOnTheCaptureVideoPreviewLayer = NO;  
1954 - break;  
1955 - }  
1956 - }  
1957 -  
1958 - if (allTouchesAreOnTheCaptureVideoPreviewLayer)  
1959 - {  
1960 - self.effectiveScale = self.beginGestureScale * recognizer.scale;  
1961 - if (self.effectiveScale < 1.0f)  
1962 - {  
1963 - self.effectiveScale = 1.0f;  
1964 - }  
1965 -  
1966 - // NSLog(@"%f-------------->%f------------recognizerScale%f", self.effectiveScale, self.beginGestureScale, recognizer.scale);  
1967 -  
1968 - CGFloat imageMaxScaleAndCropFactor = [[self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor];  
1969 -  
1970 - // NSLog(@"%f", imageMaxScaleAndCropFactor);  
1971 - if (self.effectiveScale > imageMaxScaleAndCropFactor)  
1972 - {  
1973 - self.effectiveScale = imageMaxScaleAndCropFactor;  
1974 - }  
1975 -  
1976 - [self setCaptureVideoPreviewLayerTransformWithScale:self.effectiveScale];  
1977 - }  
1978 -}  
1979 -  
1980 -- (void)setCaptureVideoPreviewLayerTransformWithScale:(CGFloat)scale  
1981 -{  
1982 - self.effectiveScale = scale;  
1983 - [CATransaction begin];  
1984 - [CATransaction setAnimationDuration:0.25f]; //时长最好低于 START_VIDEO_ANIMATION_DURATION  
1985 - [self.captureVideoPreviewLayer setAffineTransform:CGAffineTransformMakeScale(scale, scale)];  
1986 - [CATransaction commit];  
1987 -}  
1988 -  
1989 -#pragma mark - UIGestureRecognizerDelegate  
1990 -  
1991 -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer  
1992 -{  
1993 - if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]])  
1994 - {  
1995 - self.beginGestureScale = self.effectiveScale;  
1996 - }  
1997 -  
1998 - return YES;  
1999 -}  
2000 -  
2001 -#pragma mark - 重力感应相关  
2002 -  
2003 -/**  
2004 - * 开始监听屏幕方向  
2005 - */  
2006 -- (void)startUpdateAccelerometer  
2007 -{  
2008 - if ([self.motionManager isAccelerometerAvailable] == YES)  
2009 - {  
2010 - //回调会一直调用,建议获取到就调用下面的停止方法,需要再重新开始,当然如果需求是实时不间断的话可以等离开页面之后再stop  
2011 - [self.motionManager setAccelerometerUpdateInterval:1.0];  
2012 - [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)  
2013 - {  
2014 - double x = accelerometerData.acceleration.x;  
2015 - double y = accelerometerData.acceleration.y;  
2016 - if (fabs(y) >= fabs(x))  
2017 - {  
2018 - if (y >= 0)  
2019 - {  
2020 - // Down  
2021 - NSLog(@"Down");  
2022 - self->_shootingOrientation = UIDeviceOrientationPortraitUpsideDown;  
2023 - }  
2024 - else  
2025 - {  
2026 - // Portrait  
2027 - NSLog(@"Portrait");  
2028 - self->_shootingOrientation = UIDeviceOrientationPortrait;  
2029 - }  
2030 - }  
2031 - else  
2032 - {  
2033 - if (x >= 0)  
2034 - {  
2035 - // Right  
2036 - NSLog(@"Right");  
2037 - self->_shootingOrientation = UIDeviceOrientationLandscapeRight;  
2038 - }  
2039 - else  
2040 - {  
2041 - // Left  
2042 - NSLog(@"Left");  
2043 - self->_shootingOrientation = UIDeviceOrientationLandscapeLeft;  
2044 - }  
2045 - }  
2046 - }];  
2047 - }  
2048 -}  
2049 -  
2050 -/**  
2051 - * 停止监听屏幕方向  
2052 - */  
2053 -- (void)stopUpdateAccelerometer  
2054 -{  
2055 - if ([self.motionManager isAccelerometerActive] == YES)  
2056 - {  
2057 - [self.motionManager stopAccelerometerUpdates];  
2058 - _motionManager = nil;  
2059 - }  
2060 -}  
2061 -  
2062 -#pragma mark - 判断是否有权限  
2063 -  
2064 -/**  
2065 - * 请求权限  
2066 - */  
2067 -- (void)requestAuthorizationForVideo  
2068 -{  
2069 - __weak typeof(self) weakSelf = self;  
2070 -  
2071 - // 请求相机权限  
2072 - AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];  
2073 - if (videoAuthStatus != AVAuthorizationStatusAuthorized)  
2074 - {  
2075 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
2076 -  
2077 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
2078 - if (appName == nil)  
2079 - {  
2080 - appName = @"APP";  
2081 - }  
2082 - NSString *message = [NSString stringWithFormat:@"请在iPhone的“设置-隐私”选项中,允许%@访问你的相册,相机和麦克风。", appName];  
2083 -  
2084 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];//无法拍摄  
2085 -  
2086 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
2087 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
2088 - }];  
2089 -  
2090 - [alertController addAction:okAction];  
2091 - [self presentViewController:alertController animated:YES completion:nil];  
2092 - }  
2093 -  
2094 - // 请求麦克风权限  
2095 - AVAuthorizationStatus audioAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];  
2096 - if (audioAuthStatus != AVAuthorizationStatusAuthorized)  
2097 - {  
2098 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
2099 -  
2100 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
2101 - if (appName == nil)  
2102 - {  
2103 - appName = @"APP";  
2104 - }  
2105 - NSString *message = [NSString stringWithFormat:@"请在iPhone的“设置-隐私“选项中,允许%@访问你的相机,相册和麦克风。", appName];//[NSString stringWithFormat:@"请在iPhone的““设置-隐私””选项中, 允许%@访问你的麦克风?", appName];  
2106 -  
2107 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];  
2108 -  
2109 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
2110 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
2111 - }];  
2112 -  
2113 - [alertController addAction:okAction];  
2114 -  
2115 - [self presentViewController:alertController animated:YES completion:nil];  
2116 - }  
2117 -  
2118 -  
2119 -}  
2120 -  
2121 -- (void)requestAuthorizationForPhotoLibrary  
2122 -{  
2123 - __weak typeof(self) weakSelf = self;  
2124 -  
2125 - // 请求照片权限  
2126 - [XFPhotoLibraryManager requestALAssetsLibraryAuthorizationWithCompletion:^(Boolean isAuth) {  
2127 -  
2128 - if (!isAuth)  
2129 - {  
2130 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
2131 -  
2132 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
2133 - if (appName == nil)  
2134 - {  
2135 - appName = @"APP";  
2136 - }  
2137 - NSString *message = [NSString stringWithFormat:@"请在iPhone的""设置-隐私-相册""中允许%@访问相册", appName];//@"允许%@访问你的相册?"  
2138 -  
2139 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];  
2140 -  
2141 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
2142 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
2143 - weakSelf.isAlertShow = NO;  
2144 - }];  
2145 -  
2146 -// UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
2147 -// NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];  
2148 -// if ([[UIApplication sharedApplication] canOpenURL:url])  
2149 -// {  
2150 -// [[UIApplication sharedApplication] openURL:url];  
2151 -// [weakSelf dismissViewControllerAnimated:YES completion:nil];  
2152 -// }  
2153 -// }];  
2154 -  
2155 - [alertController addAction:okAction];  
2156 -// [alertController addAction:setAction];  
2157 -  
2158 - [self presentViewController:alertController animated:YES completion:nil];  
2159 - self->_isAlertShow = YES;  
2160 -  
2161 - }  
2162 - }];  
2163 -}  
2164 -  
2165 -- (void)requestAuthCamera  
2166 -{  
2167 - __weak typeof(self) weakSelf = self;  
2168 -  
2169 - // 请求相机权限  
2170 - AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];  
2171 - if (videoAuthStatus != AVAuthorizationStatusAuthorized)  
2172 - {  
2173 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
2174 -  
2175 - NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
2176 - if (appName == nil)  
2177 - {  
2178 - appName = @"APP";  
2179 - }  
2180 - NSString *message = [NSString stringWithFormat:@"请在iPhone的“设置-隐私”选项中,允许%@访问你的摄像头和麦克风。", appName];  
2181 -  
2182 - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];//无法拍摄  
2183 -  
2184 - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {  
2185 - [weakSelf dismissViewControllerAnimated:YES completion:nil];  
2186 - }];  
2187 -  
2188 - [alertController addAction:okAction];  
2189 - [self presentViewController:alertController animated:YES completion:nil];  
2190 - }  
2191 -}  
2192 -  
2193 -#pragma mark - 进入前后台监听  
2194 -  
2195 -- (void)applicationBecomeActive  
2196 -{  
2197 - if (self.player) {  
2198 - [self.player play];  
2199 - }  
2200 -}  
2201 -  
2202 -- (void)enterBackgroundNotification  
2203 -{  
2204 - if (_isPicOrVideo) {  
2205 - //已经拍照或者录视频 不dismiss  
2206 - }else  
2207 - {//没有拍照或者录制视频 dismiss  
2208 - if (!_isAlertShow) {  
2209 - [self dismissViewControllerAnimated:YES completion:nil];  
2210 - }  
2211 - }  
2212 -}  
2213 -  
2214 -@end  
CNLiveAVCamera/Classes/XFAVCamera/XFPhotoLibraryManager.h deleted 100644 → 0
1 -//  
2 -// XFPhotoLibraryManager.h  
3 -// WeChatVideoDemo  
4 -//  
5 -// Created by xf-ling on 2017/6/15.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import <UIKit/UIKit.h>  
10 -#import <Photos/Photos.h>  
11 -  
12 -typedef void(^RequestAssetsLibraryAuthCompletion)(Boolean isAuth);  
13 -typedef void(^SavePhotoCompletionBlock)(UIImage *image, NSError *error);  
14 -typedef void(^SaveVideoCompletionBlock)(NSURL *vedioUrl, NSError *error);  
15 -  
16 -//zx  
17 -typedef void(^GetCameraVideoCompletionBlock)(PHAsset *asset,NSURL *vedioUrl, NSError *error);  
18 -  
19 -  
20 -@interface XFPhotoLibraryManager : NSObject  
21 -  
22 -/**  
23 - * 请求照片权限,注意,强烈要求用户获得照片权限,否则视频写入照片会有崩溃  
24 - */  
25 -+ (void)requestALAssetsLibraryAuthorizationWithCompletion:(RequestAssetsLibraryAuthCompletion) requestAssetsLibraryAuthCompletion;  
26 -  
27 -/**  
28 - * 保存照片  
29 - *  
30 - * @param image UImage  
31 - * @param assetCollectionName 相册名字,不填默认为app名字+相册  
32 - */  
33 -+ (void)savePhotoWithImage:(UIImage *)image andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(SavePhotoCompletionBlock)savePhotoCompletionBlock;  
34 -  
35 -/**  
36 - * 保存视频  
37 - *  
38 - * @param videoUrl 视频地址  
39 - * @param assetCollectionName 相册名字,不填默认为app名字  
40 - */  
41 -+ (void)saveVideoWithVideoUrl:(NSURL *)videoUrl andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(SaveVideoCompletionBlock)saveVideoCompletionBlock;  
42 -  
43 -  
44 -/**  
45 - * zx保存视频  
46 - *  
47 - * @param videoUrl 视频地址  
48 - * @param assetCollectionName 相册名字,不填默认为app名字  
49 - */  
50 -+ (void)zx_saveVideoWithVideoUrl:(NSURL *)videoUrl andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(GetCameraVideoCompletionBlock)getCameraVideoCompletionBlock;  
51 -@end  
CNLiveAVCamera/Classes/XFAVCamera/XFPhotoLibraryManager.m deleted 100644 → 0
1 -//  
2 -// XFPhotoLibraryManager.m  
3 -// WeChatVideoDemo  
4 -//  
5 -// Created by xf-ling on 2017/6/15.  
6 -// Copyright © 2017年 LXF. All rights reserved.  
7 -//  
8 -  
9 -#import "XFPhotoLibraryManager.h"  
10 -#import <Photos/Photos.h>  
11 -#import <AssetsLibrary/AssetsLibrary.h>  
12 -  
13 -@implementation XFPhotoLibraryManager  
14 -  
15 -/**  
16 - * 请求照片权限,注意,强烈要求用户获得照片权限,否则视频写入照片会有崩溃  
17 - */  
18 -+ (void)requestALAssetsLibraryAuthorizationWithCompletion:(RequestAssetsLibraryAuthCompletion)requestAssetsLibraryAuthCompletion  
19 -{  
20 - PHAuthorizationStatus authStatus = [PHPhotoLibrary authorizationStatus];  
21 - if (authStatus != PHAuthorizationStatusAuthorized) // 未授权  
22 - {  
23 - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {  
24 - if (status != PHAuthorizationStatusAuthorized) //已授权  
25 - {  
26 - NSLog(@"用户拒绝访问相册!");  
27 - if (requestAssetsLibraryAuthCompletion)  
28 - {  
29 - requestAssetsLibraryAuthCompletion(NO);  
30 - }  
31 - }  
32 - else  
33 - {  
34 - NSLog(@"用户允许访问相册!");  
35 - if (requestAssetsLibraryAuthCompletion)  
36 - {  
37 - requestAssetsLibraryAuthCompletion(YES);  
38 - }  
39 - }  
40 - }];  
41 - }  
42 - else  
43 - {  
44 - // nothing  
45 - }  
46 -}  
47 -  
48 -/**  
49 - * 保存照片  
50 - *  
51 - * @param image UImage  
52 - * @param assetCollectionName 相册名字,不填默认为app名字+相册  
53 - */  
54 -+ (void)savePhotoWithImage:(UIImage *)image andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(SavePhotoCompletionBlock)savePhotoCompletionBlock  
55 -{  
56 - if (assetCollectionName == nil)  
57 - {  
58 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
59 -  
60 - assetCollectionName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
61 -  
62 - if (assetCollectionName == nil)  
63 - {  
64 - assetCollectionName = @"视频相册";  
65 - }  
66 - }  
67 -  
68 - __block NSString *blockAssetCollectionName = assetCollectionName;  
69 - __block UIImage *blockImage = image;  
70 - __block NSString *assetId = nil;  
71 -  
72 - PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];  
73 -  
74 - // 1. 存储图片到"相机胶卷"  
75 - [library performChanges:^{ // 这个block里保存一些"修改"性质的代码  
76 - // 新建一个PHAssetCreationRequest对象, 保存图片到"相机胶卷"  
77 - // 返回PHAsset(图片)的字符串标识  
78 - if (@available(iOS 9.0, *)) {  
79 - assetId = [PHAssetCreationRequest creationRequestForAssetFromImage:blockImage].placeholderForCreatedAsset.localIdentifier;  
80 - } else {  
81 - // Fallback on earlier versions  
82 - }  
83 - } completionHandler:^(BOOL success, NSError * _Nullable error) {  
84 - if (error) {  
85 - NSLog(@"error1%@", error);  
86 - return;  
87 - }  
88 -  
89 - NSLog(@"成功保存图片到相机胶卷中");  
90 -  
91 - // 2. 获得相册对象  
92 - // 获取曾经创建过的自定义视频相册名字  
93 - PHAssetCollection *createdAssetCollection = nil;  
94 - PHFetchResult <PHAssetCollection*> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];  
95 - for (PHAssetCollection *assetCollection in assetCollections)  
96 - {  
97 - if ([assetCollection.localizedTitle isEqualToString:blockAssetCollectionName])  
98 - {  
99 - createdAssetCollection = assetCollection;  
100 - break;  
101 - }  
102 - }  
103 -  
104 - //如果这个自定义框架没有创建过  
105 - if (createdAssetCollection == nil)  
106 - {  
107 - //创建新的[自定义的 Album](相簿\相册)  
108 - [library performChangesAndWait:^{  
109 -  
110 - assetId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:blockAssetCollectionName].placeholderForCreatedAssetCollection.localIdentifier;  
111 -  
112 - } error:&error];  
113 -  
114 - NSLog(@"error2: %@", error);  
115 -  
116 - //抓取刚创建完的视频相册对象  
117 - createdAssetCollection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetId] options:nil].firstObject;  
118 -  
119 - }  
120 -  
121 - // 3. 将“相机胶卷”中的图片添加到新的相册  
122 -// [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{  
123 -// PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];  
124 -//  
125 -// // 根据唯一标示获得相片对象  
126 -// PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject;  
127 -// // 添加图片到相册中  
128 -// [request addAssets:@[asset]];  
129 -// } completionHandler:^(BOOL success, NSError * _Nullable error) {  
130 -// if (error)  
131 -// {  
132 -// NSLog(@"添加图片到相册中失败");  
133 -// return;  
134 -// }  
135 -//  
136 -// NSLog(@"成功添加图片到相册中");  
137 -// }];  
138 -  
139 - // 将【Camera Roll】(相机胶卷)的视频 添加到【自定义Album】(相簿\相册)中  
140 - [library performChangesAndWait:^{  
141 - PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];  
142 -  
143 - [request addAssets:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]];  
144 -  
145 - } error:&error];  
146 - NSLog(@"error3: %@", error);  
147 - // 提示信息  
148 - if (savePhotoCompletionBlock)  
149 - {  
150 - if (error)  
151 - {  
152 - NSLog(@"保存照片失败!");  
153 -  
154 - savePhotoCompletionBlock(nil, error);  
155 - }  
156 - else  
157 - {  
158 - NSLog(@"保存照片成功!");  
159 -  
160 - savePhotoCompletionBlock(blockImage, nil);  
161 - }  
162 - }  
163 -  
164 - }];  
165 -}  
166 -  
167 -/**  
168 - * 保存视频  
169 - *  
170 - * @param videoUrl 视频地址  
171 - * @param assetCollectionName 相册名字,不填默认为app名字+视频  
172 - */  
173 -+ (void)saveVideoWithVideoUrl:(NSURL *)videoUrl andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(SaveVideoCompletionBlock)saveVideoCompletionBlock  
174 -{  
175 - if (assetCollectionName == nil)  
176 - {  
177 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
178 -  
179 - assetCollectionName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
180 -  
181 - if (assetCollectionName == nil)  
182 - {  
183 - assetCollectionName = @"视频相册";  
184 - }  
185 - }  
186 -  
187 - __block NSString *blockAssetCollectionName = assetCollectionName;  
188 - __block NSURL *blockVideoUrl = videoUrl;  
189 - PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];  
190 -  
191 - dispatch_async(dispatch_get_main_queue(), ^{  
192 -  
193 - NSError *error = nil;  
194 - __block NSString *assetId = nil;  
195 - __block NSString *assetCollectionId = nil;  
196 -  
197 - // 保存视频到【Camera Roll】(相机胶卷)  
198 - [library performChangesAndWait:^{  
199 -  
200 - assetId = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:blockVideoUrl].placeholderForCreatedAsset.localIdentifier;  
201 -  
202 - } error:&error];  
203 -  
204 - NSLog(@"error1: %@", error);  
205 -  
206 - // 获取曾经创建过的自定义视频相册名字  
207 - PHAssetCollection *createdAssetCollection = nil;  
208 - PHFetchResult <PHAssetCollection*> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];  
209 - for (PHAssetCollection *assetCollection in assetCollections)  
210 - {  
211 - if ([assetCollection.localizedTitle isEqualToString:blockAssetCollectionName])  
212 - {  
213 - createdAssetCollection = assetCollection;  
214 - break;  
215 - }  
216 - }  
217 -  
218 - //如果这个自定义框架没有创建过  
219 - if (createdAssetCollection == nil)  
220 - {  
221 - //创建新的[自定义的 Album](相簿\相册)  
222 - [library performChangesAndWait:^{  
223 -  
224 - assetCollectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:blockAssetCollectionName].placeholderForCreatedAssetCollection.localIdentifier;  
225 -  
226 - } error:&error];  
227 -  
228 - NSLog(@"error2: %@", error);  
229 -  
230 - //抓取刚创建完的视频相册对象  
231 - createdAssetCollection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionId] options:nil].firstObject;  
232 -  
233 - }  
234 -  
235 - // 将【Camera Roll】(相机胶卷)的视频 添加到【自定义Album】(相簿\相册)中  
236 - [library performChangesAndWait:^{  
237 - PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];  
238 - [request addAssets:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]];  
239 -  
240 - } error:&error];  
241 - NSLog(@"error3: %@", error);  
242 -  
243 - // 提示信息  
244 - if (saveVideoCompletionBlock)  
245 - {  
246 - if (error)  
247 - {  
248 - NSLog(@"保存视频失败!");  
249 -  
250 - saveVideoCompletionBlock(nil, error);  
251 - }  
252 - else  
253 - {  
254 - NSLog(@"保存视频成功!");  
255 -  
256 - saveVideoCompletionBlock(blockVideoUrl, nil);  
257 - }  
258 - }  
259 -  
260 - });  
261 -}  
262 -  
263 -+ (void)zx_saveVideoWithVideoUrl:(NSURL *)videoUrl andAssetCollectionName:(NSString *)assetCollectionName withCompletion:(GetCameraVideoCompletionBlock)getCameraVideoCompletionBlock  
264 -{  
265 - if (assetCollectionName == nil)  
266 - {  
267 - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
268 -  
269 - assetCollectionName = [infoDictionary objectForKey:@"CFBundleDisplayName"];  
270 -  
271 - if (assetCollectionName == nil)  
272 - {  
273 - assetCollectionName = @"视频相册";  
274 - }  
275 - }  
276 -  
277 - __block NSString *blockAssetCollectionName = assetCollectionName;  
278 - __block NSURL *blockVideoUrl = videoUrl;  
279 - PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];  
280 -  
281 - dispatch_async(dispatch_get_main_queue(), ^{  
282 -  
283 - NSError *error = nil;  
284 - __block NSString *assetId = nil;  
285 - __block NSString *assetCollectionId = nil;  
286 -  
287 - // 保存视频到【Camera Roll】(相机胶卷)  
288 - [library performChangesAndWait:^{  
289 -  
290 - assetId = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:blockVideoUrl].placeholderForCreatedAsset.localIdentifier;  
291 -  
292 - } error:&error];  
293 -  
294 - NSLog(@"error1: %@", error);  
295 -  
296 - // 获取曾经创建过的自定义视频相册名字  
297 - PHAssetCollection *createdAssetCollection = nil;  
298 - PHFetchResult <PHAssetCollection*> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];  
299 - for (PHAssetCollection *assetCollection in assetCollections)  
300 - {  
301 - if ([assetCollection.localizedTitle isEqualToString:blockAssetCollectionName])  
302 - {  
303 - createdAssetCollection = assetCollection;  
304 - break;  
305 - }  
306 - }  
307 -  
308 - //如果这个自定义框架没有创建过  
309 - if (createdAssetCollection == nil)  
310 - {  
311 - //创建新的[自定义的 Album](相簿\相册)  
312 - [library performChangesAndWait:^{  
313 -  
314 - assetCollectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:blockAssetCollectionName].placeholderForCreatedAssetCollection.localIdentifier;  
315 -  
316 - } error:&error];  
317 -  
318 - NSLog(@"error2: %@", error);  
319 -  
320 - //抓取刚创建完的视频相册对象  
321 - createdAssetCollection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[assetCollectionId] options:nil].firstObject;  
322 -  
323 - }  
324 -  
325 - // 将【Camera Roll】(相机胶卷)的视频 添加到【自定义Album】(相簿\相册)中  
326 - [library performChangesAndWait:^{  
327 - PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];  
328 - [request addAssets:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]];  
329 -  
330 - } error:&error];  
331 - NSLog(@"error3: %@", error);  
332 -  
333 -  
334 - PHFetchResult<PHAsset *> *res = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];  
335 - PHAsset *asset = res[0];  
336 - NSLog(@"asset:\n%@",asset);  
337 -  
338 - if (getCameraVideoCompletionBlock) {  
339 - if (error)  
340 - {  
341 - getCameraVideoCompletionBlock(nil,nil,error);  
342 - }  
343 - else  
344 - {  
345 - getCameraVideoCompletionBlock(asset,blockVideoUrl,nil);  
346 - }  
347 - }  
348 -  
349 -//  
350 -// // 将【Camera Roll】(相机胶卷)的视频 添加到【自定义Album】(相簿\相册)中  
351 -// [library performChangesAndWait:^{  
352 -// PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdAssetCollection];  
353 -//  
354 -//// PHFetchResult<PHAsset *> *res = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];  
355 -//// PHAsset *asset1 = res[0];  
356 -//// NSLog(@"asset1:\n%@",asset1);  
357 -//  
358 -// [request addAssets:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]];  
359 -//  
360 -// } error:&error];  
361 -// NSLog(@"error3: %@", error);  
362 -//  
363 -// // 提示信息  
364 -// if (saveVideoCompletionBlock)  
365 -// {  
366 -// if (error)  
367 -// {  
368 -// NSLog(@"保存视频失败!");  
369 -//  
370 -// saveVideoCompletionBlock(nil, error);  
371 -// }  
372 -// else  
373 -// {  
374 -// NSLog(@"保存视频成功!");  
375 -//  
376 -// saveVideoCompletionBlock(blockVideoUrl, nil);  
377 -// }  
378 -// }  
379 -  
380 - });  
381 -}  
382 -@end  
Example/CNLiveAVCamera.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 objects = { 7 objects = {
8 8
9 /* Begin PBXBuildFile section */ 9 /* Begin PBXBuildFile section */
  10 + 4D327C57328514E41C80BC95 /* Pods_CNLiveAVCamera_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FA68C9FF1F570173346565 /* Pods_CNLiveAVCamera_Tests.framework */; };
10 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 11 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
11 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 12 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
12 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 13 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
@@ -20,10 +21,9 @@ @@ -20,10 +21,9 @@
20 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 21 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
21 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 22 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
22 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; 23 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
23 - 62962500ECE4CD1C5B1DDD0D /* Pods_CNLiveAVCamera_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48AAEA5EC11292C1A67CDDD7 /* Pods_CNLiveAVCamera_Example.framework */; };  
24 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 24 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; };
25 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; 25 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
26 - BCD57394A56C50847A1D0A30 /* Pods_CNLiveAVCamera_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12855D6E1B2B0DA048CAC16 /* Pods_CNLiveAVCamera_Tests.framework */; }; 26 + CE195475D0896946275F8767 /* Pods_CNLiveAVCamera_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 876F38133C52213CA7BB6367 /* Pods_CNLiveAVCamera_Example.framework */; };
27 /* End PBXBuildFile section */ 27 /* End PBXBuildFile section */
28 28
29 /* Begin PBXContainerItemProxy section */ 29 /* Begin PBXContainerItemProxy section */
@@ -37,10 +37,9 @@ @@ -37,10 +37,9 @@
37 /* End PBXContainerItemProxy section */ 37 /* End PBXContainerItemProxy section */
38 38
39 /* Begin PBXFileReference section */ 39 /* Begin PBXFileReference section */
40 - 084A487B8D91F2EC25B5CF39 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests.debug.xcconfig"; sourceTree = "<group>"; };  
41 - 0DEF7D98D19D939CF6521425 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example.debug.xcconfig"; sourceTree = "<group>"; };  
42 - 35820DA1F6C64F6B7D896139 /* Pods-CNLiveAVCamera_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests.release.xcconfig"; sourceTree = "<group>"; };  
43 - 48AAEA5EC11292C1A67CDDD7 /* Pods_CNLiveAVCamera_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveAVCamera_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 40 + 03D1C9ED998415725CAE8BF3 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example.debug.xcconfig"; sourceTree = "<group>"; };
  41 + 2242358099573105074E8A8D /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
  42 + 263AFF8B2121BC39145CA5EE /* Pods-CNLiveAVCamera_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests.release.xcconfig"; sourceTree = "<group>"; };
44 6003F58A195388D20070C39A /* CNLiveAVCamera_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveAVCamera_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 6003F58A195388D20070C39A /* CNLiveAVCamera_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveAVCamera_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
45 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 44 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
46 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 45 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@@ -62,11 +61,12 @@ @@ -62,11 +61,12 @@
62 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; }; 61 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
63 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 62 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
64 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 63 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
65 - 93BF696255FE00CF6E596D8F /* Pods-CNLiveAVCamera_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example.release.xcconfig"; sourceTree = "<group>"; };  
66 - 9EC6432D35122051E3EAA096 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };  
67 - AD6C2CD543580B3E793C7DA5 /* CNLiveAVCamera.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveAVCamera.podspec; path = ../CNLiveAVCamera.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };  
68 - C12855D6E1B2B0DA048CAC16 /* Pods_CNLiveAVCamera_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveAVCamera_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };  
69 - FA45440BB6994ACA16F686E1 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; }; 64 + 876F38133C52213CA7BB6367 /* Pods_CNLiveAVCamera_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveAVCamera_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  65 + 91D86358FC3A20D099BF20BF /* CNLiveAVCamera.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveAVCamera.podspec; path = ../CNLiveAVCamera.podspec; sourceTree = "<group>"; };
  66 + A08A1D9662A4589773CD2F34 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
  67 + B83BAF65F6BCA4FD64ADC040 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests.debug.xcconfig"; sourceTree = "<group>"; };
  68 + E7FA68C9FF1F570173346565 /* Pods_CNLiveAVCamera_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveAVCamera_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  69 + F64038E6BB292F8CD89CA832 /* Pods-CNLiveAVCamera_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveAVCamera_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example.release.xcconfig"; sourceTree = "<group>"; };
70 /* End PBXFileReference section */ 70 /* End PBXFileReference section */
71 71
72 /* Begin PBXFrameworksBuildPhase section */ 72 /* Begin PBXFrameworksBuildPhase section */
@@ -77,7 +77,7 @@ @@ -77,7 +77,7 @@
77 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 77 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
78 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 78 6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
79 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 79 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
80 - 62962500ECE4CD1C5B1DDD0D /* Pods_CNLiveAVCamera_Example.framework in Frameworks */, 80 + CE195475D0896946275F8767 /* Pods_CNLiveAVCamera_Example.framework in Frameworks */,
81 ); 81 );
82 runOnlyForDeploymentPostprocessing = 0; 82 runOnlyForDeploymentPostprocessing = 0;
83 }; 83 };
@@ -88,24 +88,13 @@ @@ -88,24 +88,13 @@
88 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 88 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
89 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 89 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
90 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, 90 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
91 - BCD57394A56C50847A1D0A30 /* Pods_CNLiveAVCamera_Tests.framework in Frameworks */, 91 + 4D327C57328514E41C80BC95 /* Pods_CNLiveAVCamera_Tests.framework in Frameworks */,
92 ); 92 );
93 runOnlyForDeploymentPostprocessing = 0; 93 runOnlyForDeploymentPostprocessing = 0;
94 }; 94 };
95 /* End PBXFrameworksBuildPhase section */ 95 /* End PBXFrameworksBuildPhase section */
96 96
97 /* Begin PBXGroup section */ 97 /* Begin PBXGroup section */
98 - 05AFF5DE83EFB9FB65E5C744 /* Pods */ = {  
99 - isa = PBXGroup;  
100 - children = (  
101 - 0DEF7D98D19D939CF6521425 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */,  
102 - 93BF696255FE00CF6E596D8F /* Pods-CNLiveAVCamera_Example.release.xcconfig */,  
103 - 084A487B8D91F2EC25B5CF39 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */,  
104 - 35820DA1F6C64F6B7D896139 /* Pods-CNLiveAVCamera_Tests.release.xcconfig */,  
105 - );  
106 - name = Pods;  
107 - sourceTree = "<group>";  
108 - };  
109 6003F581195388D10070C39A = { 98 6003F581195388D10070C39A = {
110 isa = PBXGroup; 99 isa = PBXGroup;
111 children = ( 100 children = (
@@ -114,7 +103,7 @@ @@ -114,7 +103,7 @@
114 6003F5B5195388D20070C39A /* Tests */, 103 6003F5B5195388D20070C39A /* Tests */,
115 6003F58C195388D20070C39A /* Frameworks */, 104 6003F58C195388D20070C39A /* Frameworks */,
116 6003F58B195388D20070C39A /* Products */, 105 6003F58B195388D20070C39A /* Products */,
117 - 05AFF5DE83EFB9FB65E5C744 /* Pods */, 106 + 6981E16BA651A5C0254CA344 /* Pods */,
118 ); 107 );
119 sourceTree = "<group>"; 108 sourceTree = "<group>";
120 }; 109 };
@@ -134,8 +123,8 @@ @@ -134,8 +123,8 @@
134 6003F58F195388D20070C39A /* CoreGraphics.framework */, 123 6003F58F195388D20070C39A /* CoreGraphics.framework */,
135 6003F591195388D20070C39A /* UIKit.framework */, 124 6003F591195388D20070C39A /* UIKit.framework */,
136 6003F5AF195388D20070C39A /* XCTest.framework */, 125 6003F5AF195388D20070C39A /* XCTest.framework */,
137 - 48AAEA5EC11292C1A67CDDD7 /* Pods_CNLiveAVCamera_Example.framework */,  
138 - C12855D6E1B2B0DA048CAC16 /* Pods_CNLiveAVCamera_Tests.framework */, 126 + 876F38133C52213CA7BB6367 /* Pods_CNLiveAVCamera_Example.framework */,
  127 + E7FA68C9FF1F570173346565 /* Pods_CNLiveAVCamera_Tests.framework */,
139 ); 128 );
140 name = Frameworks; 129 name = Frameworks;
141 sourceTree = "<group>"; 130 sourceTree = "<group>";
@@ -189,13 +178,24 @@ @@ -189,13 +178,24 @@
189 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 178 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
190 isa = PBXGroup; 179 isa = PBXGroup;
191 children = ( 180 children = (
192 - AD6C2CD543580B3E793C7DA5 /* CNLiveAVCamera.podspec */,  
193 - FA45440BB6994ACA16F686E1 /* README.md */,  
194 - 9EC6432D35122051E3EAA096 /* LICENSE */, 181 + 91D86358FC3A20D099BF20BF /* CNLiveAVCamera.podspec */,
  182 + 2242358099573105074E8A8D /* README.md */,
  183 + A08A1D9662A4589773CD2F34 /* LICENSE */,
195 ); 184 );
196 name = "Podspec Metadata"; 185 name = "Podspec Metadata";
197 sourceTree = "<group>"; 186 sourceTree = "<group>";
198 }; 187 };
  188 + 6981E16BA651A5C0254CA344 /* Pods */ = {
  189 + isa = PBXGroup;
  190 + children = (
  191 + 03D1C9ED998415725CAE8BF3 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */,
  192 + F64038E6BB292F8CD89CA832 /* Pods-CNLiveAVCamera_Example.release.xcconfig */,
  193 + B83BAF65F6BCA4FD64ADC040 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */,
  194 + 263AFF8B2121BC39145CA5EE /* Pods-CNLiveAVCamera_Tests.release.xcconfig */,
  195 + );
  196 + name = Pods;
  197 + sourceTree = "<group>";
  198 + };
199 /* End PBXGroup section */ 199 /* End PBXGroup section */
200 200
201 /* Begin PBXNativeTarget section */ 201 /* Begin PBXNativeTarget section */
@@ -203,11 +203,11 @@ @@ -203,11 +203,11 @@
203 isa = PBXNativeTarget; 203 isa = PBXNativeTarget;
204 buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveAVCamera_Example" */; 204 buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveAVCamera_Example" */;
205 buildPhases = ( 205 buildPhases = (
206 - 3BF042746DF1F81EEFFDA492 /* [CP] Check Pods Manifest.lock */, 206 + 17EA93F5C0E0544AEBD5F882 /* [CP] Check Pods Manifest.lock */,
207 6003F586195388D20070C39A /* Sources */, 207 6003F586195388D20070C39A /* Sources */,
208 6003F587195388D20070C39A /* Frameworks */, 208 6003F587195388D20070C39A /* Frameworks */,
209 6003F588195388D20070C39A /* Resources */, 209 6003F588195388D20070C39A /* Resources */,
210 - 086F8B4A7B6AA64B1992EDCC /* [CP] Embed Pods Frameworks */, 210 + 5DB2F813A813F713BD4BA61D /* [CP] Embed Pods Frameworks */,
211 ); 211 );
212 buildRules = ( 212 buildRules = (
213 ); 213 );
@@ -222,11 +222,10 @@ @@ -222,11 +222,10 @@
222 isa = PBXNativeTarget; 222 isa = PBXNativeTarget;
223 buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveAVCamera_Tests" */; 223 buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveAVCamera_Tests" */;
224 buildPhases = ( 224 buildPhases = (
225 - DDD8D3907CD139B1CDEF6F68 /* [CP] Check Pods Manifest.lock */, 225 + CFC16709BBBEA2470565BEAB /* [CP] Check Pods Manifest.lock */,
226 6003F5AA195388D20070C39A /* Sources */, 226 6003F5AA195388D20070C39A /* Sources */,
227 6003F5AB195388D20070C39A /* Frameworks */, 227 6003F5AB195388D20070C39A /* Frameworks */,
228 6003F5AC195388D20070C39A /* Resources */, 228 6003F5AC195388D20070C39A /* Resources */,
229 - E5FB82D83C5E4059CE0F5A8A /* [CP] Embed Pods Frameworks */,  
230 ); 229 );
231 buildRules = ( 230 buildRules = (
232 ); 231 );
@@ -252,7 +251,6 @@ @@ -252,7 +251,6 @@
252 DevelopmentTeam = 94X49GG3ZW; 251 DevelopmentTeam = 94X49GG3ZW;
253 }; 252 };
254 6003F5AD195388D20070C39A = { 253 6003F5AD195388D20070C39A = {
255 - DevelopmentTeam = 94X49GG3ZW;  
256 TestTargetID = 6003F589195388D20070C39A; 254 TestTargetID = 6003F589195388D20070C39A;
257 }; 255 };
258 }; 256 };
@@ -299,29 +297,7 @@ @@ -299,29 +297,7 @@
299 /* End PBXResourcesBuildPhase section */ 297 /* End PBXResourcesBuildPhase section */
300 298
301 /* Begin PBXShellScriptBuildPhase section */ 299 /* Begin PBXShellScriptBuildPhase section */
302 - 086F8B4A7B6AA64B1992EDCC /* [CP] Embed Pods Frameworks */ = {  
303 - isa = PBXShellScriptBuildPhase;  
304 - buildActionMask = 2147483647;  
305 - files = (  
306 - );  
307 - inputFileListPaths = (  
308 - );  
309 - inputPaths = (  
310 - "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example-frameworks.sh",  
311 - "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework",  
312 - );  
313 - name = "[CP] Embed Pods Frameworks";  
314 - outputFileListPaths = (  
315 - );  
316 - outputPaths = (  
317 - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework",  
318 - );  
319 - runOnlyForDeploymentPostprocessing = 0;  
320 - shellPath = /bin/sh;  
321 - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example-frameworks.sh\"\n";  
322 - showEnvVarsInLog = 0;  
323 - };  
324 - 3BF042746DF1F81EEFFDA492 /* [CP] Check Pods Manifest.lock */ = { 300 + 17EA93F5C0E0544AEBD5F882 /* [CP] Check Pods Manifest.lock */ = {
325 isa = PBXShellScriptBuildPhase; 301 isa = PBXShellScriptBuildPhase;
326 buildActionMask = 2147483647; 302 buildActionMask = 2147483647;
327 files = ( 303 files = (
@@ -343,7 +319,7 @@ @@ -343,7 +319,7 @@
343 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 319 shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
344 showEnvVarsInLog = 0; 320 showEnvVarsInLog = 0;
345 }; 321 };
346 - DDD8D3907CD139B1CDEF6F68 /* [CP] Check Pods Manifest.lock */ = { 322 + 5DB2F813A813F713BD4BA61D /* [CP] Embed Pods Frameworks */ = {
347 isa = PBXShellScriptBuildPhase; 323 isa = PBXShellScriptBuildPhase;
348 buildActionMask = 2147483647; 324 buildActionMask = 2147483647;
349 files = ( 325 files = (
@@ -351,21 +327,21 @@ @@ -351,21 +327,21 @@
351 inputFileListPaths = ( 327 inputFileListPaths = (
352 ); 328 );
353 inputPaths = ( 329 inputPaths = (
354 - "${PODS_PODFILE_DIR_PATH}/Podfile.lock",  
355 - "${PODS_ROOT}/Manifest.lock", 330 + "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example-frameworks.sh",
  331 + "${BUILT_PRODUCTS_DIR}/CNLiveAVCamera/CNLiveAVCamera.framework",
356 ); 332 );
357 - name = "[CP] Check Pods Manifest.lock"; 333 + name = "[CP] Embed Pods Frameworks";
358 outputFileListPaths = ( 334 outputFileListPaths = (
359 ); 335 );
360 outputPaths = ( 336 outputPaths = (
361 - "$(DERIVED_FILE_DIR)/Pods-CNLiveAVCamera_Tests-checkManifestLockResult.txt", 337 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveAVCamera.framework",
362 ); 338 );
363 runOnlyForDeploymentPostprocessing = 0; 339 runOnlyForDeploymentPostprocessing = 0;
364 shellPath = /bin/sh; 340 shellPath = /bin/sh;
365 - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 341 + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Example/Pods-CNLiveAVCamera_Example-frameworks.sh\"\n";
366 showEnvVarsInLog = 0; 342 showEnvVarsInLog = 0;
367 }; 343 };
368 - E5FB82D83C5E4059CE0F5A8A /* [CP] Embed Pods Frameworks */ = { 344 + CFC16709BBBEA2470565BEAB /* [CP] Check Pods Manifest.lock */ = {
369 isa = PBXShellScriptBuildPhase; 345 isa = PBXShellScriptBuildPhase;
370 buildActionMask = 2147483647; 346 buildActionMask = 2147483647;
371 files = ( 347 files = (
@@ -373,18 +349,18 @@ @@ -373,18 +349,18 @@
373 inputFileListPaths = ( 349 inputFileListPaths = (
374 ); 350 );
375 inputPaths = ( 351 inputPaths = (
376 - "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests-frameworks.sh",  
377 - "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework", 352 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  353 + "${PODS_ROOT}/Manifest.lock",
378 ); 354 );
379 - name = "[CP] Embed Pods Frameworks"; 355 + name = "[CP] Check Pods Manifest.lock";
380 outputFileListPaths = ( 356 outputFileListPaths = (
381 ); 357 );
382 outputPaths = ( 358 outputPaths = (
383 - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework", 359 + "$(DERIVED_FILE_DIR)/Pods-CNLiveAVCamera_Tests-checkManifestLockResult.txt",
384 ); 360 );
385 runOnlyForDeploymentPostprocessing = 0; 361 runOnlyForDeploymentPostprocessing = 0;
386 shellPath = /bin/sh; 362 shellPath = /bin/sh;
387 - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveAVCamera_Tests/Pods-CNLiveAVCamera_Tests-frameworks.sh\"\n"; 363 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
388 showEnvVarsInLog = 0; 364 showEnvVarsInLog = 0;
389 }; 365 };
390 /* End PBXShellScriptBuildPhase section */ 366 /* End PBXShellScriptBuildPhase section */
@@ -521,7 +497,7 @@ @@ -521,7 +497,7 @@
521 }; 497 };
522 6003F5C0195388D20070C39A /* Debug */ = { 498 6003F5C0195388D20070C39A /* Debug */ = {
523 isa = XCBuildConfiguration; 499 isa = XCBuildConfiguration;
524 - baseConfigurationReference = 0DEF7D98D19D939CF6521425 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */; 500 + baseConfigurationReference = 03D1C9ED998415725CAE8BF3 /* Pods-CNLiveAVCamera_Example.debug.xcconfig */;
525 buildSettings = { 501 buildSettings = {
526 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 502 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
527 DEVELOPMENT_TEAM = 94X49GG3ZW; 503 DEVELOPMENT_TEAM = 94X49GG3ZW;
@@ -537,7 +513,7 @@ @@ -537,7 +513,7 @@
537 }; 513 };
538 6003F5C1195388D20070C39A /* Release */ = { 514 6003F5C1195388D20070C39A /* Release */ = {
539 isa = XCBuildConfiguration; 515 isa = XCBuildConfiguration;
540 - baseConfigurationReference = 93BF696255FE00CF6E596D8F /* Pods-CNLiveAVCamera_Example.release.xcconfig */; 516 + baseConfigurationReference = F64038E6BB292F8CD89CA832 /* Pods-CNLiveAVCamera_Example.release.xcconfig */;
541 buildSettings = { 517 buildSettings = {
542 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 518 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
543 DEVELOPMENT_TEAM = 94X49GG3ZW; 519 DEVELOPMENT_TEAM = 94X49GG3ZW;
@@ -553,10 +529,9 @@ @@ -553,10 +529,9 @@
553 }; 529 };
554 6003F5C3195388D20070C39A /* Debug */ = { 530 6003F5C3195388D20070C39A /* Debug */ = {
555 isa = XCBuildConfiguration; 531 isa = XCBuildConfiguration;
556 - baseConfigurationReference = 084A487B8D91F2EC25B5CF39 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */; 532 + baseConfigurationReference = B83BAF65F6BCA4FD64ADC040 /* Pods-CNLiveAVCamera_Tests.debug.xcconfig */;
557 buildSettings = { 533 buildSettings = {
558 BUNDLE_LOADER = "$(TEST_HOST)"; 534 BUNDLE_LOADER = "$(TEST_HOST)";
559 - DEVELOPMENT_TEAM = 94X49GG3ZW;  
560 FRAMEWORK_SEARCH_PATHS = ( 535 FRAMEWORK_SEARCH_PATHS = (
561 "$(SDKROOT)/Developer/Library/Frameworks", 536 "$(SDKROOT)/Developer/Library/Frameworks",
562 "$(inherited)", 537 "$(inherited)",
@@ -578,10 +553,9 @@ @@ -578,10 +553,9 @@
578 }; 553 };
579 6003F5C4195388D20070C39A /* Release */ = { 554 6003F5C4195388D20070C39A /* Release */ = {
580 isa = XCBuildConfiguration; 555 isa = XCBuildConfiguration;
581 - baseConfigurationReference = 35820DA1F6C64F6B7D896139 /* Pods-CNLiveAVCamera_Tests.release.xcconfig */; 556 + baseConfigurationReference = 263AFF8B2121BC39145CA5EE /* Pods-CNLiveAVCamera_Tests.release.xcconfig */;
582 buildSettings = { 557 buildSettings = {
583 BUNDLE_LOADER = "$(TEST_HOST)"; 558 BUNDLE_LOADER = "$(TEST_HOST)";
584 - DEVELOPMENT_TEAM = 94X49GG3ZW;  
585 FRAMEWORK_SEARCH_PATHS = ( 559 FRAMEWORK_SEARCH_PATHS = (
586 "$(SDKROOT)/Developer/Library/Frameworks", 560 "$(SDKROOT)/Developer/Library/Frameworks",
587 "$(inherited)", 561 "$(inherited)",
Example/CNLiveAVCamera/CNLiveAppDelegate.h
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // CNLiveAppDelegate.h 2 // CNLiveAppDelegate.h
3 // CNLiveAVCamera 3 // CNLiveAVCamera
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 @import UIKit; 9 @import UIKit;
Example/CNLiveAVCamera/CNLiveAppDelegate.m
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // CNLiveAppDelegate.m 2 // CNLiveAppDelegate.m
3 // CNLiveAVCamera 3 // CNLiveAVCamera
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 #import "CNLiveAppDelegate.h" 9 #import "CNLiveAppDelegate.h"
Example/CNLiveAVCamera/CNLiveViewController.h
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // CNLiveViewController.h 2 // CNLiveViewController.h
3 // CNLiveAVCamera 3 // CNLiveAVCamera
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 @import UIKit; 9 @import UIKit;
Example/CNLiveAVCamera/CNLiveViewController.m
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // CNLiveViewController.m 2 // CNLiveViewController.m
3 // CNLiveAVCamera 3 // CNLiveAVCamera
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 #import "CNLiveViewController.h" 9 #import "CNLiveViewController.h"
Example/CNLiveAVCamera/main.m
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // main.m 2 // main.m
3 // CNLiveAVCamera 3 // CNLiveAVCamera
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 @import UIKit; 9 @import UIKit;
Example/Podfile
@@ -4,11 +4,9 @@ platform :ios, &#39;8.0&#39; @@ -4,11 +4,9 @@ platform :ios, &#39;8.0&#39;
4 4
5 target 'CNLiveAVCamera_Example' do 5 target 'CNLiveAVCamera_Example' do
6 pod 'CNLiveAVCamera', :path => '../' 6 pod 'CNLiveAVCamera', :path => '../'
7 - pod 'Masonry', '~> 1.0.2'  
8 7
9 target 'CNLiveAVCamera_Tests' do 8 target 'CNLiveAVCamera_Tests' do
10 inherit! :search_paths 9 inherit! :search_paths
11 - pod 'Masonry', '~> 1.0.2'  
12 10
13 11
14 end 12 end
Example/Tests/Tests.m
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 // CNLiveAVCameraTests.m 2 // CNLiveAVCameraTests.m
3 // CNLiveAVCameraTests 3 // CNLiveAVCameraTests
4 // 4 //
5 -// Created by jyyjkt on 12/10/2018.  
6 -// Copyright (c) 2018 jyyjkt. All rights reserved. 5 +// Created by jyyjkt on 05/05/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
7 // 7 //
8 8
9 @import XCTest; 9 @import XCTest;
1 -Copyright (c) 2018 jyyjkt <jyyjkt@qq.com> 1 +Copyright (c) 2019 jyyjkt <jyyjkt@qq.com>
2 2
3 Permission is hereby granted, free of charge, to any person obtaining a copy 3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal 4 of this software and associated documentation files (the "Software"), to deal