//
//  AlivcLivePusher.h
//  AlivcLiveCaptureLib
//
//  Created by TripleL on 17/7/13.
//  Copyright © 2017年 Alibaba. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <VideoToolbox/VideoToolbox.h>
#import <UIKit/UIKit.h>
#import <ReplayKit/ReplayKit.h>
#import "AlivcLivePushConfig.h"
#import "AlivcLivePushStatsInfo.h"
#import "AlivcLivePushError.h"
#import "AlivcLivePushDef.h"

/// @details 阿里云直播推流SDK从4.4.2版本开始增加license管理，老版本升级到4.4.2及以后版本需要参照阿里云官网获取推流SDK license
///  其SDK接入流程变化：
///  1. 在Info.plist中配置licenseKey和licenseFile
///  2.调用[AlivcLiveBase registerSDK]注册推流SDK
///  3.监听onLicenceCheck回调，确保license校验通过
///  4.创建推流对象，开始直播推流
///  其相关文档参考https://help.aliyun.com/document_detail/431730.html、
///  https://help.aliyun.com/document_detail/94821.html、https://help.aliyun.com/document_detail/94828.html

/// @details From V4.4.2, Alibaba Cloud Push SDK adds the support for license management. If you upgrade Push SDK from a previous version to V4.4.2 or later,
/// you need to obtain a license for the SDK, and there are some minor changes in the procedure of integrating the SDK.
/// 1. Configure licenseKey and licenseFile in the Info.plist file
/// 2. Call [AlivcLiveBase registerSDK] to register Push SDK
/// 3. Listen to the onLicenceCheck callback to ensure that the license verification is passed
/// 4. Create an object to start stream push
/// For more information, see https://help.aliyun.com/document_detail/431730.html、
///  https://help.aliyun.com/document_detail/94821.html、https://help.aliyun.com/document_detail/94828.html

/**
 * @details 错误回调, 网络回调, 状态回调, BGM回调, 滤镜回调
 */


@protocol AlivcLivePusherErrorDelegate,
AlivcLivePusherNetworkDelegate,
AlivcLivePusherInfoDelegate,
AlivcLivePusherBGMDelegate,
AlivcLivePusherCustomFilterDelegate,
AlivcLivePusherCustomDetectorDelegate,
AlivcLivePusherSnapshotDelegate,
AlivcLivePusherAudioSampleDelegate;



/**
 * @defgroup AlivcLivePusher 直播推流引擎
 * @ingroup live
 *  直播推流功能的主要接口类
 *  @{
 */

@interface AlivcLivePusher : NSObject



/**
 * @brief 显示调试悬浮窗
 * @note 注意 ：Debug悬浮窗会占用一定的系统资源，只可用于APP研发的Debug阶段，Release版本请勿调用此接口
 */

+ (void)showDebugView;



/**
 * @brief 隐藏调试悬浮窗
 */

+ (void)hideDebugView;


/**
 * @brief 创建一个推流引擎实例
 * @param config 推流配置信息 {@link AlivcLivePushConfig}
 * @return self:success  nil:failure
 * @note 同一时间只会存在一个主推流引擎实例
 */

- (instancetype)initWithConfig:(AlivcLivePushConfig *)config;

/**
 * @brief 设置推流错误监听回调
 * @param delegate {@link AlivcLivePusherErrorDelegate}
 */

- (void)setErrorDelegate:(id<AlivcLivePusherErrorDelegate>)delegate;


/**
 * @brief 设置推流状态监听回调
 * @param delegate {@link AlivcLivePusherInfoDelegate}
 */

- (void)setInfoDelegate:(id<AlivcLivePusherInfoDelegate>)delegate;

/**
 * @brief 设置推流网络监听回调
 * @param delegate {@link AlivcLivePusherNetworkDelegate}
 */

- (void)setNetworkDelegate:(id<AlivcLivePusherNetworkDelegate>)delegate;

/**
 * @brief 设置用户自定义滤镜回调
 * @param delegate {@link AlivcLivePusherCustomFilterDelegate}
 */

- (void)setCustomFilterDelegate:(id<AlivcLivePusherCustomFilterDelegate>)delegate;


/**
 * @brief 设置用户自定义人脸识别回调
 * @param delegate {@link AlivcLivePusherCustomDetectorDelegate}
 */

- (void)setCustomDetectorDelegate:(id<AlivcLivePusherCustomDetectorDelegate>)delegate;

/**
 * @brief 设置背景音乐监听回调
 * @param delegate {@link AlivcLivePusherBGMDelegate}
 */

- (void)setBGMDelegate:(id<AlivcLivePusherBGMDelegate>)delegate;

/**
 * @brief 设置音频裸数据回调
 * @param delegate {@link AlivcLivePusherAudioSampleDelegate}
 */

- (void)setAudioSampleDelegate:(id<AlivcLivePusherAudioSampleDelegate>)delegate;

/**
 * @brief 开始预览 同步接口
 * @param previewView 预览view
 * @return 0:success  非0:failure
 */

- (int)startPreview:(UIView *)previewView;


/**
 * @brief 停止预览
 * @return 0:success  非0:failure
 */

- (int)stopPreview;


/**
 * @brief 开始推流 同步接口
 * @param pushURL 推流URL
 * @return 0:success  非0:failure
 */

- (int)startPushWithURL:(NSString *)pushURL;


/**
 * @brief 停止推流
 * @return 0:success  非0:failure
 */

- (int)stopPush;


/**
 * @brief 重新推流 同步接口
 * @return 0:success  非0:failure
 */

- (int)restartPush;


/**
 * @brief 暂停摄像头推流，如果pushCongfig 中设置了pauseImg图片，将推设置的静态图片
 * @return 0:success  非0:failure
 */

- (int)pause;



/**
 * @brief 恢复摄像头推流 同步接口
 * @return 0:success  非0:failure
 */

- (int)resume;


/**
 * @brief 重连 异步接口
 * @return 0:success  非0:failure
 */

