//
//  NvRecordViewController.m
//  SDKDemo
//
//  Created by 刘东旭 on 2018/8/6.
 //
//

#import "NvRecordViewController.h"
#import "NvTimelineUtils.h"
#import "NvTimelineCaptionUtils.h"
#import "NvTimelineData.h"
#import "NVHeader.h"
#import "NvRecord.h"
#import "NvVoiceTypeView.h"
#import "NvSequenceViewCtl.h"
#import "NvsAudioClip.h"
#import "NvsAudioFx.h"
#import "NvRecordModel.h"
#import <MediaPlayer/MediaPlayer.h>
#import "NvSystemVolume.h"
#import "NvSDKUtils.h"

typedef enum : NSUInteger {
    NvRecordingStart,//准备录制
    NvRecordingStop,//录制过程中
    NvRecordingDelete,//准备删除
} NvRecordingStatus;

@interface NvRecordViewController ()<NvLiveWindowPanelViewDelegate, NvsStreamingContextDelegate, NvSequenceViewCtlDelegate> {
    float left,right,musicLeft,musicRight;
    NvSystemVolume *volumeView;
}

@property (nonatomic, strong) NvButton *minusButton;
@property (nonatomic, strong) NvButton *addButton;
@property (nonatomic, strong) UILabel *timeLabel;
@property (nonatomic, strong) UIButton *styleButton;
@property (nonatomic, strong) UIButton *okButton;
@property (nonatomic, strong) NvDubbingModel *dubbingModel;//配音数据
@property (nonatomic, strong) NvRecord *record;//录音对象
@property (nonatomic, strong) UIButton *addRecordButton;
@property (nonatomic, assign) NvRecordingStatus status;
@property (nonatomic, strong) NSMutableArray *recordingPathInfoArray;
@property (nonatomic, strong) UISlider *volumSlider;
@property (nonatomic, strong) NvVoiceTypeView *voiceTypeView;
@property (nonatomic, strong) NvSequenceViewCtl *sequenceView;
@property (nonatomic, strong) UIButton *playButton;

@property (nonatomic, assign) int64_t currentPosition;
@property (nonatomic, strong) NvsAudioTrack *audioTrack;
@property (nonatomic, strong) NvsAudioClip *clip;
@property (nonatomic, strong) NvRecordModel *model;//当前录音数据对象
@property (nonatomic, assign) BOOL isManualPlay;//是否是手动播放，还是录制播放
@property (nonatomic, strong) NSMutableArray *needRemoveClip;//当前录音过程中需要移除的clip
@property (nonatomic, assign) BOOL granted;
@property (nonatomic, assign) BOOL isFxModel;//是否是特效模式
@property (nonatomic, assign) int64_t fxPosition;//fx当前的时间

@property (nonatomic) float volume;//系统声音

@property (nonatomic, strong) UIView *line;

@end

@implementation NvRecordViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"配音";
    self.recordingPathInfoArray = [NSMutableArray array];
    [self initTimeline];
    
    self.needRemoveClip = [NSMutableArray array];
    [self initSubViews];
    [self.liveWindowPanel setForceHiddenControlPanel:YES];
    [self.liveWindowPanel addTapScreenPause];
    self.liveWindowPanel.delegate = self;
    self.record = [NvRecord new];
//    MPMusicPlayerController *mp=[MPMusicPlayerController applicationMusicPlayer];
//    self.volume = mp.volume;
    self.timeLabel.text= [NSString stringWithFormat:@"%@/%@",[NvUtils convertTimecodePrecision:self.currentPosition],[NvUtils convertTimecodePrecision:self.timeline.duration]];
    [self setSequenceDefaultData];
    [self showFxVolume];
    AVAudioSession *session =[AVAudioSession sharedInstance];
    self.granted = YES;
    [session requestRecordPermission:^(BOOL granted) {
        if (!granted) {
            [NvToast showInfoWithMessage:@"录音权限被禁止"];
            self->_granted = granted;
            return ;
        }
    }];
}
//MARK: 返回按钮
- (UIView *)leftNavigationBarItemView {
    return [UIView new];
}

