//
//  NvVKeyerViewController.m
//  SDKDemo
//
//  Created by ms20180425 on 2018/10/11.
 //
//

#import "NvVKeyerViewController.h"
#import "NvTipsView.h"
#import <AVFoundation/AVFoundation.h>
#import "NvFilterItem.h"
#import "NvAssetManager.h"
#import "NvsAssetPackageManager.h"
#import "NvsCaptureVideoFx.h"
#import "stMobileDetected.h"
#import "NvFilterCell.h"
#import "NvSDKUtils.h"
#import <Photos/Photos.h>
#import "NvCompileViewController.h"
#import "NvsTimeline.h"
#import "NvsVideoTrack.h"
#import "NvPreViewLiveWindow.h"
#import "NvGraphicBtn.h"
#import "NvsTimelineAnimatedSticker.h"

@interface NvVKeyerViewController ()<NvsStreamingContextDelegate, UICollectionViewDelegate, UICollectionViewDataSource, NvCompileViewControllerDelegate>
//界面按钮
@property (nonatomic, strong) UIButton *backBtn;         //关闭
@property (nonatomic, strong) NvGraphicBtn *deviceBtn;       //切换摄像头
@property (nonatomic, strong) NvGraphicBtn *flashBtn;        //闪光灯
@property (nonatomic, strong) NvGraphicBtn *virtualBgBtn;    //虚拟背景
@property (nonatomic, strong) UIButton *shootingBtn;     //拍摄
@property (nonatomic, strong) UIButton *shootingBtn_1;   //自己特有的拍摄按钮
@property (nonatomic, strong) UIButton *finishBtn;       //完成
@property (nonatomic, strong) UILabel  *timeLabel;       //录制时长
@property (nonatomic, strong) UIButton *deleteBtn;       //删除视频
@property (nonatomic, strong) UILabel  *videoCount;      //视频个数

//权限视图
@property (nonatomic, strong) NvTipsView *permissions;
//提示
@property (nonatomic, strong) NvTipsView *tipView;
//相册权限视图
@property (nonatomic, strong) NvTipsView *photoView;

//抠像视图
@property (nonatomic, strong) UIView *virtualBgView;                     //最外层
@property (nonatomic, strong) UIView *virtualBgHeaderView;               //虚拟背景抠像提示视图
@property (nonatomic, strong) UICollectionView *virtualBgCollectionView; //背景特效滑动视图
@property (nonatomic, strong) NSMutableArray *virtualBgDataSource;       //背景特效数组

//预览视图
@property (nonatomic, strong) NvPreViewLiveWindow *preView;

//-----------------逻辑相关----------------//
@property (nonatomic, assign) int currentDeviceIndex;          //当前设备摄像头索引
@property (nonatomic, assign) int currentFxIndex;              //当前特效对象索引
@property (nonatomic, assign) BOOL clickState;                 //底部弹窗视图出现和消失
@property (nonatomic, strong) NvFilterItem *currentItem;       //当前操作的特效对象
@property (nonatomic, strong) NSMutableArray *videoPathArray;  //视频路径数组
@property (nonatomic, strong) NSMutableArray *durationArray;   //断点拍摄每段视频的时长数组
@property (nonatomic, assign) int64_t duration;                //总拍摄时长
@property (nonatomic, assign) int64_t lastDuration;            //断点拍摄每次停止录制的时长，duration和durationArray需要用到
@property (nonatomic, strong) NSString *compileFilePath;//生成路径


//-----------------sdk相关----------------//
@property (nonatomic, strong) NvsStreamingContext *streamingContext;
@property (nonatomic, strong) NvsLiveWindow *liveWindow;
@property (nonatomic, strong) NvsLiveWindow *liveWindowBack;
@property (nonatomic, strong) NvsLiveWindow *curLiveWindow;//当前窗口
@property (nonatomic, strong) NvAssetManager *assetManager;//素材管理
@property (nonatomic, strong) NvsCaptureVideoFx *keyerFx;  //背景抠像特效

@end

@implementation NvVKeyerViewController

- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    NSLog(@"%s",__func__);
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if (self.streamingContext.getStreamingEngineState != NvsStreamingEngineState_CapturePreview) {
        [self startCapturePreview];
        self.streamingContext.delegate = self;
    }
    self.navigationController.navigationBar.hidden = YES;
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    self.navigationController.navigationBar.hidden = NO;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.virtualBgDataSource = [NSMutableArray array];
    self.videoPathArray = [NSMutableArray array];
    self.durationArray = [NSMutableArray array];
    
    [self addObservers];
    // 检查摄像头权限
    __weak typeof(self)weakSelf = self;
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                AVAuthorizationStatus audioAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
                if (audioAuthStatus == AVAuthorizationStatusNotDetermined) {
                    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
                        if (granted) {
                            dispatch_async(dispatch_get_main_queue(), ^{
                                [weakSelf startupCapture];
                            });
                        } else {
                            // 提示麦克风权限未获得
                            dispatch_async(dispatch_get_main_queue(), ^{
                                [weakSelf startupCapture];
                                [weakSelf.view addSubview:weakSelf.permissions];
                            });
                        }
                    }];
                }
            } else {
                // 提示摄像头权限未获得
                dispatch_async(dispatch_get_main_queue(), ^{
                    [weakSelf.view addSubview:weakSelf.permissions];
                });
            }
        }];
    } else if (authStatus == AVAuthorizationStatusDenied) {
        // 提示摄像头权限未获得
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf.view addSubview:weakSelf.permissions];
        });
    } else {
        // 检查麦克风权限
        authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
        if (authStatus == AVAuthorizationStatusDenied) {
            // 提示麦克风权限未获得
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf.view addSubview:weakSelf.permissions];
            });
        }
        [weakSelf startupCapture];
    }
}