- (int)reconnectPushAsync;

/**
 * @brief 推流URL的重连 异步接口
 * @return 0:success  非0:failure
 */

- (int)reconnectPushAsync:(NSString *)pushURL;

/**
 * @brief 销毁推流引擎
 */

- (void)destory;



/* ***********************异步接口*********************** */
/**
 * @brief 开始预览 异步接口
 * @param preview 预览view
 * @return 0:success  非0:failure
 */

- (int)startPreviewAsync:(UIView *)preview;


/**
 * @brief 开始推流 异步接口
 * @param pushURL 推流URL
 * @return 0:success  非0:failure
 */

- (int)startPushWithURLAsync:(NSString *)pushURL;


/**
 * @brief 重新推流 异步接口
 * @return 0:success  非0:failure
 */

- (int)restartPushAsync;


/**
 * @brief 恢复推流 异步接口
 * @return 0:success  非0:failure
 */

- (int)resumeAsync;

/* ****************************************************** */



/**
 * @brief 切换摄像头
 * @return 0:success  非0:failure
 */

- (int)switchCamera;


/**
 * @brief 设置自动对焦
 * @param autoFocus true:自动对焦 false:手动对焦
 * @return 0:success  非0:failure
 */

- (int)setAutoFocus:(bool)autoFocus;


/**
 * @brief 对焦
 * @param point 对焦的点，point.x和point.y的取值是(0,1)，表示当前点相对于渲染view的相对位置
 * @param autoFocus 是否自动对焦
 * @return 0:success  非0:failure
 */

- (int)focusCameraAtAdjustedPoint:(CGPoint)point autoFocus:(bool)autoFocus;


/**
 * @brief 缩放
 * @param zoom 缩放值[0:MaxZoom]
 * @return 0:success  非0:failure
 */

- (int)setZoom:(float)zoom;


/**
 * @brief 获取支持的最大变焦值
 * @return 最大变焦值
 */

- (float)getMaxZoom;


/**
 * @brief 获取当前变焦值
 * @return 当前变焦值
 */

- (float)getCurrentZoom;


/**
 * @brief 闪光灯开关
 * @param flash true:打开闪光灯 false:关闭闪光灯
 * @return 0:success  非0:failure
 */

- (int)setFlash:(bool)flash;


/**
 * @brief 设置曝光度
 * @param exposure 曝光度
 * @return 0:success  非0:failure
 */

- (int)setExposure:(float)exposure;


/**
 * @brief 获取当前曝光度
 * @return  曝光度
 */

- (float)getCurrentExposure;

/**
 * @brief 获取支持最小曝光度
 * @return  最小曝光度
 */

- (float)getSupportedMinExposure;

/**
 * @brief 获取支持最大曝光度
 * @return  最大曝光度
 */

- (float)getSupportedMaxExposure;


/**
 * @brief 推流镜像开关
 * @param mirror true:打开推流镜像 false:关闭推流镜像
 */

- (void)setPushMirror:(bool)mirror;


/**
 * @brief 预览镜像开关
 * @param mirror true:打开预览镜像 false:关闭预览镜像
 */

- (void)setPreviewMirror:(bool)mirror;


/**
 * @brief 静音推流
 * @param mute true:静音推流 false:正常推流
 */

- (void)setMute:(bool)mute;


/**
 * @brief 设置推流模式
 * @param qualityMode 推流模式 : 选择 ResolutionFirst 模式时，SDK内部会优先保障推流视频的清晰度; 选择 FluencyFirst 模式时，SDK内部会优先保障推流视频的流畅度，此接口只支持这两种模式。设置后码率设置失效。
 * @return 0:success  非0:failure
 */

- (int)setQualityMode:(AlivcLivePushQualityMode)qualityMode;


/**
 * @brief 设置目标码率
 * @param targetBitrate 目标码率 [100  5000](Kbps)
 * @return 0:success  非0:failure
 */

- (int)setTargetVideoBitrate:(int)targetBitrate;


/**
 * @brief 设置最小码率
 * @param minBitrate 最小码率 [100  5000](Kbps)
 * @return 0:success  非0:failure
 */

- (int)setMinVideoBitrate:(int)minBitrate;

/**
 * @brief 设置预览显示模式
 * @param displayMode 预览显示模式
 */

- (void)setpreviewDisplayMode:(AlivcPusherPreviewDisplayMode)displayMode;


/**
 * @brief 设置推流分辨率
 * @param resolution 推流分辨率
 */

- (void)setResolution:(AlivcLivePushResolution)resolution;



/* ***********************背景音乐*********************** */

/**
 * @brief 播放背景音乐
 * @param path 背景音乐路径
 * @return 0:success  非0:failure
 */

- (int)startBGMWithMusicPathAsync:(NSString *)path;


/**
 * @brief 停止播放背景音乐
 * @return 0:success  非0:failure
 */

- (int)stopBGMAsync;


/**
 * @brief 暂停播放背景音乐
 * @return 0:success  非0:failure
 */

- (int)pauseBGM;


/**
 * @brief 恢复播放背景音乐
 * @return 0:success  非0:failure
 */

- (int)resumeBGM;


/**
 * @brief 设置背景音乐是否循环播放
 * @param isLoop 是否循环  true:循环 false:不循环
 * @return 0:success  非0:failure
 */

- (int)setBGMLoop:(bool)isLoop;


/**
 * @brief 设置背景音乐耳返开关
 * @param isOpen 是否打开耳返  true:开启耳返 false:关闭耳返
 * @return 0:success  非0:failure
 */

- (int)setBGMEarsBack:(bool)isOpen;


/**
 * @brief 设置降噪开关
 * @param isOpen 是否打开降噪 true:开启 false:关闭 默认:true
 * @return 0:success  非0:failure
 */

- (int)setAudioDenoise:(bool)isOpen;