//MARK:给Sequence设置默认数据
- (void)setSequenceDefaultData {
    for (int i = 0; i < self.dubbingModel.dubbingInfoModels.count; i++) {
        NvDubbingInfoModel *modelInfo = self.dubbingModel.dubbingInfoModels[i];
        NvRecordModel *model = [NvRecordModel new];
        model.recordingPath = modelInfo.dubbingFilePath;
        model.inpoint = modelInfo.inPoint;
        model.trimIn = modelInfo.trimIn;
        model.outpoint = modelInfo.inPoint + modelInfo.duration - modelInfo.trimIn;
        model.volume = modelInfo.volume;
        model.builtInFxName = modelInfo.builtInFxName;
        [self.recordingPathInfoArray addObject:model];
    }
    [self.sequenceView updateSpanItems:self.recordingPathInfoArray];
}

- (void)showFxVolume {
    self.clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    if (self.clip) {
        self.status = NvRecordingDelete;
    } else {
        self.status = NvRecordingStart;
    }
    
    //是否显示特效按钮
    self.styleButton.hidden = !self.clip;
    self.volumSlider.hidden = !self.clip;
    self.model = [self getModelWithClip:self.clip];
    if (self.clip) {
        float left;
        [self.clip getVolumeGain:&left rightVolumeGain:&left];
        self.volumSlider.value = left;
    }
}

//MARK:重新创建timeline和数据结构
- (void)initTimeline {
    self.timeline = [NvTimelineUtils createTimeline:self.editMode];
    [NvTimelineUtils recreateTimeline:self.timeline];
    NvTimelineData *data = [NvTimelineData sharedInstance];
    self.dubbingModel = [data.dubbingModel copy];
//    self.dubbingDataArray = [[NSMutableArray alloc] initWithArray:[data dubbingDataArray] copyItems:YES];
    [NvTimelineUtils resetDubbingTrack:self.timeline dubbingModel:self.dubbingModel];
    self.audioTrack = [self.timeline getAudioTrackByIndex:NV_DUBBING_SOUND_TRACK];
}

- (void)setStatus:(NvRecordingStatus)status {
    _status = status;
    if (status == NvRecordingStart) {
        [self.addRecordButton setImage:[NvUtils imageWithName:@"NvRecordingStart"] forState:UIControlStateNormal];
    } else if (status == NvRecordingStop) {
        [self.addRecordButton setImage:[NvUtils imageWithName:@"NvRecordingStop"] forState:UIControlStateNormal];
    } else {
        [self.addRecordButton setImage:[NvUtils imageWithName:@"deleteRecord"] forState:UIControlStateNormal];
    }
}
// MARK:更改音量
- (void)volumChanged:(UISlider *)slider {
    self.model.volume = slider.value;
    NvsAudioClip *clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    [clip setVolumeGain:slider.value rightVolumeGain:slider.value];
}