#pragma mark 初始化sdk
- (void)startupCapture{
    // 初始化SDK
    self.streamingContext = [NvSDKUtils getSDKContext];
    if (!_streamingContext) {
        NSLog(@"初始化失败！");
        return;
    }
    
    // 设置回调接口
    _streamingContext.delegate = self;
    
    // 由于本示例程序需要演示虚拟场景，所以需要给拍摄添加一个抠像特技
    self.keyerFx = [_streamingContext appendBuiltinCaptureVideoFx:@"Master Keyer"];
    if (_keyerFx) {
        // 开启溢色去除
        [_keyerFx setBooleanVal:@"Spill Removal" val:YES];
        // 将溢色去除强度设置为最低
        [_keyerFx setFloatVal:@"Spill Removal Intensity" val:0];
        // 设置收缩边界强度
        [_keyerFx setFloatVal:@"Shrink Intensity" val:0.4];
    }
    
    // 检查可用采集设备的数量
    if ([_streamingContext captureDeviceCount] == 0) {
        NSLog(@"没有可用于采集的设备！");
    }
    
    // 创建采集预览窗口并连接到摄像头采集次输出
    _liveWindowBack = [[NvsLiveWindow alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
    [self.view addSubview:_liveWindowBack];
    _liveWindow = [[NvsLiveWindow alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
    [self.view addSubview:_liveWindow];
    _curLiveWindow = _liveWindowBack;
    if (![_streamingContext connectCapturePreviewWithLiveWindow:_curLiveWindow]) {
        NSLog(@"连接预览窗口失败！");
    }
    _curLiveWindow = _liveWindow;
    if (![_streamingContext connectCapturePreviewWithLiveWindow:_curLiveWindow]) {
        NSLog(@"连接预览窗口失败！");
    }
    
    self.currentDeviceIndex = [self frontCameraDeviceIndex];
    if (![self startCapturePreview]) {
        NSLog(@"启动摄像头采集预览失败！");
    }
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
    tap.numberOfTapsRequired = 1;
    [_liveWindow addGestureRecognizer:tap];
    
    UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
    tap.numberOfTapsRequired = 1;
    [_liveWindowBack addGestureRecognizer:tap1];
    
    [self addSubViews];
    [self addVirtualBgView];
    [self addVirtualBgDataSource];
    if (![[[NSUserDefaults standardUserDefaults] valueForKey:@"NvVKeyerViewController"] boolValue]) {
        [self addTipUserOperation];
    }
    if (_currentDeviceIndex == [self frontCameraDeviceIndex]) {
        self.flashBtn.userInteractionEnabled = NO;
        self.flashBtn.alpha = 0.7;
    } else {
        self.flashBtn.userInteractionEnabled = YES;
        self.flashBtn.alpha = 1;
    }
}

#pragma mark 添加子视图
- (void)addSubViews{
    // 初始化UI
    self.backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.backBtn setImage:[NvUtils imageWithName:@"Nvback"] forState:UIControlStateNormal];
    [self.backBtn addTarget:self action:@selector(backBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.deviceBtn = [NvGraphicBtn buttonWithType:UIButtonTypeCustom withTitle:@"切换" withImageNormal:@"Nvdevice" withImageSelected:nil];
    [self.deviceBtn addTarget:self action:@selector(deviceBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.flashBtn = [NvGraphicBtn buttonWithType:UIButtonTypeCustom withTitle:@"补光" withImageNormal:@"Nvflash_off" withImageSelected:@"Nvflash_on"];
    [self.flashBtn addTarget:self action:@selector(flashBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.virtualBgBtn = [NvGraphicBtn buttonWithType:UIButtonTypeCustom withTitle:@"背景" withImageNormal:@"NvVirtualKeyerBg" withImageSelected:nil];
    [self.virtualBgBtn addTarget:self action:@selector(virtualBgBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.shootingBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.shootingBtn setImage:[NvUtils imageWithName:@"Nvshooting"] forState:UIControlStateNormal];
    [self.shootingBtn setImage:[NvUtils imageWithName:@"Nvsuspended"] forState:UIControlStateSelected];
    [self.shootingBtn addTarget:self action:@selector(shootingBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.shootingBtn_1 = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.shootingBtn_1 setImage:[NvUtils imageWithName:@"NvVirtualShooting"] forState:UIControlStateNormal];
    [self.shootingBtn_1 addTarget:self action:@selector(shootingBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.deleteBtn setImage:[NvUtils imageWithName:@"Nvdelete"] forState:UIControlStateNormal];
    [self.deleteBtn addTarget:self action:@selector(deleteBtnBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    self.finishBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.finishBtn setImage:[NvUtils imageWithName:@"Nvfinish"] forState:UIControlStateNormal];
    [self.finishBtn addTarget:self action:@selector(finishBtnBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    self.timeLabel = [UILabel new];
    self.timeLabel.text = @"00:00";
    self.timeLabel.textColor = [UIColor nv_colorWithHexRGB:@"#D0021B"];
    self.timeLabel.font = [NvUtils fontWithSize:12 * SCREANSCALE];
    
    self.videoCount = [UILabel new];
    self.videoCount.userInteractionEnabled = NO;
    self.videoCount.font = [NvUtils fontWithSize:12 * SCREANSCALE];
    self.videoCount.textColor = UIColor.whiteColor;
    
    [self.view addSubview:self.backBtn];
    [self.view addSubview:self.deviceBtn];
    [self.view addSubview:self.flashBtn];
    [self.view addSubview:self.virtualBgBtn];
    [self.view addSubview:self.shootingBtn];
    [self.view addSubview:self.deleteBtn];
    [self.view addSubview:self.finishBtn];
    [self.view addSubview:self.timeLabel];
    [self.shootingBtn addSubview:self.shootingBtn_1];
    [self.shootingBtn addSubview:self.videoCount];
    
    [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(NV_STATUSBARHEIGHT);
        make.left.equalTo(self.view).offset(13 * SCREANSCALE);
        make.width.offset(33 * SCREANSCALE);
        make.height.offset(33 * SCREANSCALE);
    }];
    
    [self.deviceBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(NV_STATUSBARHEIGHT);
        make.right.equalTo(self.view).offset(- 13 * SCREANSCALE);
        make.width.offset(33 * SCREANSCALE);
    }];
    
    [self.flashBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.deviceBtn.mas_bottom).offset(10 * SCREANSCALE);
        make.centerX.equalTo(self.deviceBtn.mas_centerX);
        make.width.equalTo(self.deviceBtn.mas_width);
    }];
    
    [self.virtualBgBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.flashBtn.mas_bottom).offset(10 * SCREANSCALE);
        make.centerX.equalTo(self.deviceBtn.mas_centerX);
        make.width.equalTo(self.deviceBtn.mas_width);
    }];
    
    [self.shootingBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view.mas_bottom).offset(- 20 * SCREANSCALE);
        make.centerX.equalTo(self.view.mas_centerX);
        make.width.offset(64 * SCREANSCALE);
        make.height.offset(64 * SCREANSCALE);
    }];
    
    [self.shootingBtn_1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.shootingBtn);
        make.bottom.equalTo(self.shootingBtn);
        make.left.equalTo(self.shootingBtn);
        make.right.equalTo(self.shootingBtn);
    }];
    
    [self.deleteBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.shootingBtn.mas_left).offset(- 56 * SCREANSCALE);
        make.centerY.equalTo(self.shootingBtn.mas_centerY);
        make.width.offset(48 * SCREANSCALE);
        make.height.offset(33 * SCREANSCALE);
    }];
    
    [self.finishBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.shootingBtn.mas_right).offset(56 * SCREANSCALE);
        make.centerY.equalTo(self.shootingBtn.mas_centerY);
        make.width.offset(40 * SCREANSCALE);
        make.height.offset(40 * SCREANSCALE);
    }];
    
    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view.mas_centerX);
        make.centerY.equalTo(self.backBtn.mas_centerY);
    }];
    
    [self.videoCount mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.shootingBtn.mas_centerX);
        make.centerY.equalTo(self.shootingBtn.mas_centerY);
    }];
    
    self.timeLabel.hidden = YES;
    self.deleteBtn.hidden = YES;
    self.finishBtn.hidden = YES;
}