/**
 * @brief 开启智能降噪
 * @return
 * - 0: 成功
 * - 非0: 返回错误码
 * @details
 * - 智能降噪功能以插件形式提供，直播SDK采用插件形式提供音视频增强能力，可通过[官网组件文档] 进行组建下载，参考插件集成文档集成进直播推流引擎
 * https://help.aliyun.com/document_detail/600551.html
 * - 调用该接口前，请确保已集成了直播官网提供的pulginAliDenoise.framework
 * - 此接口可以通话过程中控制打开智能降噪功能，通话过程中可以支持开启和关闭智能降噪
 * - 默认关闭，开启后可能导致功耗增加，智能降噪适合于会议，教育等语音通讯为主的场景，不适合有背景音乐的场景
 */

- (int)startIntelligentDenoise;

/**
 * @brief 关闭智能降噪
 * @note 此接口可以通话过程中控制关闭智能降噪功能
*/

- (int)stopIntelligentDenoise;

/**
 * @brief 设置变声音效模式
 * @param mode 参考 {@link AlivcLivePushAudioEffectVoiceChangerMode} 对应的变声音效模式值
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 推流前和推流过程中调用都生效
 */

- (int)setAudioEffectVoiceChangeMode:(AlivcLivePushAudioEffectVoiceChangeMode)mode;

/**
 * @brief 设置混响音效模式
 * @param mode 参考 {@link AlivcLivePushAudioEffectReverbMode} 对应的混响模式
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 推流前和推流过程中调用都生效
 */

- (int)setAudioEffectReverbMode:(AlivcLivePushAudioEffectReverbMode)mode;

/**
 * @brief 设置背景音乐混音 音乐音量
 * @param volume 音乐音量大小 范围:[0 ~ 100] 默认:50
 * @return 0:success  非0:failure
 */

- (int)setBGMVolume:(int)volume;


/**
 * @brief 设置背景音乐混音 人声音量
 * @param volume 人声音量大小 范围:[0 ~ 100] 默认:50
 * @return 0:success  非0:failure
 */

- (int)setCaptureVolume:(int)volume;

/* **********************开启屏幕分享******************************** */

/**
 * @brief 开始屏幕分享（该接口支持 iOS 11.0 及以上的 iPhone 和 iPad）。
 *
 * @details 该接口开始 iOS 系统的屏幕分享，可以实现录屏推流功能
 *     该接口配合AlivcLibReplayKitExt.framework使用，在Extension进程中添加AlivcLibReplayKitExt.framework库完成屏幕采集和发送
 *     在Host APP中接收音视频数据，完成推流。
 * @param appGroup App group ID 主 App 与 Extension 共享的 Application Group Identifier，当前接口仅支持主 App 与 Extension 属于同一个App *
 * Group的情况，如果不存在App Group， 不可调用该接口。
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode
 * 模式下开始屏幕分享（录屏推流），AlivcLivePushInteractiveMode模式下暂时不支持开始屏幕分享（录屏推流）
 */

- (int)startScreenCapture:(NSString *)appGroup;

/* ***********************外部数据*********************** */

/**
 * @brief 发送自定义video SampleBuffer
 *
 * @param sampleBuffer video sample buffer
 * @note 当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下发送自定义video SampleBuffer，AlivcLivePushInteractiveMode模式下暂时不支持发送自定义video
 * SampleBuffer
 */

- (void)sendVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer;

/**
 * @brief 发送自定义的audio SampleBuffer
 * @details 只限于replaykit录屏直播使用
 *
 * @param sampleBuffer audio sample buffer
 * @param sampleBufferType audio sample buffer type
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下发送自定义的audio
 * SampleBuffer，AlivcLivePushInteractiveMode模式下暂时不支持发送自定义的audio SampleBuffer
 */

- (void)sendAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType;

/**
 * @brief 发送自定义视频数据
 *
 * @param data 视频数据
 * @param width 视频宽度
 * @param height 视频高度
 * @param size 数据大小
 * @param pts 时间戳（单位微秒）
 * @param rotation 旋转
 */

- (void)sendVideoData:(char *)data width:(int)width height:(int)height size:(int)size pts:(uint64_t)pts rotation:(int)rotation;

/**
 * @brief 发送自定义音频数据
 *
 * @param data 音频数据
 * @param size 数据大小
 * @param sampleRate 采样率
 * @param channel 声道数
 * @param pts 时间戳（单位微秒）
 */

- (void)sendPCMData:(char *)data size:(int)size sampleRate:(int)sampleRate channel:(int)channel pts:(uint64_t)pts;

/**
 * @brief 添加视频混流设置
 * @param format 原始视频数据格式 {@link  AlivcLivePushVideoFormat}
 * @param width 图像宽
 * @param height 图像高
 * @param rotation 图像角度
 * @param displayX 图像要放置到屏幕的左上角坐标x
 * @param displayY 图像要放置到屏幕的左上角坐标y
 * @param displayW 图像显示的宽度
 * @param displayH 图像显示的高度
 * @param adjustHeight 图像自适应的高度
 * @return 返回对应视频混流标识ID
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下添加视频混流设置，AlivcLivePushInteractiveMode模式下暂时不支持添加视频混流设置
 */

- (int)addMixVideo:(int)format width:(int)width height:(int)height rotation:(int)rotation displayX:(float)displayX displayY:(float)displayY displayW:(float)displayW displayH:(float)displayH adjustHeight:(bool)adjustHeight;

/**
 * @brief 改变视频混流位置
 * @param handler 视频混流标识ID，通过addMixVideo接口获得
 * @param displayX 图像要放置到屏幕的左上角坐标x
 * @param displayY 图像要放置到屏幕的左上角坐标y
 * @param displayW 图像显示的宽度
 * @param displayH 图像显示的高度
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下改变视频混流位置，AlivcLivePushInteractiveMode模式下暂时不支持改变视频混流位置
 */

- (void)changeMixVideoPosition:(int)handler displayX:(float)displayX displayY:(float)displayY displayW:(float)displayW displayH:(float)displayH;