- (void)fxClick {
    self.isFxModel = YES;
    self.fxPosition = self.currentPosition;
    NvsAudioClip *clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    NvsAudioFx *fx = [clip getFxWithIndex:0];
    NSString *name = fx.bultinAudioFxName;
    for (NvVoiceItem *item in self.voiceTypeView.dataSource) {
        if ((item.builtinName == nil && name == nil) || [item.builtinName isEqualToString:name]) {
            item.isSelect = YES;
        } else {
            item.isSelect = NO;
        }
    }
    self.voiceTypeView.dataSource = self.voiceTypeView.dataSource;
}
// MARK:保存默认音量数据并设置当前音量为0
- (void)saveOriginVideoVolume {
    NvsVideoTrack *videoTrack = [self.timeline getVideoTrackByIndex:0];
    [videoTrack getVolumeGain:&left rightVolumeGain:&right];
    [videoTrack setVolumeGain:0 rightVolumeGain:0];
    NvsAudioTrack *audioTrack = [self.timeline getAudioTrackByIndex:NV_MUSIC_SOUND_TRACK];
    [audioTrack getVolumeGain:&musicLeft rightVolumeGain:&musicRight];
    [audioTrack setVolumeGain:0 rightVolumeGain:0];
}
//MARK: 重新设置音量
- (void)resetOriginVideoVolume {
    NvsVideoTrack *videoTrack = [self.timeline getVideoTrackByIndex:0];
    [videoTrack setVolumeGain:left rightVolumeGain:right];
    NvsAudioTrack *audioTrack = [self.timeline getAudioTrackByIndex:NV_MUSIC_SOUND_TRACK];
    [audioTrack setVolumeGain:musicLeft rightVolumeGain:musicRight];
}
//MARK: 开始录制包含UI变化
- (void)startRecording {
    [self.liveWindowPanel removeTapScreenPause];
    self.status = NvRecordingStop;
    [self.streamingContext stop];
    self.addButton.userInteractionEnabled = NO;
    self.minusButton.userInteractionEnabled = NO;
    self.addRecordButton.userInteractionEnabled = NO;
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        weakSelf.addRecordButton.userInteractionEnabled = YES;
    });
    self.isManualPlay = NO;
    [self saveOriginVideoVolume];
    [self.liveWindowPanel playbackBtnClicked];
    [self.sequenceView setSequenceViewScrollEnabled:NO];
    NSString *recordingPath = [self.record startRecord];
    //静音
    volumeView = [NvSystemVolume instence];
    [self.view addSubview:volumeView];
    self.volume = volumeView.volume;
    volumeView.volume = 0;
    if ([recordingPath isEqualToString:@""]) {
        [self.liveWindowPanel addTapScreenPause];
        [NvToast showInfoWithMessage:@"录制失败,请重试"];
        //恢复音量
        volumeView.volume = self.volume;
        [volumeView removeFromSuperview];
        volumeView = nil;
        [self.liveWindowPanel playbackBtnClicked];
        [self.sequenceView setSequenceViewScrollEnabled:YES];
        self.status = NvRecordingStart;
        [self.record stopRecord];
        self.addButton.userInteractionEnabled = YES;
        self.minusButton.userInteractionEnabled = YES;
        self.addRecordButton.userInteractionEnabled = YES;
        return;
    }
    [self.sequenceView startRecording:self.currentPosition];
    self.model = [NvRecordModel new];
    self.model.recordingPath = recordingPath;
    self.model.inpoint = self.currentPosition;
    self.volumSlider.hidden = YES;
    self.playButton.userInteractionEnabled = NO;
}
//MARK: 结束录制包含UI变化
- (void)stopRecording {
    [self.liveWindowPanel addTapScreenPause];
    self.status = NvRecordingStart;
    [self.record stopRecord];
    //恢复音量
    volumeView.volume = self.volume;
    [volumeView removeFromSuperview];
    volumeView = nil;
    self.addButton.userInteractionEnabled = YES;
    self.minusButton.userInteractionEnabled = YES;
    self.addRecordButton.userInteractionEnabled = YES;
    [self resetOriginVideoVolume];
    [self.sequenceView stopRecording];
    [self.liveWindowPanel playbackBtnClicked];
    [self.sequenceView setSequenceViewScrollEnabled:YES];
    self.model.outpoint = self.currentPosition;
    
    for (int i = 0; i < self.recordingPathInfoArray.count; i++) {
        NvRecordModel *model = self.recordingPathInfoArray[i];
        if (model.inpoint >= self.model.inpoint && self.model.outpoint >=model.inpoint && model.outpoint>=self.model.outpoint) {
            //覆盖一半需要裁剪trimin
            model.trimIn = self.model.outpoint - model.inpoint;
            model.inpoint = self.model.outpoint;
        } else if (model.inpoint >= self.model.inpoint && model.outpoint <= self.model.outpoint) {
            //直接删除
            [self.recordingPathInfoArray removeObject:model];
            i--;
        }
    }
    
    [self.recordingPathInfoArray addObject:self.model];
    self.playButton.userInteractionEnabled = YES;

    NvsAudioClip *clip = [self.audioTrack addClip:self.model.recordingPath inPoint:self.model.inpoint trimIn:0 trimOut:self.model.outpoint - self.model.inpoint];
    [clip setVolumeGain:self.model.volume rightVolumeGain:self.model.volume];
    //刷新sequenceView
    [self.sequenceView updateSpanItems:self.recordingPathInfoArray];
    
    //停止录音时，如果当前有录音则要显示删除按钮
    NvsAudioTrack *audioTrack = [self.timeline getAudioTrackByIndex:NV_DUBBING_SOUND_TRACK];
    self.clip = [audioTrack getClipWithTimelinePosition:self.currentPosition];
    self.model = [self getModelWithClip:self.clip];
    
    //是否显示特效按钮
    self.styleButton.hidden = !self.clip;
    self.volumSlider.hidden = !self.clip;
    
    if (self.clip) {
        float left;
        [self.clip getVolumeGain:&left rightVolumeGain:&left];
        self.volumSlider.value = left;
    }
    
    //滑动时不响应录音
    if (self.clip) {
        self.status = NvRecordingDelete;
    } else {
        self.status = NvRecordingStart;
    }
}
//MARK: 删除录制
- (void)deleteRecording {
    self.status = NvRecordingStart;
    [self.audioTrack removeClip:self.clip.index keepSpace:YES];
    //删除数据
    for (NvRecordModel *model in self.recordingPathInfoArray) {
        if (model.inpoint <= self.currentPosition && model.outpoint >= self.currentPosition) {
            [self.recordingPathInfoArray removeObject:model];
            [self.sequenceView removeSpanItem:self.currentPosition];
            break;
        }
    }
    //刷新sequenceView
    [self.sequenceView updateSpanItems:self.recordingPathInfoArray];
    self.clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    //是否显示特效按钮
    self.styleButton.hidden = !self.clip;
    self.volumSlider.hidden = !self.clip;
}