#pragma mark 添加虚拟背景抠像视图
- (void)addVirtualBgView{
    self.virtualBgView = [[UIView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGTH, SCREEN_WDITH, 140*SCREANSCALE + INDICATOR)];
    _virtualBgView.backgroundColor = [UIColor nv_colorWithHexARGB:@"#99000000"];
    [self.view addSubview:_virtualBgView];
    
    self.virtualBgHeaderView = [[UIView alloc] init];
    _virtualBgHeaderView.backgroundColor = [UIColor clearColor];
    [_virtualBgView addSubview:_virtualBgHeaderView];
    [_virtualBgHeaderView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.virtualBgView);
        make.width.offset(SCREANWIDTH);
        make.height.offset(40 * SCREANSCALE);
    }];
    
    UILabel *tipLabel = [[UILabel alloc]init];
    tipLabel.text = @"点选要去除的画面颜色，再选择一个场景进行录制";
    tipLabel.font = [UIFont systemFontOfSize:12];
    tipLabel.textColor = UIColor.whiteColor;
    [_virtualBgHeaderView addSubview:tipLabel];
    [tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.virtualBgHeaderView.mas_centerX).offset(15 * SCREANSCALE);
        make.centerY.equalTo(self.virtualBgHeaderView.mas_centerY);
    }];
    
    UIImageView *tipImageView = [[UIImageView alloc]init];
    tipImageView.contentMode = UIViewContentModeScaleAspectFit;
    tipImageView.image = [NvUtils imageWithName:@"NvVirtualKeyerTip"];
    [_virtualBgHeaderView addSubview:tipImageView];
    [tipImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(tipLabel.mas_left).offset(-15 * SCREANSCALE);
        make.centerY.equalTo(self.virtualBgHeaderView.mas_centerY);
        make.width.offset(20 * SCREANSCALE);
        make.width.offset(20 * SCREANSCALE);
    }];
    
    UIView *lineView = [[UIView alloc]init];
    lineView.backgroundColor = [UIColor nv_colorWithHexRGB:@"#979797"];
    [_virtualBgHeaderView addSubview:lineView];
    [lineView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.virtualBgHeaderView.mas_bottom);
        make.width.equalTo(self.virtualBgHeaderView.mas_width);
        make.height.offset(1);
    }];
    
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    layout.itemSize = CGSizeMake(70 * SCREANSCALE, 70*SCREANSCALE);
    layout.minimumLineSpacing = 0;
    layout.minimumInteritemSpacing = 0;
    layout.sectionInset = UIEdgeInsetsMake(20 * SCREANSCALE, 0, 0, 0);
    self.virtualBgCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
    _virtualBgCollectionView.backgroundColor = UIColor.clearColor;
    _virtualBgCollectionView.delegate = self;
    _virtualBgCollectionView.dataSource = self;
    _virtualBgCollectionView.showsHorizontalScrollIndicator = NO;
    [_virtualBgView addSubview:_virtualBgCollectionView];
    [_virtualBgCollectionView registerClass:[NvFilterCell class] forCellWithReuseIdentifier:@"NvFilterCell"];
    [_virtualBgCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.virtualBgView).offset(-INDICATOR);
        make.left.equalTo(self.virtualBgView);
        make.right.equalTo(self.virtualBgView);
        make.height.offset(100 * SCREANSCALE);
    }];
}