/**
 * @brief 改变视频混流镜像
 * @param handler 视频混流标识ID，通过addMixVideo接口获得
 * @param isMirror 是否镜像
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下改变视频混流镜像，AlivcLivePushInteractiveMode模式下暂时不支持改变视频混流镜像
 */

- (void)setMixVideoMirror:(int)handler isMirror:(BOOL)isMirror;

/**
 * @brief 输入视频混流数据
 * @param handler 视频混流标识ID，通过addMixVideo接口获得
 * @param dataptr 数据buffer的地址
 * @param width 图像宽
 * @param height 图像高
 * @param stride 图像存储时内存中每行像素所占用的空间
 * @param size 此帧图像的大小
 * @param pts 时间戳（单位微秒）
 * @param rotation 图像角度
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下输入视频混流数据，AlivcLivePushInteractiveMode模式下暂时不支持输入视频混流数据
 */

- (void)inputMixVideoData:(int)handler data:(long)dataptr width:(int)width height:(int)height stride:(int)stride size:(int)size pts:(long)pts rotation:(int)rotation;

/**
 * @brief 移除视频混流设置
 * @param handler 视频混流标识ID，通过addMixVideo接口获得
 */

- (void)removeMixVideo:(int) handler;

/**
 * @brief 添加音频混流设置
 * @param channels 声道数
 * @param format 音频格式  {@link AlivcLivePushAudioFormat}
 * @param audioSample 音频采样率
 * @return 返回对应音频混流标识ID
 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下添加音频混流，AlivcLivePushInteractiveMode模式下暂时不支持添加音频混流
 */

- (int)addMixAudio:(int)channels format:(int)format audioSample:(int)audioSample;

/**
 * @brief 输入音频混流数据
 * @param handler 音频混流标识ID，通过addMixAudio接口获得
 * @param dataptr 数据buffer的地址
 * @param size 音频数据的大小
 * @param pts 时间戳（单位微秒）
 * @return success:true, failed:false
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下输入音频混流数据，AlivcLivePushInteractiveMode模式下暂时不支持输入音频混流数据
 */

- (bool)inputMixAudioData:(int)handler data:(long)dataptr size:(int)size pts:(long)pts;

/**
 * @brief 移除音频混流
 * @param handler 音频混流标识ID，通过addMixAudio接口获得
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下移除音频混流，AlivcLivePushInteractiveMode模式下暂时不支持移除音频混流
 */

- (void)removeMixAudio:(int)handler;

/* ****************************************************** */

/**
 * @brief 设置自定义Message (SEI)
 * @param msg 用户推流消息
 * @param count 重复次数
 * @param time 延时时间，单位毫秒
 * @param isKeyFrame 是否只发关键帧，该参数只支持在livePushMode = AlivcLivePushBasicMode 模式下设置，AlivcLivePushInteractiveMode模式下暂时不支持设置
 * @return 0:success  非0:failure
 */

- (int)sendMessage:(NSString *)msg repeatCount:(int)count delayTime:(int)time KeyFrameOnly:(bool)isKeyFrame;


/**
 * @brief 获取是否正在推流
 * @return YES:正在推流 NO:未推流
 */

- (BOOL)isPushing;


/**
 * @brief 获取当前推流URL
 * @return 推流URL
 */

- (NSString *)getPushURL;

/**
 * @brief 获取当前推流状态
 * @return 推流状态 {@link AlivcLivePushStatus}
 */

- (AlivcLivePushStatus)getLiveStatus;

/**
 * @brief 获取推流数据统计
 * @return 推流数据 {@link AlivcLivePushStatsInfo}
 */

- (AlivcLivePushStatsInfo *)getLivePushStatusInfo;


/**
 * @brief 设置Log级别
 * @param level Log级别 default:AlivcLivePushLogLevelError
 * @return 0:success  非0:failure
 */

- (int)setLogLevel:(AlivcLivePushLogLevel)level __deprecated_msg("Use AlivcLiveBase->setLogLevel instead.");

/**
 * @brief 设置Log路径
 * @param logPath Log路径
 * @param maxPartFileSizeInKB 每个分片最大大小。最终日志总体积是 5*最大分片大小
 * @return 0:success  非0:failure
 */

- (int)setLogPath:(NSString *)logPath maxPartFileSizeInKB:(int)maxPartFileSizeInKB __deprecated_msg("Use AlivcLiveBase->setLogPath:maxPartFileSizeInKB instead.");

/**
 * @brief 获取SDK版本号
 * @return 版本号
 */

+ (NSString *)getSDKVersion __deprecated_msg("Use AlivcLiveBase->getSDKVersion instead.");

/**
 * @brief 添加水印 最多支持3个水印
 * @param path 水印路径
 * @param coordX 水印左上顶点x的相对坐标 [0,1]
 * @param coordY 水印左上顶点y的相对坐标 [0,1]
 * @param width 水印的相对宽度 (水印会根据水印图片实际大小和水印宽度等比缩放) (0,1]
 * @return 0:success  非0:failure
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下添加水印，AlivcLivePushInteractiveMode模式下使用setWatermark添加水印
 */

- (int)addWatermarkWithPath:(NSString *)path
             watermarkCoordX:(CGFloat)coordX
             watermarkCoordY:(CGFloat)coordY
              watermarkWidth:(CGFloat)width;

/**
 * @brief 设置水印显示和隐藏
 * @param visable true:显示水印，false:隐藏水印
 */

- (void)setWatermarkVisible:(bool) visable;

/**
 * @brief 添加动态贴纸,最多支持添加5个贴纸
 * @param waterMarkDirPath：贴纸图片sequence目录
 * @param 显示屏幕x位置（0~1.0f)
 * @param 显示屏幕y位置（0~1.0f)
 * @param 显示屏幕宽
 * @param 显示屏幕高
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushBasicMode 模式下添加动态贴纸，AlivcLivePushInteractiveMode模式下暂时不支持添加动态贴纸
 * @return 返回动态贴纸的id号，删除贴纸传此id
 */