- (NvRecordModel *)getModelWithClip:(NvsAudioClip *)clip {
    for (int i = 0; i < self.recordingPathInfoArray.count; i++) {
        NvRecordModel *model = self.recordingPathInfoArray[i];
        if (model.inpoint == clip.inPoint && model.outpoint == clip.outPoint) {
            return model;
        }
    }
    return nil;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
// MARK: 初始化视图
- (void)initSubViews {
    self.volumSlider = [[UISlider alloc] initWithFrame:CGRectMake(SCREANWIDTH-125*SCREANSCALE, self.liveWindowPanel.centerY, 191*SCREANSCALE, 20*SCREANSCALE)];
    self.volumSlider.value = 1;
    self.volumSlider.maximumValue = 4;
    [self.volumSlider setThumbImage:[NvUtils imageWithName:@"NvSliderHandle"] forState:UIControlStateNormal];
    [self.view addSubview:self.volumSlider];
    self.volumSlider.transform = CGAffineTransformRotate(self.volumSlider.transform, -M_PI_2);
    [self.volumSlider addTarget:self action:@selector(volumChanged:) forControlEvents:UIControlEventValueChanged];
    self.volumSlider.hidden = YES;
    
    self.okButton = [UIButton nv_buttonWithTitle:nil textColor:nil fontSize:-1 image:[NvUtils imageWithName:@"Nvcheck - material"]];
    [self.view addSubview:self.okButton];
    [self.okButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.width.equalTo(@(25*SCREANSCALEHEIGHT));
        make.height.equalTo(@(20*SCREANSCALEHEIGHT));
        if (@available(iOS 11.0, *)) {
            make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-15*SCREANSCALEHEIGHT);
        } else {
            // Fallback on earlier versions
            make.bottom.equalTo(@(-15*SCREANSCALEHEIGHT));
        }
    }];
