//
//  AliyunRecorder.h
//  AliyunVideoSDKPro
//
//  Created by coder.pi on 2021/4/20.
//  Copyright © 2021 aliyun. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AliyunRecorderConfig.h"
#import "AliyunClipManager.h"

/**
 *  @defgroup ugc_recorder 视频录制
 *  @ingroup ugc
 *  @{
 */
/** @}*/

/**
 *  @defgroup ugc_single_recorder 视频录制
 *  @ingroup ugc_recorder
 *  @{
 */

/**
 录制状态 API_AVAILABLE(3.22.0)
 */
typedef NS_ENUM(NSUInteger, AliyunRecorderState) {
    /**
     空闲状态，等待录制 API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_Idle = 0,
    /**
     录制前加载；等待各个录制源首帧回调；收到全部回调后会自动变为recording状态 API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_LoadingForRecord,
    /**
     录制中 API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_Recording,
    /**
     正在停止；等待内部缓冲处理完成会自动变为停止状态 API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_Stopping,
    /**
     停止录制 API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_Stop,
    /**
     发生错误；可以通过cancel来把状态重置为idle API_AVAILABLE(3.22.0)
     */
    AliyunRecorderState_Error,
    
    AliyunRecorderState_Max,
};

@class AliyunRecorder;
/**
 录制事件回调 API_AVAILABLE(3.22.0)
 */
@protocol AliyunRecorderDelegate <NSObject>
@optional
/**
 录制状态发生改变 API_AVAILABLE(3.22.0)
 */
- (void) onAliyunRecorder:(AliyunRecorder *)recorder stateDidChange:(AliyunRecorderState)state;
/**
 预览状态发生改变 API_AVAILABLE(3.22.0)
 */
- (void) onAliyunRecorder:(AliyunRecorder *)recorder previewStateDidChange:(BOOL)isPreviewing;
/**
  录制进度发生改变 API_AVAILABLE(3.22.0)
 */
- (void) onAliyunRecorder:(AliyunRecorder *)recorder progressWithDuration:(CGFloat)duration;
/**
  录制发生了错误 API_AVAILABLE(3.22.0)
 */
- (void) onAliyunRecorder:(AliyunRecorder *)recorder occursError:(NSError *)error;

/**
 即将到达最大时长时回调 API_AVAILABLE(3.26.0)
 */
- (void) onAliyunRecorderWillStopWithMaxDuration:(AliyunRecorder *)recorder;

/**
 当录至最大时长时回调 API_AVAILABLE(3.26.0)
 */
- (void) onAliyunRecorderDidStopWithMaxDuration:(AliyunRecorder *)recorder;

@end

/**
 自定义渲染回调 API_AVAILABLE(3.22.0)
 */
@protocol AliyunRecorderCustomRender <NSObject>
@optional
/**
 通过CMSampleBuffer自定义渲染，并返回结果的CVPixelBufferRef API_AVAILABLE(3.22.0)
 */
- (CVPixelBufferRef) onAliyunRecorderCustomRenderToPixelBuffer:(AliyunRecorder *)recorder
                                              withSampleBuffer:(CMSampleBufferRef)sampleBuffer;

/**
 通过CMSampleBuffer自定义渲染(与摄像头预览分辨率一致)，并返回结果的CVPixelBufferRef API_AVAILABLE(6.9.2)
 */
- (CVPixelBufferRef) onAliyunRecorderCustomRenderToPixelBuffer:(AliyunRecorder *)recorder
                                       withPreviewSampleBuffer:(CMSampleBufferRef)sampleBuffer;

/**
 通过CMSampleBuffer自定义渲染，并返回结果的纹理ID API_AVAILABLE(3.22.0)
 */
- (int) onAliyunRecorderCustomRenderToTexture:(AliyunRecorder *)recorder
                             withSampleBuffer:(CMSampleBufferRef)sampleBuffer;
/**
 通过纹理ID渲染，并返回结果的纹理ID API_AVAILABLE(3.22.0)
 
 @param textureId 纹理id
 @param size 纹理大小
 */
- (int) onAliyunRecorderCustomRenderToTexture:(AliyunRecorder *)recorder
                             withSrcTextureId:(int)textureId
                                         size:(CGSize)size;

/**
 建议销毁自定义渲染相关 API_AVAILABLE(3.22.0)
 */
- (void) onAliyunRecorderDidDestory:(AliyunRecorder *)recorder;
@end

/**
 多源录制器
 */
@interface AliyunRecorder : NSObject
/**
 是否正在录制 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, readonly) BOOL isRecording;
/**
 是否正在预览 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, readonly) BOOL isPreviewing;
/**
 录制状态 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, readonly) AliyunRecorderState state;
/**
 录制事件回调 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, weak) id<AliyunRecorderDelegate> delegate;
/**
 自定义渲染，仅对摄像头采集数据回调 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, weak) id<AliyunRecorderCustomRender> customRender;

/**
 录制输出配置 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, readonly) AliyunRecorderConfig *config;
/**
 录制速率 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, assign) CGFloat rate;
/**
 片段管理器 API_AVAILABLE(3.22.0)
 */
@property (nonatomic, readonly) AliyunClipManager *clipManager;

/**
 初始化 API_AVAILABLE(3.22.0)
 
 @param config 输出视频配置
 */
- (instancetype) initWithConfig:(AliyunRecorderConfig *)config;

/**
 API_AVAILABLE(3.22.0)
 录制准备；一些录制源可能需要在这阶段去做权限申请之类；如果不调用会在开始录制或者开始预览时调用
 @return 准备是否成功
 */
- (BOOL) prepare;

/**
 开始预览 API_AVAILABLE(3.22.0)
 */
- (int) startPreview;
/**
 结束预览 API_AVAILABLE(3.22.0)
 */
- (void) stopPreview;

/**
 开始录制 API_AVAILABLE(3.22.0)
 */
- (int) startRecord;
/**
 结束录制 API_AVAILABLE(3.22.0)
 */
- (void) stopRecord;

/**
 结束录制 API_AVAILABLE(3.22.0)
 
 @param completion 结束完成的回调；结束录制需要对多段录制进行异步拼接；拼接完成会调用此回调
 */
- (void) finishRecord:(void(^)(NSString *outputPath, NSError *error))completion;

/**
 结束录制，输出给编辑器 API_AVAILABLE(3.23.0)
 
 @param completion 结束完成的回调
 */
- (void) finishRecordForEdit:(void(^)(NSString *taskPath, NSError *error))completion;

/**
 取消录制；删除之前录制片段，状态重置为idle API_AVAILABLE(3.22.0)
 */
- (void) cancel;
@end

/** @}*/