- (int)addDynamicWaterMarkImageDataWithPath:(NSString *)waterMarkDirPath x:(float)x y:(float)y w:(float)w h: (float)h;

/**
 * @brief 删除动态贴纸
 * @param vid:贴纸id，addDynamicWaterMarkImageDataWithPath时返回
 */

- (void)removeDynamicWaterMark:(int)vid;

/**
 * @brief 截图
 * @param count截图次数
 * @param interval 截图间隔
 * @note livePushMode = AlivcLivePushBasicMode 基础模式下可以指定count和interval，
 * AlivcLivePushInteractiveMode模式下暂时不支持指定count和interval，传递任何值都不做解析，每次只截图一张画面
 */

- (void)snapshot:(int)count interval:(int)interval;


/**
 * @brief 设置截图回调
 * @param delegate {@link AlivcLivePusherSnapshotDelegate }
 */

- (void)setSnapshotDelegate:(id<AlivcLivePusherSnapshotDelegate>)delegate;

/* **********************互动模式下特定API******************************** */
/* **********************Specific methods in interactive mode******************************** */

// 以下API是只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
// 非互动模式调用以下API将无任何效果，特定API包括：
// setLiveMixTranscodingConfig
// muteLocalCamera
// enableSpeakerphone
// isEnableSpeakerphone
// refreshPushURLToken
// isCameraAutoFocusFaceModeSupported
// setCameraAutoFocusFaceModeEnabled
//enableAudioVolumeIndication
//setH5CompatibleMode

// Some methods are available only when livePushMode is set to AlivcLivePushInteractiveMode,
// that is, only when Push SDK is working in interactive mode. Calling these methods in non-interactive
// mode have no effect. These methods include:
// setLiveMixTranscodingConfig
// muteLocalCamera
// enableSpeakerphone
// isEnableSpeakerphone
// refreshPushURLToken
// isCameraAutoFocusFaceModeSupported
// setCameraAutoFocusFaceModeEnabled
//enableAudioVolumeIndication
//setH5CompatibleMode

/**
 * @brief 设置云端的混流（转码）参数
 * 一个直播间中可能有不止一位主播，而且每个主播都有自己的画面和声音，但对于 CDN 观众来说，他们只需要一路直播流
 * 所以您需要将多路音视频流混成一路标准的直播流，这就需要混流转码
 * 在连麦场景下，需要将主播和连麦观众音视频流混成一路标准的直播流，供CDN观众观看
 * 在PK场景下，需要将进行PK的多个主播的音视频流混成一路标准的直播流，供CDN观众观看
 * @param config 参考AlivcLiveDef.h中关于{@link AlivcLiveTranscodingConfig}的介绍，如果传入nil，则取消云端混流转码
 * @return 0:success  非0:failure
 * @note 若主播还在房间中但不再需要混流，请务必传入 nil 进行取消，因为当发起混流后，云端混流模块就会开始工作，
 * 不及时取消混流可能会引起不必要的计费损失
 */

- (int)setLiveMixTranscodingConfig:(AlivcLiveTranscodingConfig *)config;

/**
 * @brief 关闭/打开视频（非互动模式暂不支持该API，调用无任何效果）
 * @param mute  YES表示不发送视频数据；NO表示恢复正常
 * @return
 * - 0: 表示Success
 * - 非0: 表示Failure
 */

- (int)muteLocalCamera:(BOOL)mute;

/**
 * @brief 设置音频输出为听筒还是扬声器
 * @param enable
 * - YES: 扬声器模式(默认)
 * - NO: 听筒模式
 * @return
 * - 0: 成功
 * - <0: 失败
 */

- (int)enableSpeakerphone:(BOOL)enable;

/**
 * @brief 获取当前音频输出为听筒还是扬声器
 * @return
 * - YES: 扬声器模式；
 * - NO: 听筒模式
 */

- (BOOL)isEnableSpeakerphone;

/**
 * @brief 刷新Token鉴权信息，传入一个新的推流URL，包含未过期的新token信息，房间ID/用户ID/sdkAppId需要和之前保持一样
 * @details 该方法用于更新鉴权信息推流URL中的token信息，主要为了防止鉴权过期，导致推流失败，当我们收到 {@link onPushURLTokenWillExpire} 回调时，应用应当更新鉴权信息
 * @param pushURL 推流URL
 * @return
 * - 0: 成功
 * - <0: 失败
 */

- (int)refreshPushURLToken:(NSString *_Nonnull)pushUrl;

/**
 * @brief 摄像头是否支持人脸聚焦
 * @return
 * - YES: 支持
 * - NO: 不支持
 * @note 在camera没有打开的情况下返回 NO，
 *    在camera打开的情况下，如果当前camera同时支持人脸识别和对焦功能则返回 YES
*/

- (BOOL)isCameraAutoFocusFaceModeSupported;

/**
 * @brief 设置摄像头人脸对焦
 * @param enable  YES: 开启; NO:关闭
 * @return
 * - YES: 成功
 * - NO: 失败
 * @note 如果 {@link isCameraAutoFocusFaceModeSupported} 返回 YES
 *      且此调用enable为 YES 的情况下，实时对焦到采集到数据的人脸上
*/

- (BOOL)setCameraAutoFocusFaceModeEnabled:(BOOL)enable;

/**
 * @brief 设置音量回调频率和平滑系数
 * @param interval 时间间隔，单位毫秒，最小值不得小于10ms, 建议设置300-500ms, <= 0表示不启用音量提示和说话人提示功能
 * @param smooth 平滑系数，数值越大平滑程度越高，反之越低，实时性越好，建议设置3，范围[0, 9];
 * @param reportVad 说话人检测开关
 * - 1: 打开本地人声检测
 * - 0: 关闭本地人声检测
 * @return
 * - 0: 成功
 * - <0: 失败
 * @note 设置之后，音频音量和说话人uid会分别通过 {@link onMicrophoneVolumeUpdate:} 和 {@link onPlayoutVolumeUpdate:} 回调
 */