//MARK: 确定按钮
    __weak typeof(self)weakSelf = self;
    [self.okButton nv_BtnClickHandler:^{
        //如果正在录制则停止
        if (weakSelf.record.isRecording) {
            [weakSelf.record stopRecord];
            [weakSelf.liveWindowPanel playbackBtnClicked];
            [weakSelf.sequenceView stopRecording];
            weakSelf.model.outpoint = weakSelf.currentPosition;
            [weakSelf.recordingPathInfoArray addObject:weakSelf.model];
        }
        
        [weakSelf.streamingContext removeTimeline:weakSelf.timeline];
        NSMutableArray *order = [[NvTimelineData sharedInstance] dataOrder];
        [order removeObject:@"Dubbing"];
        [order addObject:@"Dubbing"];
        NvDubbingModel *md = [NvDubbingModel new];
        NSMutableArray *dubArray = [NSMutableArray array];
        for (NvRecordModel *model in weakSelf.recordingPathInfoArray) {
            NvDubbingInfoModel *modelInfo = [NvDubbingInfoModel new];
            modelInfo.dubbingFilePath = model.recordingPath;
            modelInfo.volume = model.volume;
            modelInfo.speed = 1;
            modelInfo.inPoint = model.inpoint;
            modelInfo.trimIn = model.trimIn;
            modelInfo.duration = model.outpoint - model.inpoint + model.trimIn;
            modelInfo.builtInFxName = model.builtInFxName;
            [dubArray addObject:modelInfo];
        }
        md.dubbingInfoModels = dubArray;
        md.volume = weakSelf.dubbingModel?weakSelf.dubbingModel.volume:1;
        if (dubArray.count == 0) {
            md = nil;
        }
        [[NvTimelineData sharedInstance] setDubbingModel:md];
        [weakSelf.navigationController popViewControllerAnimated:YES];
    }];
    
    self.line = [UIView new];
    self.line.backgroundColor = [UIColor nv_colorWithHexARGB:@"#1AFFFFFF"];
    [self.view addSubview:self.line];
    [self.line mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(@0);
        make.height.equalTo(@1);
        make.bottom.equalTo(self.okButton.mas_top).offset(-12*SCREANSCALE);
    }];
    
    self.addRecordButton = [UIButton nv_buttonWithTitle:nil textColor:nil fontSize:-1 image:[NvUtils imageWithName:@"NvRecordingStart"]];
    [self.view addSubview:self.addRecordButton];
    [self.addRecordButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.width.height.equalTo(@(40*SCREANSCALE));
        make.bottom.equalTo(self.okButton.mas_top).offset(-26*SCREANSCALE);
    }];
    
    [self.addRecordButton nv_BtnClickHandler:^{
        if (weakSelf.status == NvRecordingStart) {
            if (weakSelf.granted == NO) {
                return ;
            }
            [weakSelf startRecording];
        } else if (weakSelf.status == NvRecordingStop) {
            [weakSelf stopRecording];
        } else {
            [weakSelf deleteRecording];
        }
    }];
    
    UIView *sequenceView = [UIView new];
    [self.view addSubview:sequenceView];
    sequenceView.backgroundColor = [UIColor clearColor];
    [sequenceView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(@(49*SCREANSCALE));
        make.left.right.equalTo(@0);
        make.bottom.equalTo(self.addRecordButton.mas_top).offset(-26*SCREANSCALE);
    }];
    [self.view layoutIfNeeded];

    self.sequenceView = [[NvSequenceViewCtl alloc] initWithFrame:CGRectMake(0, 0, SCREANWIDTH, sequenceView.height)];
    self.sequenceView.delegate = self;
    NvsVideoTrack *videoTrack = [self.timeline getVideoTrackByIndex:0];
    NSMutableArray *clipPath = [NSMutableArray array];
    for (int i = 0; i < videoTrack.clipCount; i++) {
        NvsVideoClip *clip = [videoTrack getClipWithIndex:i];
        NvsThumbnailSequenceDesc *info = [[NvsThumbnailSequenceDesc alloc] init];
        info.mediaFilePath = clip.filePath;
        info.inPoint = clip.inPoint;
        info.outPoint = clip.outPoint;
        info.trimIn = clip.trimIn;
        info.trimOut = clip.trimOut;
        info.stillImageHint = false;
        [clipPath addObject:info];
    }
    
    [self.sequenceView initSequenceViewCtl:clipPath duration:self.timeline.duration];
    
    [sequenceView addSubview:self.sequenceView];
    
    self.playButton = [UIButton nv_buttonWithTitle:nil textColor:nil fontSize:-1 image:[NvUtils imageWithName:@"NvPlayback"]];
    [self.playButton setImage:[NvUtils imageWithName:@"NvPause"] forState:UIControlStateSelected];
    self.playButton.frame = CGRectMake(0, 0, self.sequenceView.height, self.sequenceView.height);
    self.playButton.backgroundColor = self.view.backgroundColor;
    [self.sequenceView addSubview:self.playButton];
    
    [self.playButton nv_BtnClickHandler:^{
        weakSelf.playButton.selected = !weakSelf.playButton.selected;
        if (weakSelf.playButton.selected) {
            weakSelf.isManualPlay = YES;
            [[NvSDKUtils getSDKContext] playbackTimeline:weakSelf.timeline startTime:[[NvSDKUtils getSDKContext] getTimelineCurrentPosition:weakSelf.timeline] endTime:weakSelf.timeline.duration videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize preload:YES flags:0];
        } else {
            [[NvSDKUtils getSDKContext] stop];
        }
    }];
    
    self.minusButton = [NvButton nv_buttonWithTitle:nil textColor:nil fontSize:-1 image:[NvUtils imageWithName:@"Nvminus"]];
    [self.view addSubview:self.minusButton];
    self.addButton = [NvButton nv_buttonWithTitle:nil textColor:nil fontSize:-1 image:[NvUtils imageWithName:@"Nvadd"]];
    [self.view addSubview:self.addButton];
    self.timeLabel = [UILabel nv_labelWithText:@"00:00.0/00:00.0" fontSize:10 textColor:[UIColor nv_colorWithHexRGB:@"#FFFFFF"]];
    [self.view addSubview:self.timeLabel];
    float height = self.liveWindowPanel.bottom;
    
    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(sequenceView.mas_top).offset(-16*SCREANSCALEHEIGHT);
        make.centerX.equalTo(self.view);
    }];
    [self.minusButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.timeLabel.mas_left).offset(-19*SCREANSCALE);
        make.height.width.equalTo(@(12*SCREANSCALEHEIGHT));
        make.centerY.equalTo(self.timeLabel);
    }];
    [self.addButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.timeLabel.mas_right).offset(19*SCREANSCALE);
        make.height.width.equalTo(@(12*SCREANSCALEHEIGHT));
        make.centerY.equalTo(self.timeLabel);
    }];
    
    [self.minusButton nv_BtnClickHandler:^{
        [weakSelf.sequenceView scaleSequenceView:0.8];
    }];
    
    [self.addButton nv_BtnClickHandler:^{
        [weakSelf.sequenceView scaleSequenceView:1.2];
    }];
    
    self.styleButton = [UIButton nv_buttonWithTitle:@"声效" textColor:[UIColor whiteColor] fontSize:10];
    self.styleButton.backgroundColor = [UIColor nv_colorWithHexRGB:@"#4A90E2"];
    [self.view addSubview:self.styleButton];
    [self.styleButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(@(-13*SCREANSCALE));
        make.centerY.equalTo(self.addButton);
        make.width.equalTo(@(39*SCREANSCALE));
        make.height.equalTo(@(17*SCREANSCALE));
    }];
    self.styleButton.layer.cornerRadius = 17/2.0*SCREANSCALE;
    self.styleButton.layer.masksToBounds = YES;
    [self.styleButton nv_BtnClickHandler:^{
        weakSelf.voiceTypeView = [NvVoiceTypeView new];
        weakSelf.voiceTypeView.delegate = weakSelf;
        [weakSelf.view addSubview:weakSelf.voiceTypeView];
        [weakSelf.voiceTypeView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.bottom.equalTo(@0);
            make.top.equalTo(@(height+10*SCREANSCALE));
        }];
        [weakSelf fxClick];
    }];
}