#pragma mark 给virtualBgDataSource添加数据
- (void)addVirtualBgDataSource{
    self.assetManager = [NvAssetManager sharedInstance];
    NSString *VirtualBgPath = [[[NSBundle bundleForClass:[self class]] bundlePath] stringByAppendingPathComponent:@"VirtualBgPackage"];
    [self.assetManager searchReservedAssets:ASSET_CAPTURE_SCENE bundlePath:VirtualBgPath];
    
    NSArray *temporaryArray = [self.assetManager getUsableAssets:ASSET_CAPTURE_SCENE aspectRatio:AspectRatio_All categoryId:0];
    for (NvAsset *asset in temporaryArray) {
        if (asset.downloadStatus == DownloadStatusDecompressingFailed) {
            continue;
        }
        NvFilterItem *item = [NvFilterItem new];
        item.packID = asset.uuid;
        item.displayName = asset.name;
        item.cover = [asset.coverUrl absoluteString];
        item.categoryId = asset.categoryId;
        
        [self.virtualBgDataSource addObject:item];
    }
    
    [self.virtualBgCollectionView reloadData];
}

#pragma mark 提示——用户虚拟背景抠像的引导视图
- (void)addTipUserOperation{
    self.tipView = [[NvTipsView alloc]initWithFrameVirtual:self.view.frame withPrompt:@"提示" describeTitle:@"建议拍摄背景为单一颜色" describeContent:nil buttonText:@"知道了" withCenter:YES];
    [_tipView.clickBtn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
    [_tipView.clickBtn1 addTarget:self action:@selector(clickBtn1:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_tipView];
}

#pragma mark tipView按钮点击事件
- (void)clickBtn:(UIButton *)sender{
    [self.tipView removeFromSuperview];
    self.tipView = nil;
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NvVKeyerViewController"];
}

- (void)clickBtn1:(UIButton *)sender{
    [self.tipView removeFromSuperview];
    self.tipView = nil;
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NvVKeyerViewController"];
}

#pragma mark 相册权限提示
- (void)popUpTip{
    self.photoView = [[NvTipsView alloc]initWithFrame:self.view.frame withPrompt:@"保存失败" describeTitle:@"您还没有允许相册访问权限" describeContent:nil buttonText:@"知道了" withCenter:YES];
    [_photoView.clickBtn addTarget:self action:@selector(popUpTipKnowClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_photoView];
}

#pragma mark tipView按钮点击事件
- (void)popUpTipKnowClick:(UIButton *)sender{
    _photoView.hidden = YES;
}

#pragma mark 切换摄像头
- (void)deviceBtnClick:(UIButton *)sender{
    UIView *fromView;
    UIView *toView;
    if ([_curLiveWindow isEqual:_liveWindow]) {
        fromView = _liveWindow;
        toView = _liveWindowBack;
    } else {
        fromView = _liveWindowBack;
        toView = _liveWindow;
    }
    _curLiveWindow = (NvsLiveWindow *)toView;
    
    if (![_streamingContext connectCapturePreviewWithLiveWindow:_curLiveWindow]) {
        NSLog(@"连接预览窗口失败！");
    }
    
    if (_currentDeviceIndex == 0) {
        _currentDeviceIndex = 1;
    } else {
        _currentDeviceIndex = 0;
    }
    
    if (_currentDeviceIndex == [self frontCameraDeviceIndex]) {
        _flashBtn.alpha = 0.7;
        _flashBtn.userInteractionEnabled = NO;
        _flashBtn.selected = NO;
    } else {
        _flashBtn.alpha = 1;
        _flashBtn.userInteractionEnabled = YES;
    }
    
    [UIView transitionFromView:fromView toView:toView duration:0.3 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
        [self.view sendSubviewToBack:self.curLiveWindow];
    }];
    [self startCapturePreview];
}

#pragma mark 闪光灯开关
- (void)flashBtnClick:(UIButton *)sender{
    if ([_streamingContext getCaptureDeviceCapability:_currentDeviceIndex].supportFlash) {
        [_streamingContext toggleFlash:![_streamingContext isFlashOn]];
        _flashBtn.selected = sender.selected ? NO : YES;
    }
}

#pragma mark 关闭退出
- (void)backBtnClick:(UIButton *)sender{
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [_streamingContext removeCurrentCaptureScene];
        [_streamingContext removeAllCaptureVideoFx];
        [_streamingContext stop];
        [self.navigationController popViewControllerAnimated:YES];
//    });
}

#pragma mark 背景按钮点击事件
- (void)virtualBgBtnClick:(UIButton *)sender{
    self.clickState = YES;
    [self faceHiddenBtn:YES];
    [UIView animateWithDuration:0.1 animations:^{
         self.virtualBgView.frame = CGRectMake(0, SCREEN_HEIGTH - self.virtualBgView.frame.size.height, SCREEN_WDITH, self.virtualBgView.frame.size.height);
    }];
}

#pragma mark 拍摄按钮点击
- (void)shootingBtnClick:(UIButton *)sender{
    if ([sender isEqual:self.shootingBtn_1]) {
        self.shootingBtn_1.hidden = YES;
        self.shootingBtn.selected = YES;
        self.timeLabel.textColor = UIColor.redColor;
        self.videoCount.hidden = YES;
        [self faceHiddenBtn:YES];
        self.shootingBtn.hidden = NO;
        self.timeLabel.hidden = NO;
        self.shootingBtn.enabled = NO;
        [self startRecording];
    }else{
        if (sender.selected) {
            sender.selected = NO;
            [self faceHiddenBtn:NO];
            [self stopRecording];
            self.videoCount.text = [NSString stringWithFormat:@"%lu",(unsigned long)_videoPathArray.count];
            self.timeLabel.textColor = UIColor.whiteColor;
            self.videoCount.hidden = NO;
            self.duration = self.duration + self.lastDuration;
            [self.durationArray addObject:[NSNumber numberWithLongLong:self.lastDuration]];
        }else{
            self.timeLabel.textColor = UIColor.redColor;
            self.videoCount.hidden = YES;
            sender.selected = YES;
            [self faceHiddenBtn:YES];
            self.shootingBtn.hidden = NO;
            self.timeLabel.hidden = NO;
            self.shootingBtn.enabled = NO;
            [self startRecording];
        }
    }
}

#pragma mark 开始录制
- (void)startRecording{
    NSString *path = [VIDEO_PATH(@"Virtual") stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4", [NvUtils currentDateAndTime]]];
    NSMutableDictionary *config = [[NSMutableDictionary alloc] init];
    [_streamingContext startRecordingWithFx:path withFlags:0 withRecordConfigurations:config];
    [self.videoPathArray addObject:path];
}

#pragma mark 关闭录制
- (void)stopRecording{
    [_streamingContext stopRecording];
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    if (status == PHAuthorizationStatusRestricted || status == PHAuthorizationStatusDenied)
    {
        if (!self.photoView) {
            [self popUpTip];
        }
        return;
    }
    if (self.photoView) {
        [self.photoView removeFromSuperview];
    }
    UISaveVideoAtPathToSavedPhotosAlbum(self.videoPathArray.lastObject, self, nil, nil);
    
    //    UISaveVideoAtPathToSavedPhotosAlbum(
    //                                        self.videoPathArray.lastObject, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
}

#pragma mark 删除按钮点击
- (void)deleteBtnBtnClick:(UIButton *)sender{
    NSString *filePath = (NSString *)[_videoPathArray lastObject];
    [_videoPathArray removeLastObject];
    NSError *error;
    if (![[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]){
        NSLog(@"删除文件失败, 错误: %@", error);
    }
    if (_videoPathArray.count == 0) {
        self.videoCount.text = @"";
        self.timeLabel.text = @"00:00";
        self.timeLabel.hidden = YES;
        self.deleteBtn.hidden = YES;
        self.finishBtn.hidden = YES;
        self.duration = 0;
        self.shootingBtn_1.hidden = NO;
    }else{
        self.videoCount.text = [NSString stringWithFormat:@"%lu",(unsigned long)_videoPathArray.count];
        self.duration = self.duration - [[_durationArray lastObject] longLongValue];
        self.timeLabel.text = [NvUtils convertTimecode:self.duration];
    }
}

#pragma mark 完成按钮点击
- (void)finishBtnBtnClick:(UIButton *)sender{
    //路径数组 self.videoPathArray
    AVURLAsset*audioAsset=[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:self.videoPathArray.firstObject] options:nil];
    AVAssetTrack *track = [[audioAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    CGSize dimensions = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform);
    if (dimensions.width > dimensions.height) {
        // NvEditMode16v9;
        [self addPreviewView:NvEditMode16v9 withPathArray:self.videoPathArray];
    }else{
        // NvEditMode9v16;
        [self addPreviewView:NvEditMode9v16 withPathArray:self.videoPathArray];
    }
}

#pragma mark 将拍摄的视频保存到本地相册
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"打包成功" message:@"已保存至相册" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
}

#pragma mark 预览视图
- (void)addPreviewView:(NvEditMode)editMode withPathArray:(NSMutableArray *)path{
    self.preView = [[NvPreViewLiveWindow alloc]initWithFrame:self.view.frame];
    self.preView.delegate = self;
    self.preView.pathArray = path;
    self.preView.model = editMode;
    [self.view addSubview:self.preView];
}

#pragma mark NvPreViewLiveWindowDelegate
//退出关闭预览视图
- (void)backClick{
    [self.preView removeFromSuperview];
    self.preView = nil;
    [self.streamingContext connectCapturePreviewWithLiveWindow:self.curLiveWindow];
    self.streamingContext.delegate = self;
    [self startCapturePreview];
}

//生成按钮点击事件
- (void)compileClick:(NvsTimeline *)timeline{
    self.compileFilePath = [VIDEO_PATH(@"Virtual") stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4", [NvUtils currentDateAndTime]]];
    NvCompileViewController *compileViewController = [NvCompileViewController new];
    compileViewController.delegate = self;
    compileViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
    [compileViewController compileTimeline:timeline outputPath:self.compileFilePath];
    [self presentViewController:compileViewController animated:NO completion:nil];
}

#pragma mark - NvCompileViewControllerDelegate
- (void)compileFinished:(BOOL)needDelete {
    [self.preView againConnection];
    if (needDelete) {
        [[NSFileManager defaultManager] removeItemAtPath:self.compileFilePath error:nil];
    } else {
        UISaveVideoAtPathToSavedPhotosAlbum(self.compileFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
    }
}
 
#pragma mark 获取前置摄像头设备索引
- (unsigned int)frontCameraDeviceIndex {
    for (unsigned int i = 0; i < _streamingContext.captureDeviceCount; i++) {
        if (![_streamingContext isCaptureDeviceBackFacing:i])
            return i;
    }
    
    return _streamingContext.captureDeviceCount - 1;
}

#pragma mark 启动摄像头采集预览
- (BOOL)startCapturePreview {
    NSNumber *num = NV_UserInfo(@"NvRecordResolution");
    NvsVideoCaptureResolutionGrade captureResGrade = [num intValue] == 1080? NvsVideoCaptureResolutionGradeHigh:NvsVideoCaptureResolutionGradeMedium;
    if ([_streamingContext isCaptureDeviceBackFacing:_currentDeviceIndex]){
        captureResGrade = NvsVideoCaptureResolutionGradeMedium;
    }
    return [_streamingContext startCapturePreview:_currentDeviceIndex videoResGrade:captureResGrade flags: NvsStreamingEngineCaptureFlag_CaptureBuddyHostVideoFrame |NvsStreamingEngineCaptureFlag_GrabCapturedVideoFrame | NvsStreamingEngineCaptureFlag_StrictPreviewVideoSize aspectRatio:nil];
}


#pragma mark NvsStreamingContextDelegate
- (void)didCaptureRecordingDurationUpdated:(int)captureDeviceIndex duration:(int64_t)duration{
    self.lastDuration = duration;
    self.timeLabel.text = [NvUtils convertTimecode:self.duration + duration];
    if (duration >= NV_TIME_BASE) {
        self.shootingBtn.enabled = YES;
    }
}

- (void)didCaptureDeviceCapsReady:(unsigned int)captureDeviceIndex{
    // 获取采集设备的能力描述
    NvsCaptureDeviceCapability *capability = [_streamingContext getCaptureDeviceCapability:captureDeviceIndex];
    if (!capability){
        return;
    }
}

#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.virtualBgDataSource.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    NvFilterCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"NvFilterCell" forIndexPath:indexPath];
    [cell renderCellWithItem:_virtualBgDataSource[indexPath.item]];
    return cell;
   
}

#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    for (NvFilterItem *model in self.virtualBgDataSource) {
        model.selected = NO;
    }
    NvFilterItem *item = self.virtualBgDataSource[indexPath.item];
    item.selected = YES;
    [self.streamingContext applyCaptureScene:item.packID];
    [collectionView reloadData];
}
#pragma mark 点击隐藏界面按钮
- (void)faceHiddenBtn:(BOOL)hidden{
    self.deviceBtn.hidden = hidden;
    self.flashBtn.hidden = hidden;
    self.backBtn.hidden = hidden;
    self.virtualBgBtn.hidden = hidden;
    self.shootingBtn.hidden = hidden;
    self.timeLabel.hidden = hidden;
    self.deleteBtn.hidden = hidden;
    self.finishBtn.hidden = hidden;
}

#pragma mark 点击空白显示界面按钮
- (void)singleTap:(UITapGestureRecognizer *)recognizer {
    if (self.clickState) {
        self.clickState = NO;
        [self faceHiddenBtn:NO];
        [UIView animateWithDuration:0.1 animations:^{
            self.virtualBgView.frame = CGRectMake(0, SCREEN_HEIGTH, SCREEN_WDITH, self.virtualBgView.frame.size.height);
        }];
        if (_videoPathArray.count == 0) {
            self.timeLabel.hidden = YES;
            self.deleteBtn.hidden = YES;
            self.finishBtn.hidden = YES;
        }else{
            self.timeLabel.hidden = NO;
            self.deleteBtn.hidden = NO;
            self.finishBtn.hidden = NO;
        }
    }else{
        if (recognizer.state == UIGestureRecognizerStateEnded) {
            const CGPoint pos = [recognizer locationInView:self.curLiveWindow];
            static const int sampleWidth = 20, sampleHeight = 20;
            CGRect sampleRect;
            
            sampleRect.origin.x = pos.x - sampleWidth / 2;
            if (sampleRect.origin.x < 0)
                sampleRect.origin.x = 0;
            else if (sampleRect.origin.x + sampleWidth > self.curLiveWindow.bounds.size.width)
                sampleRect.origin.x = self.curLiveWindow.bounds.size.width - sampleWidth;
            
            sampleRect.origin.y = pos.y - sampleHeight / 2;
            if (sampleRect.origin.y < 0)
                sampleRect.origin.y = 0;
            else if (sampleRect.origin.y + sampleHeight > self.curLiveWindow.bounds.size.height)
                sampleRect.origin.y = self.curLiveWindow.bounds.size.height - sampleHeight;
            
            sampleRect.size.width = sampleWidth;
            sampleRect.size.height = sampleHeight;
            
            NvsColor sampledColor = [_streamingContext sampleColorFromCapturedVideoFrame:sampleRect];
            
            // 将吸取下来的背景画面颜色值设置给抠像特技
            NvsCaptureVideoFx *keyerFx = [_streamingContext getCaptureVideoFxByIndex:0];
            if (keyerFx){
                [keyerFx setColorVal:@"Key Color" val:&sampledColor];
            }
        }
    }
}

#pragma mark 懒加载权限视图
- (NvTipsView *)permissions{
    if (!_permissions)
    {
        _permissions = [[NvTipsView alloc]initWithFrame:self.view.frame withPrompt:@"提示" describeTitle:@"需要打开摄像头和麦克风权限 请在手机设置中进行允许" describeContent:nil buttonText:@"知道了" withCenter:YES];
        [_permissions.clickBtn addTarget:self action:@selector(knowClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _permissions;
}

#pragma mark 权限按钮点击事件
- (void)knowClick{
    [_permissions removeFromSuperview];
    [self.navigationController popViewControllerAnimated:YES];
}


#pragma mark 注册应用前台后台通知事件
- (void)addObservers {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}

// 应用进入后台，停止采集
- (void)applicationWillResignActive:(NSNotification*)notification {
    if ([_streamingContext getStreamingEngineState] == NvsStreamingEngineState_CaptureRecording) {
        self.shootingBtn.selected = NO;
        [self faceHiddenBtn:NO];
        [self stopRecording];
        self.videoCount.text = [NSString stringWithFormat:@"%lu",(unsigned long)_videoPathArray.count];
        self.timeLabel.textColor = UIColor.whiteColor;
        self.videoCount.hidden = NO;
        self.duration = self.duration + self.lastDuration;
        [self.durationArray addObject:[NSNumber numberWithLongLong:self.lastDuration]];
    }
    
    if ([_streamingContext getStreamingEngineState] == NvsStreamingEngineState_CapturePreview ||[_streamingContext getStreamingEngineState] == NvsStreamingEngineState_Playback) {
        [_streamingContext stop];
    }
    if ([_streamingContext getStreamingEngineState] == NvsStreamingEngineState_CapturePreview) {
        [_streamingContext stop];
    }
}

// 应用进入前台，开始采集
- (void)applicationDidBecomeActive:(NSNotification*)notification {
    
    if ([_streamingContext getStreamingEngineState] == NvsStreamingEngineState_Stopped) {
        [self startCapturePreview];
    }
}

#pragma mark 防止锁屏
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