- (int)enableAudioVolumeIndication:(int)interval smooth:(int)smooth reportVad:(int)reportVad;

/**
 * @brief 添加水印(互动模式下使用该接口添加水印)
 * @note 水印位置是通过 rect 参数来指定，rect 是一个四元组参数，其格式为 (x，y，width，height)，其中x和y是水印的坐标，取值范围为0 1的浮点数。width：水印的宽度，取值范围为0 - 1的浮点数，height：不需要设置的，SDK 内部会根据水印图片的宽高比自动计算高度。
 * 例如：当推流分辨率是 720 × 1280时，rect 参数为（0.1，0.1，0.3，0.0），则水印的左上角坐标点就是（720 × 0.1，1280 × 0.1）即（72，128），水印的宽度是720x0.3=216，水印高度是根据水印图片的宽高比自动算出来。
 * @param  image 水印图片， 使用透明底色的 png 格式。
 * @param rect 水印相对于推流分辨率的相对坐标，x，y，width，height 取值范围0 - 1。
 */
- (void)setWatermark:(nullable UIImage *)image rect:(CGRect)rect;

/**
 * @brief 开启本地音视频流录制
 * @note 开启后把直播中的音视频内容录制到本地的一个文件。调用接口后，通过onMediaRecordEvent回调通知录制状态
 * @param config 本地录制参数，参见AlivcLiveLocalRecoderConfig
 */

- (BOOL)startRecording:(AlivcLiveLocalRecoderConfig *_Nullable)config;

/**
 * @brief 停止本地音视频流录制
 * @note 如果录制任务在结束推流前尚未通过本接口停止，则结束推流后录制任务会自动被停止。
*/

- (void)stopRecording;

/**
 * @brief 启动屏幕分享
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)startScreenShare;

/**
 * @brief 停止屏幕分享
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)stopScreenShare;


/**
 * @brief 设置音频profile
 * @param audio_profile 音频采集/编码模式参数, 详见 {@link AlivcLiveAudioProfile};
 * @return
 * - 0: 成功
 * - 其他: 失败
 * @note 只支持 {@link startPushWithURL} 前设置有效；
 */

- (int)setAudioProfile:(AlivcLiveAudioProfile)audio_profile;

/**
 * @brief 获取当前视频编码格式
 * @return
 * - AlivcLivePushVideoEncoderModeHardCodecH264: H264
 * - AlivcLivePushVideoEncoderModeHardCodecHEVC: HEVC
 */

- (AlivcLivePushVideoEncoderModeHardCodec)getVideoCodecType;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//      美颜相关api，在v4.2.0版本已删除，推流SDK不再提供内置美颜功能，请使用阿里云Queen提供的美颜服务
//      详见：https://help.aliyun.com/document_detail/211047.html?spm=a2c4g.11174283.6.736.79c5454ek41M8B
//
//
//      From V4.2.0, methods related to face retouching are deleted. Push SDK no longer provides a
//      built-in face retouching   feature. Please use Queen SDK to implement face
//      retouching.：https://help.aliyun.com/document_detail/211047.html?spm=a2c4g.11174283.6.736.79c5454ek41M8B
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@end

/** @} */


/**
 * @defgroup AlivcLivePusher_Delegate 直播推流引擎回调
 * @ingroup live
 *  直播推流引擎回调
 *  @{
 */


/**
 * 推流错误回调
 */

@protocol AlivcLivePusherErrorDelegate <NSObject>

@required

/**
 * @brief 系统错误回调
 * @param pusher 推流引擎对象
 * @param error 错误信息，{@link AlivcLivePushError}
 */

- (void)onSystemError:(AlivcLivePusher *)pusher error:(AlivcLivePushError *)error;


/**
 * @brief SDK错误回调
 * @param pusher 推流引擎对象
 * @param error 错误信息，{@link AlivcLivePushError}
 */

- (void)onSDKError:(AlivcLivePusher *)pusher error:(AlivcLivePushError *)error;

@end


/**
 * 推流网络相关回调
 */

@protocol AlivcLivePusherNetworkDelegate <NSObject>

@required

/**
 * @brief 网络差回调
 * @param pusher 推流引擎对象
 * @note 此回调表示当前主播网络差
 */

- (void)onNetworkPoor:(AlivcLivePusher *)pusher;


/**
 * @brief 推流链接失败
 * @param pusher 推流引擎对象
 * @param error 错误信息，{@link AlivcLivePushError}
 */

- (void)onConnectFail:(AlivcLivePusher *)pusher error:(AlivcLivePushError *)error;


/**
 * @brief 网络恢复
 * @param pusher 推流引擎对象
 * @note 此回调表示当前主播网络恢复
 */

- (void)onConnectRecovery:(AlivcLivePusher *)pusher;


/**
 * @brief 重连开始回调
 * @param pusher 推流引擎对象
 * @note 此回调表示当前推流链接断开，正在开始重连
 */

- (void)onReconnectStart:(AlivcLivePusher *)pusher;


/**
 * @brief 重连成功回调
 * @param pusher 推流引擎对象
 * @note 此回调表示重连成功
 */

- (void)onReconnectSuccess:(AlivcLivePusher *)pusher;

/**
 * @brief 链接断开
 * @param pusher 推流引擎对象
 * @note 此回调表示推流链接断开
 */

- (void)onConnectionLost:(AlivcLivePusher *)pusher;


/**
 * @brief 重连失败回调
 * @param pusher 推流引擎对象
 * @param error 错误信息，{@link AlivcLivePushError}
 * @note 此回调表示重连失败
 */

- (void)onReconnectError:(AlivcLivePusher *)pusher error:(AlivcLivePushError *)error;


/**
 * @brief 发送数据超时
 * @param pusher 推流引擎对象
 * @note 此回调表示发送数据超时
 */

- (void)onSendDataTimeout:(AlivcLivePusher *)pusher;