//MARK: 变声代理回调NvVoiceTypeViewDelegate
- (void)voiceTypeView:(NvVoiceTypeView *)voiceTypeView didSelectItem:(NvVoiceItem *)item {
    [self.clip removeFx:0];
    [self.clip appendFx:item.builtinName];
    [self.streamingContext playbackTimeline:self.timeline startTime:self.clip.inPoint endTime:self.clip.outPoint videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize preload:YES flags:0];
    self.model.builtInFxName = item.builtinName;
}

- (void)voiceTypeView:(NvVoiceTypeView *)voiceTypeView okClick:(UIButton *)button {
    self.isFxModel = NO;
    [self seekTimeline:self.fxPosition];
    self.sequenceView.timelinePosition = self.fxPosition;
    [self.voiceTypeView removeFromSuperview];
    self.voiceTypeView = nil;
    [self.streamingContext stop];
}
//MARK: 缩略图代理回调NvSequenceViewCtlDelegate
- (void)sequenceViewCtl:(id)sequenceViewCtl scroll:(int64_t)timestamp {
    [self seekTimeline:timestamp];
    self.playButton.selected = NO;
    self.currentPosition = timestamp;
    self.timeLabel.text= [NSString stringWithFormat:@"%@/%@",[NvUtils convertTimecodePrecision:timestamp],[NvUtils convertTimecodePrecision:self.timeline.duration]];
    
    self.clip = [self.audioTrack getClipWithTimelinePosition:timestamp];
    self.model = [self getModelWithClip:self.clip];
    //是否显示特效按钮
    self.styleButton.hidden = !self.clip;
    self.volumSlider.hidden = !self.clip;
    
    if (self.clip) {
        float left;
        [self.clip getVolumeGain:&left rightVolumeGain:&left];
        self.volumSlider.value = left;
    }
    
    //滑动时不响应录音
    self.addRecordButton.userInteractionEnabled = NO;
    if (self.clip) {
        self.status = NvRecordingDelete;
    } else {
        self.status = NvRecordingStart;
    }
}

- (void)sequenceViewCtl:(id)sequenceViewCtl scrollEnded:(int64_t)timestamp {
    self.addRecordButton.userInteractionEnabled = YES;
}

//MARK: sdk Context代理方法
- (void)didPlaybackTimelinePosition:(NvsTimeline *)timeline position:(int64_t)position {
    self.sequenceView.timelinePosition = position;
    self.playButton.selected = YES;
    self.timeLabel.text= [NSString stringWithFormat:@"%@/%@",[NvUtils convertTimecodePrecision:position],[NvUtils convertTimecodePrecision:self.timeline.duration]];
    self.currentPosition = position;
    self.clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    //如果是手动点击的播放
    if (self.isManualPlay) {
        if (self.clip) {
            self.status = NvRecordingDelete;
        } else {
            self.status = NvRecordingStart;
        }
        
        //是否显示特效按钮
        self.styleButton.hidden = !self.clip;
        self.volumSlider.hidden = !self.clip;
        self.model = [self getModelWithClip:self.clip];
        if (self.clip) {
            float left;
            [self.clip getVolumeGain:&left rightVolumeGain:&left];
            self.volumSlider.value = left;
        }
    }
}

- (void)didPlaybackStopped:(NvsTimeline *)timeline {
    self.playButton.selected = NO;
    self.clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];
    self.styleButton.hidden = !self.clip;
}

- (void)didPlaybackEOF:(NvsTimeline *)timeline {
    if (self.isFxModel) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self seekTimeline:self.fxPosition];
            self.sequenceView.timelinePosition = self.fxPosition;
        });
        return;
    }
    if (self.record.isRecording) {
        [self stopRecording];
    }
    
    self.sequenceView.timelinePosition = 0;
    [self seekTimeline:0];
    self.playButton.selected = NO;
    self.timeLabel.text= [NSString stringWithFormat:@"%@/%@",[NvUtils convertTimecodePrecision:0],[NvUtils convertTimecodePrecision:self.timeline.duration]];
    self.currentPosition = 0;
    self.clip = [self.audioTrack getClipWithTimelinePosition:self.currentPosition];

    if (self.clip) {
        self.status = NvRecordingDelete;
    } else {
        self.status = NvRecordingStart;
    }
    //是否显示特效按钮
    self.styleButton.hidden = !self.clip;
    self.volumSlider.hidden = !self.clip;
    
    if (self.clip) {
        float left;
        [self.clip getVolumeGain:&left rightVolumeGain:&left];
        self.volumSlider.value = left;
    }
}

@end