/**
 * @brief 推流URL的鉴权时长即将过期(将在过期前1min内发送此回调)
 * @param pusher 推流引擎对象
 * @return 新的重新生成鉴权URL的推流URL
 * @note 此回调当前推流URL鉴权过期，需要给SDK传递一个新的URL
 */

- (NSString *)onPushURLAuthenticationOverdue:(AlivcLivePusher *)pusher;

/**
 * @brief 连麦推流URL的token即将过期(将在过期前30s内发送此回调)
 * @param pusher 推流引擎对象
 * @note 此回调只在互动模式下生效，该回调在鉴权信息30秒前触发，收到该回调后应该及时将新的token的URL传入SDK，参考 {@link refreshPushURLToken:}
 */

- (void)onPushURLTokenWillExpire:(AlivcLivePusher *)pusher;

/**
 * @brief 连麦推流URL的token已经过期
 * @param pusher 推流引擎对象
 * @note 此回调只在互动模式下生效，该回调触发代表鉴权信息已过期，需要调用结束推流后使用新的token的URL重新推流
 */

- (void)onPushURLTokenExpired:(AlivcLivePusher *)pusher;


/**
 * @brief 发送SEI Message 通知
 * @param pusher 推流引擎对象
 */

- (void)onSendSeiMessage:(AlivcLivePusher *)pusher;

/**
 * @brief 网络质量变化时发出的消息
 * @param pusher pusher 推流引擎对象
 * @param upQuality  上行网络质量
 * @param downQuality 下行网络质量
 * @note 当对端网络质量发生变化时触发, 此回调只在互动模式下生效
 */

- (void)onPusherNetworkQualityChanged:(AlivcLivePusher *)pusher upNetworkQuality:(AlivcLiveNetworkQuality)upQuality downNetworkQuality:(AlivcLiveNetworkQuality)downQuality;

@optional

/**
 * @brief 网络原因导致音视频丢包
 * @param pusher 推流引擎对象
 */

- (void)onPacketsLost:(AlivcLivePusher *)pusher;


@end



/**
 * 推流基本信息相关回调
 */

@protocol AlivcLivePusherInfoDelegate <NSObject>

@optional

/**
 * @brief 预览开始
 * @param pusher 推流引擎对象
 */

- (void)onPreviewStarted:(AlivcLivePusher *)pusher;



/**
 * @brief 停止预览回调
 * @param pusher 推流引擎对象
 */

- (void)onPreviewStoped:(AlivcLivePusher *)pusher;


/**
 * @brief 渲染第一帧回调
 * @param pusher 推流引擎对象
 */

- (void)onFirstFramePreviewed:(AlivcLivePusher *)pusher;


/**
 * @brief 发送第一帧音视频流回调
 * @param pusher 推流引擎对象
 */

- (void)onFirstFramePushed:(AlivcLivePusher *)pusher;

/**
 * @brief 推流开始回调
 * @param pusher 推流引擎对象
 */

- (void)onPushStarted:(AlivcLivePusher *)pusher;


/**
 * @brief 摄像头推流暂停回调
 * @param pusher 推流引擎对象
 */

- (void)onPushPaused:(AlivcLivePusher *)pusher;


/**
 * @brief 摄像头推流恢复回调
 * @param pusher 推流引擎对象
 */

- (void)onPushResumed:(AlivcLivePusher *)pusher;


/**
 * @brief 重新推流回调
 * @param pusher 推流引擎对象
 */

- (void)onPushRestart:(AlivcLivePusher *)pusher;


/**
 * @brief 推流停止回调
 * @param pusher 推流引擎对象
 */

- (void)onPushStoped:(AlivcLivePusher *)pusher;

/**
 * @brief 直播推流器统计数据回调（每2秒回调一次）
 *
 * @param pusher 推流引擎对象
 * @param statistics 推流器统计数据 {@link AlivcLivePushStatsInfo}
 */

- (void)onPushStatistics:(AlivcLivePusher *)pusher statsInfo:(AlivcLivePushStatsInfo*)statistics;

/**
 * @brief 设置云端的混流（转码）参数回调，对应于setLiveMixTranscodingConfig接口
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param isSuccess YES表示成功，NO表示失败
 * @param msg 具体错误原因
 */

- (void)onSetLiveMixTranscodingConfig:(AlivcLivePusher *)pusher status:(BOOL)isSuccess message:(NSString *)msg;


/**
 * @brief 被服务侧强制踢掉回调
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param code 具体被踢掉原因
 */

- (void)onKickedOutByServer:(AlivcLivePusher *)pusher reason:(AlivcLivePushKickedOutType)code;

/**
 * @brief 麦克风音量回调
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param volume 音量大小, 取值范围[0,255]
 * @note  调用 {@link enableAudioVolumeIndication} 打开音量回调频率后，会收到这个回调通知。
 */

- (void)onMicrophoneVolumeUpdate:(AlivcLivePusher *)pusher volume:(int)volume;

/**
 * @brief 有用户加入房间回调(只针对直播连麦场景生效)
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param userId 加入房间的用户ID
 * @param isOnline 加入房间状态：YES表示加入了房间，NO表示离开了房间
 * @note
 *  主播和观众连麦时，连麦观众开始推流后，在主播侧可以收到该回调，主播拿到回调后，可以向其
 *  业务server请求该userId的连麦拉流地址，使用AlivcLivePlayer的startPlayWithURL接口进行拉流
 */

- (void)onRemoteUserEnterRoom:(AlivcLivePusher *)pusher userId:(NSString *)userId state:(BOOL)isOnline;

/**
 * @brief 有用户在房间内开启共享流回调，可以是屏幕共享流或者unity流(只针对直播连麦场景生效)
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param userId 加入房间的用户ID
 * @param videoStreamType 视频类型，摄像头流或者屏幕共享流
 * @param isPushing 推流状态：YES表示开始推流，NO表示停止推流
 * @note
 * 主播拿到共享流回调后，可以创建AliLivePlayer对象，指定videoStreamType为AlivcLivePlayVideoStreamTypeScreen，
 * 使用该userId的连麦拉流地址，用AlivcLivePlayer的startPlayWithURL接口进行拉流
 */

- (void)onRemoteUserVideoStream:(AlivcLivePusher *)pusher userId:(NSString *)userId type:(AlivcLivePlayVideoStreamType)videoStreamType state:(BOOL)isPushing;

/**
 * @brief 本地媒体录制状态回调
 * 注：录制开始或者录制异常都是通过该回调回抛
 * @param pusher 推流引擎对象
 * @param event 本地录制状态和错误回调, 参见AlivcLiveRecordMediaEventCode
 * @param storagePath 录制文件存储路径
 */

/**
 * @brief Local media recording status callback
 * Note: The recording start or recording exception will be thrown through this callback.
 * @param pusher The live pusher engine object
 * @param event Local recording status and error callback, see AlivcLiveRecordMediaEventCode
 * @param storagePath Recording file storage path
 */
- (void)onMediaRecordEvent:(AlivcLivePusher *)pusher event:(AlivcLiveRecordMediaEventCode)event recoderStoragePath:(NSString *_Nullable)storagePath;

/**
 * @brief 发送共享流推送状态回调
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param isPushing 推流状态：YES表示开始推流，NO表示停止推流
 */

- (void)onScreenFramePushState:(AlivcLivePusher *)pusher state:(BOOL)isPushing;
@end

/**
 * 背景音乐相关回调
 */

@protocol AlivcLivePusherBGMDelegate <NSObject>

@required

/**
 * @brief 背景音乐开始播放
 * @param pusher 推流引擎对象
 */

- (void)onStarted:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐停止播放
 * @param pusher 推流引擎对象
 */

- (void)onStoped:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐暂停播放
 * @param pusher 推流引擎对象
 */

- (void)onPaused:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐恢复播放
 * @param pusher 推流引擎对象
 */

- (void)onResumed:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐当前播放进度
 * @param pusher 推流引擎对象
 * @param progress 播放时长
 * @param duration 总时长
 */

- (void)onProgress:(AlivcLivePusher *)pusher progress:(long)progress duration:(long)duration;


/**
 * @brief 背景音乐播放完毕
 * @param pusher 推流引擎对象
 */

- (void)onCompleted:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐开启失败
 * @param pusher 推流引擎对象
 */

- (void)onOpenFailed:(AlivcLivePusher *)pusher;


/**
 * @brief 背景音乐下载播放超时
 * @param pusher 推流引擎对象
 */

- (void)onDownloadTimeout:(AlivcLivePusher *)pusher;


@end

/**
 * 外置滤镜相关回调
 */

@protocol AlivcLivePusherCustomFilterDelegate <NSObject>
@required
/**
 * @brief 通知外置滤镜创建回调
 * @param pusher 推流引擎对象
 * @param context 上下文环境
 */

- (void)onCreate:(AlivcLivePusher *)pusher context:(void*)context;
/**
 * @brief 通知外置滤镜处理回调(纹理回调)
 * @param pusher 推流引擎对象
 * @param texture 纹理ID
 * @param width 图像宽
 * @param height 图像高
 * @param extra 额外信息
 * @return 返回处理后的纹理ID
 */

- (int)onProcess:(AlivcLivePusher *)pusher texture:(int)texture textureWidth:(int)width textureHeight:(int)height extra:(long)extra;
/**
 * @brief 通知外置滤镜处理回调，当前版本SDK在互动模式下需要使用onProcessVideoSampleBuffer处理美颜
 * @param pusher 推流引擎对象
 * @param sampleBuffer 视频sample data {@link AlivcLiveVideoDataSample}
 * @return
 * - YES: 需要写回SDK
 * - NO: 不需要写回SDK
 * @note 此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才回回调
 */

- (BOOL)onProcessVideoSampleBuffer:(AlivcLivePusher *)pusher sampleBuffer:(AlivcLiveVideoDataSample *)sampleBuffer;

/**
 * @brief 通知外置滤镜销毁回调
 * @param pusher 推流引擎对象
 */

- (void)onDestory:(AlivcLivePusher *)pusher;

@end

/**
 * 外置人脸识别算法相关回调
 */

@protocol AlivcLivePusherCustomDetectorDelegate <NSObject>

@required
/**
 * @brief 通知外置识别器创建回调
 * @param pusher 推流引擎对象
 */

- (void)onCreateDetector:(AlivcLivePusher *)pusher;

/**
 * @brief 通知外置识别器处理回调
 * @param pusher 推流引擎对象
 * @param data 数据buffer地址
 * @param w图像宽
 * @param h图像高
 * @param rotation 图像角度
 * @param format 图像格式，{@link AlivcLivePushVideoFormat}
 * @param extra 额外信息
 * @return 处理后的数据buffer地址
 */

- (long)onDetectorProcess:(AlivcLivePusher *)pusher data:(long)data w:(int)w h:(int)h rotation:(int)rotation format:(int)format extra:(long)extra;

/**
 * @brief 通知外置识别器销毁回调
 * @param pusher 推流引擎对象
 */

- (void)onDestoryDetector:(AlivcLivePusher *)pusher;

@end

/**
 * 截图相关回调
 */

@protocol AlivcLivePusherSnapshotDelegate <NSObject>

@required

/**
 * @brief 截图回调
 * @param pusher 推流引擎对象
 * @param image 截图
 */

- (void)onSnapshot:(AlivcLivePusher *)pusher image:(UIImage *)image;
@end

/**
 * 音频裸数据相关回调
 */

@protocol AlivcLivePusherAudioSampleDelegate <NSObject>
/**
 * @brief 设备采集的原始音频数据，支持修改
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 */

- (void)onAudioSampleCallback:(AlivcLivePusher *)pusher audioSample:(AlivcLivePusherAudioDataSample*)audioSample;

@end

/** @} */

