//
//  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 创建一个推流引擎实例
 * @param config 推流配置信息 {@link AlivcLivePushConfig}
 * @return self:success  nil:failure
 * @note 同一时间只会存在一个主推流引擎实例，引擎销毁对应的接口：{@link AlivcLivePusher::destory }
 */

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

/**
 * @brief 设置推流错误监听回调
 * @param delegate {@link AlivcLivePusherErrorDelegate}
 * @note 错误回调和相关处理可参考：https://help.aliyun.com/zh/live/developer-reference/handling-of-exceptions-and-special-scenarios-for-ios
 */

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


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

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

/**
 * @brief 设置推流网络监听回调
 * @param delegate {@link AlivcLivePusherNetworkDelegate}
 * @note 网络监听回调和相关处理可参考：
 * https://help.aliyun.com/zh/live/developer-reference/handling-of-exceptions-and-special-scenarios-for-ios
 */

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

/**
 * @brief 设置用户自定义滤镜回调
 * @param delegate {@link AlivcLivePusherCustomFilterDelegate}
 * @note 对接美颜SDK相关回调可参考：
 * https://help.aliyun.com/zh/live/developer-reference/handling-of-exceptions-and-special-scenarios-for-ios
 */

- (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;

/* *****************(互动模式下没有同步接口和异步接口区别，同步异步接口调用效果完全相同，只需要选择任意一种API即可)****************** */
/**
 * @brief 开始预览 同步接口
 * @param previewView 预览view
 * @return 0:success  非0:failure
 * @note 该接口对应的回调：{@link AlivcLivePusherInfoDelegate::onPreviewStarted:}
 * @note 预览成功对应的回调：{@link AlivcLivePusherInfoDelegate::onFirstFramePreviewed:}
 * @note 如果需要更新渲染View(例如刚开始在A view上渲染，需要更新到B view上渲染)，可以调用接口：{@link AlivcLivePusher::updateLocalView:}
 * @note 如果需要调整预览现实样式(例如裁剪、拉升)，可参考接口设置：{@link AlivcLivePushConfig::previewDisplayMode} 或 {@link AlivcLivePusher::setpreviewDisplayMode:}
 */

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

/**
 * @brief 更新本地摄像头的预览画面
 * @param view 预览view
 * @note 如果需要更新渲染View(例如刚开始在A view上渲染，需要更新到B view上渲染)，可以调用此接口
 * @note 注：该API暂时只支持在livePushMode = AlivcLivePushInteractiveMode 模式下生效，AlivcLivePushBasicMode模式下暂时不支持该API，调用无任何效果
 */

- (void)updateLocalView:(UIView *)view;


/**
 * @brief 停止预览
 * @return 0:success  非0:failure
 * @note 该接口对应的回调：{@link AlivcLivePusherInfoDelegate::onPreviewStoped:}
 */

- (int)stopPreview;


/**
 * @brief 开始推流 同步接口
 * @param pushURL 推流URL
 * @return 0:success  非0:failure
 * @note 该接口调用后可收到的回调:
 * 1. 推流链接建立成功：{@link AlivcLivePusherInfoDelegate::onPushStarted:}
 * 2.发送第一帧音视频流成功回调，可作为推流成功回调: {@link AlivcLivePusherInfoDelegate::onFirstFramePushed:}
 */

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


/**
 * @brief 停止推流
 * @return 0:success  非0:failure
 * @note 该接口调用后可收到的回调: {@link AlivcLivePusherInfoDelegate::onPushStoped:}
 */

- (int)stopPush;


/**
 * @brief 重新推流 同步接口
 * @return 0:success  非0:failure
 * @note 此接口SDK内部会停止预览再开启预览，预览画面会有黑一下的过程；如果不希望重新预览，仅是重新推流，可以先调用stopPush结束推流，再调用startPushWithURL开启推流
 */

- (int)restartPush;


/**
 * @brief 暂停摄像头推流，如果pushCongfig 中设置了pauseImg图片，将推设置的静态图片
 * @return 0:success  非0:failure
 * @note SDK不提供暂停推流的接口，这个接口的含义是暂停摄像头推流切换成推静态图片，只是视频画面发生了变化，声音还是推流
 */

- (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;



/* *****************异步接口(互动模式下没有同步接口和异步接口区别，同步异步接口调用效果完全相同，只需要选择任意一种API即可)****************** */
/**
 * @brief 开始预览 异步接口
 * @param preview 预览view
 * @return 0:success  非0:failure
 * @note 该接口对应的回调：{@link AlivcLivePusherInfoDelegate::onPreviewStarted:}
 * @note 预览成功对应的回调：{@link AlivcLivePusherInfoDelegate::onFirstFramePreviewed:}
 * @note 如果需要更新渲染View(例如刚开始在A view上渲染，需要更新到B view上渲染)，可以调用接口：{@link AlivcLivePusher::updateLocalView:}
 * @note 如果需要调整预览现实样式(例如裁剪、拉升)，可参考接口设置：{@link AlivcLivePushConfig::previewDisplayMode} 或 {@link AlivcLivePusher::setpreviewDisplayMode:}
 */

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


/**
 * @brief 开始推流 异步接口
 * @param pushURL 推流URL
 * @return 0:success  非0:failure
 * @note 该接口调用后可收到的回调:
 * 1. 推流链接建立成功：{@link AlivcLivePusherInfoDelegate::onPushStarted:}
 * 2.发送第一帧音视频流成功回调，可作为推流成功回调: {@link AlivcLivePusherInfoDelegate::onFirstFramePushed:}
 */

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


/**
 * @brief 重新推流 异步接口
 * @return 0:success  非0:failure
 * @note 此接口SDK内部会停止预览再开启预览，预览画面会有黑一下的过程；如果不希望重新预览，仅是重新推流，可以先调用stopPush结束推流，再调用startPushWithURLAsync开启推流
 */

- (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
 * @note SDK内部默认是自动对焦的
 */

- (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:关闭推流镜像
 * @note SDK默认推流不镜像
 */

- (void)setPushMirror:(bool)mirror;


/**
 * @brief 预览镜像开关
 * @param mirror true:打开预览镜像 false:关闭预览镜像
 * @note SDK默认前置摄像头预览镜像，后置摄像头预览不镜像
 */

- (void)setPreviewMirror:(bool)mirror;


/**
 * @brief 静音推流
 * @param mute true:静音推流 false:正常推流
 * @note 调用此接口，控制音频流是否静音；即使在静音时，仍然占用系统麦克风权限，发送静音音频数据
 * @note 如果希望不再占用系统麦克风权限，即：关闭音频采集，可调用接口：{@link AlivcLivePusher::stopAudioCapture }
 */

- (void)setMute:(bool)mute;

/**
 * @brief 停止/恢复本地音频数据发送
 * @param mute  YES表示静音本地音频，发送静音帧; NO表示取消静音;
 * @param mode  静音模式，静音模式分三种，详见 {@link AliLiveMuteLocalAudioMode}
 * @return
 * - 0: 成功
 * - 非0: 失败
 * @note 静音是指音频流发送静音帧,采集和编码模块仍然在工作，仍然占用系统麦克风权限
 * @note 如果希望不再占用系统麦克风权限，即：关闭音频采集，可调用接口：{@link AlivcLivePusher::stopAudioCapture }
 */

- (void)setMute:(BOOL)mute mode:(AliLiveMuteLocalAudioMode)mode;


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

- (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 推流分辨率
 * @note 此接口可以动态调整推流分辨率，例如在多人PK场景，根据PK人数的不同需要动态调整推流分辨率，可以使用该接口
 */

- (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 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模式下请使用sendVideoData接口向SDK输入自定义视频数据
 */

- (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，请使用sendPCMData接口向SDK输入自定义音频数据
 */

- (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 原始视频数据格式
 * @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 音频格式  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模式下暂时不支持设置，互动模式下传入false
 * @return 0:success  非0:failure
 * @note 该接口sei 的payloadType为5
 */

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

/**
 * @brief 设置自定义Message (SEI)
 * @param msg 用户推流消息
 * @param count 重复次数
 * @param time 延时时间，单位毫秒
 * @param isKeyFrame 是否只发关键帧，该参数只支持在livePushMode = AlivcLivePushBasicMode 模式下设置，AlivcLivePushInteractiveMode模式下暂时不支持设置, ，互动模式下传入false
 * @param payloadType 类型，可设置的值为5或者[100..254]范围区间，如果设置5，则在内容前面会有一个16字节的UUID
 * @return 0:success  非0:failure
 * @note 注：当前SDK暂时只支持在livePushMode = AlivcLivePushInteractiveMode 模式下生效，AlivcLivePushBasicMode模式下暂时不支持设置payloadType
 */

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

/**
 * @brief 开启SEI视频流，内部将使用16x16全黑图片流/20fps
 * @note 在互动模式下，如果把摄像头采集关闭(调用enableLocalCamera接口)，纯音频场景，默认不会发送视频，
 * 但是如果后续调用了sendMessage接口发送SEI信息，SDK内部默认会发送16x16全黑图片流/20fps的视频流来承载SEI信息，
 * 可以通过调用enableSEIVideoStream来关闭SDK默认的推送16x16全黑图片逻辑，关闭后纯音频场景将发送不了SEI信息
 * @param enable true=开启 false=关闭
 * @return
 * - 0: 成功
 * - 非0: 失败
 */
-(int)enableSEIVideoStream:(bool)enable;

/**
 * @brief 获取是否正在推流
 * @return YES:正在推流 NO:未推流
 * @note 可以用该方法判断是否在推流
 */

- (BOOL)isPushing;


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

- (NSString *)getPushURL;

/**
 * @brief 获取当前推流状态
 * @return 推流状态 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
//setWatermark
//startRecording
//stopRecording
//startScreenShare
//stopScreenShare
//setAudioProfile
//updateLocalView
//stopAudioCapture
//startAudioCapture
//getParameter
//getCurrentEncoderManufacturer
//startBGMWithMusicPathAsync:config

// 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
//setWatermark
//startRecording
//stopRecording
//startScreenShare
//stopScreenShare
//setAudioProfile
//updateLocalView
//stopAudioCapture
//startAudioCapture
//getParameter
//getCurrentEncoderManufacturer
//startBGMWithMusicPathAsync:config

/**
 * @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 enabled
 * - YES : 启用本地视频采集
 * - NO : 禁用本地视频采集
 * @return
 * - 0 : 成功
 * - < 0 : 失败
 * @note 摄像头采集会被关闭掉
 */

- (int)enableLocalCamera:(BOOL)enabled;

/**
 * @brief 关闭/打开视频（非互动模式暂不支持该API，调用无任何效果）
 * @param mute  YES表示不发送视频数据；NO表示恢复正常
 * @return
 * - 0: 表示Success
 * - 非0: 表示Failure
 * @note 发送黑色的视频帧。采集，编码，发送模块仍然工作，只是视频内容是黑色帧
 */

- (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信息，主要为了防止鉴权过期，导致推流失败，当我们收到  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 如果  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 AlivcLivePusherInfoDelegate::onMicrophoneVolumeUpdate:volume: }回调
 * @note 可以通过调用该接口及相关回调，可以实现声音波纹效果
 */
- (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 启动屏幕分享
 * @note 直播连麦场景开启第二路视频推送，可以通过setExternalVideoSource设置外部视频源，通过pushExternalVideoFrame向第二路视频通道输入视频数据
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)startScreenShare;

/**
 * @brief 停止屏幕分享
 * @note 停止第二路视频推送
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)stopScreenShare;

/**
 * @brief 开启第二路音频流推送
 * @note 开启后第二路音频流推送后，可以调用addExternalAudioStream添加音频数据源，使用pushExternalAudioStream向第二路音频通道输入音频数据基础
 * @note 直播连麦场景使用，基础直播不可用
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)startLocalDualAudioStream;

/**
 * @brief 停止第二路音频流推送
 * @note 直播连麦场景使用，基础直播不可用
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)stopLocalDualAudioStream;

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

- (int)setAudioProfile:(AlivcLiveAudioProfile)audio_profile;







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

- (AlivcLivePushVideoEncoderModeHardCodec)getVideoCodecType;


/**
 * @brief 关闭音频采集
 * @note 调用此接口后，采集设备关闭
 * @note 调用此接口，关闭音频采集，不再占用系统麦克风权限，且不再发送音频数据
 * @note 如果调用此接口后系统仍显示有麦克风权限的占用，请检查是否由其它功能引起
 * @note 开启音频采集，对应接口：{@link AlivcLivePusher::startAudioCapture:}
 * @note 如果只需要静音，不关闭音频采集，请参考以下接口：{@link AlivcLivePusher::setMute: }
 */

- (void)stopAudioCapture;

/**
 * @brief 开启音频采集
 * @param keepAlive YES: 停止推流后麦克风采集设备保持开启状态；NO: 停止推流后麦克风采集设备关闭
 * @note 调用此接口，开始采集音频数据并发送，将会占用系统麦克风权限
 * @note 关闭音频采集，对应接口：{@link AlivcLivePusher::stopAudioCapture }
 * @note 如果只需要静音，不关闭音频采集，请参考以下接口：{@link AlivcLivePusher::setMute: }
 */

- (void)startAudioCapture:(BOOL)keepAlive;

/**
 * @brief 开启音频播放
 * @note 此接口可以控制提前打开音频播放，如果不设置，则SDK会在订阅到音频流后自动打开音频播放
 */

- (void)startAudioPlayer;

/**
 * @brief 关闭音频播放
 * @note 此接口可以控制关闭音频播放，与 {@link startAudioPlayer} 对应
 */

- (void)stopAudioPlayer;

/**
 * @brief 设置频道模式
 * @details 根据业务需求可以配置不同的频道模式，AliRTC会根据不用的频道模式模式采用不用的策略，目前主要提供通信模式(默认)、互动模式、低延迟互动直播模式
 *
 * @param profile 频道模式类型, 详细请参考  AlivcLiveChannelProfile
 * @return
 * - 0: 成功
 * - 非0: 失败
 *
 * @note
 *  - 该方法只在startPushWithURLAsync前调用有效，推流中不可以重新设置，stopPush 后可以重新设置
 */
- (int)setChannelProfile:(AlivcLiveChannelProfile)profile;

/**
 * @brief 通过数据通道发送自定义消息
 *
 * @param message 自定义消息
 * @return
 * - 0: 成功
 * - 非0: 失败
 */
- (int)sendDataChannelMessage:(NSString *)message;


/**
 * @brief 获取自定义参数
 * @param param   自定义参数
 * @return 自定义参数值
 */
- (NSString *)getParameter:(NSString *)param;

/**
* @brief 获取当前使用的编码器类型,如未开始推流，返回无效类型
* @param isCameraStreem YES: 获取摄像头流的编码器类型;  NO: 获取共享流的编码器类型
* @return AlivcLiveVideoCodecManufacturer 编码器类型
*/
- (AlivcLiveVideoCodecManufacturer)getCurrentEncoderManufacturer:(BOOL)isCameraStreem;

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

- (int)startBGMWithMusicPathAsync:(NSString *)path config:(AlivcLiveBGMConfig *_Nonnull)config;

/**
 * @brief 获取伴奏文件时长, 单位为毫秒
 * @return
 * - >=0: 伴奏文件时长
 * - <0: 返回错误码
 */

- (int)getBGMDuration;

/**
 * @brief 获取伴奏文件播放进度，单位为毫秒
 * @return
 * - >=0: 伴奏文件播放进度
 * - <0: 返回错误码
 */

- (int)getBGMCurrentPosition;

/**
 * @brief 启用外部视频输入源
 * @param enable
 * - YES 开启
 * - NO 关闭
 * @param type 流类型，详见 AliLiveVideoSource
 * - AliLiveVideoSourceCameraType 外部输入视频数据走相机流通道，如果当前相机采集打开中，调用该接口设置enable为YES，sdk会替换掉相机采集
 * - AliLiveVideoSourceScreenShareType 外部输入视频数据走屏幕流通道，如果当前屏幕共享采集打开中，调用该接口设置enable为YES，sdk会替换掉屏幕共享采集
 * @param renderMode 处理模式，外部输入视频源宽高比和推流profile不一致时，会按照对应的rendermode做对应处理，详见AliLiveRenderMode
 * - AliLiveRenderModeAuto 自动（默认） 如果外部输入的视频宽高比和推流设置的宽高比不一致时，维持外部输入的视频宽高比，等比例缩放宽高到推流设置的宽高范围内，注意此模式下为了保证原始视频的比例和内容完整性，会导致实际推流的分辨率和设置的不一致
 * - AliLiveRenderModeStretch 拉伸平铺，如果外部输入的视频宽高比和推流设置的宽高比不一致时，将输入视频拉伸到推流设置的比例，画面会变形
 * - AliLiveRenderModeFill 填充黑边，如果外部输入的视频宽高比和推流设置的宽高比不一致时，将输入视频上下或者左右填充黑边
 * - AliLiveRenderModeCrop 裁剪，如果外部输入的视频宽高比和推流设置的宽高比不一致时，将输入视频宽或者高进行裁剪，画面内容会丢失
 * @return
 * - 0: 成功
 * - 非0: 失败
 * @note 通过pushExternalVideoFrame接口向SDK 输入自定义数据
*/

- (int)setExternalVideoSource:(BOOL)enable sourceType:(AliLiveVideoSource)type renderMode:(AliLiveRenderMode)renderMode;

/**
 * @brief 输入视频数据
 * @param frame 帧数据，详见 AlivcLiveVideoDataSample
 * @param type 流类型，详见 AliLiveVideoSource
 * - AliLiveVideosourceCameraType 外部输入视频数据走相机流通道
 * - AliLiveVideosourceScreenShareType 外部输入视频数据走屏幕流通道
 *  @return
 * - 0: 成功
 * - 非0: 失败
 * @note 如果返回值为0x01070102，代表当前buffer队列塞满，需要等待后再继续输送数据
*/

- (int)pushExternalVideoFrame:(AlivcLiveVideoDataSample *_Nonnull)frame sourceType:(AliLiveVideoSource)type;

/**
 * @brief 设置是否启用外部音频输入源
 * @param enable YES:开启; NO:关闭
 * @param sampleRate 采样率 16k, 48k...
 * @param channelsPerFrame 声道数 1:单声道; 2:双声道
 * @return
 * - >=0: 成功
 * - <0: 失败
 */

- (int)setExternalAudioSource:(BOOL)enable withSampleRate:(NSUInteger)sampleRate channelsPerFrame:(NSUInteger)channelsPerFrame;

/**
 * @brief 新增外部音频流
 * @param config 外部音频流配置
 * @return
 * - <=0: 表示失败;
 * - >0: 表示成功;
 * - 返回值为 外部音频流Id
 * @note 通过pushExternalAudioStream接口向SDK 输入自定义数据
 */

- (int)addExternalAudioStream:(AliLiveExternalAudioStreamConfig *_Nonnull)config;

/**
 * @brief 输入外部音频流数据
 * @param streamId 外部音频流Id（addExternalAudioStream的返回值）
 * @param audioFrame 音频数据
 * @return
 * - <0: 表示失败;
 * - 0: 表示成功;
 * - 返回值为0x01070101 时，需要在间隔投递数据时间长度后再次重试投递
 * @note 为了保证语音连续性，sdk内部会有buffer缓存送进来的音频数据，以每次送10ms数据为例，如果返回 0x01070101 时，说明内部缓冲区已满，建议等待20ms后再重新送当前数据帧；
 */

- (int)pushExternalAudioStream:(int)streamId
                       rawData:(AlivcLivePusherAudioDataSample * _Nonnull)audioFrame;

/**
 * @brief 设置是否与麦克风采集音频混合
 * @param mixed YES：混音；NO：完全替换麦克风采集数据
 * @return
 * - 0: 成功
 * - 非0: 失败
 */

- (int)setMixedWithMic:(BOOL)mixed;

/**
 * @brief 设置外部音频流播放音量
 * @param streamId 外部音频流Id
 * @param playoutVolume 播放音量，取值范围[0, 100]
 * @return
 * - <0: 表示失败;
 * - 0: 表示成功;
 */

- (int)setExternalAudioStream:(int)streamId
                playoutVolume:(int)playoutVolume;

/**
 * @brief 设置外部音频流推流音量
 * @param streamId 外部音频流Id
 * @param publishVolume 推流音量，取值范围[0, 100]
 * @return
 * - <0: 表示失败;
 * - 0: 表示成功;
 */

- (int)setExternalAudioStream:(int)streamId
                publishVolume:(int)publishVolume;

/**
 * @brief 删除外部音频流
 * @param streamId 外部音频流Id
 * @return
 * - <0: 表示失败;
 * - 0: 表示成功;
 */

- (int)removeExternalAudioStream:(int)streamId;

/**
 * @brief 设置视频自定义分辨率(直播连麦场景可用，基础直播不可用)
 * @param videoSize 视频宽高
 * @return
 * - <0: 表示失败;
 * - 0: 表示成功;
 */
- (int)setCustomVideoResolution:(CGSize)videoSize;

/**
 * @brief 设置音频回调参数
 * @param enable 是否允许数据回调
 * @param audioSource 回调数据源类型，详见 AliLiveAudioSource
 * @param config 回调参数设置，详见AliLiveAudioFrameObserverConfig, null时默认参数为48000，1，ReadOnly
 * @details
 *  - AliLiveAudioSourcePub、AliLiveAudioSourceMixedAll只支持ReadOnly模式
 *  - AliLiveAudioSourceRemoteUser不支持修改采样率、通道数
 * @return 0: sucess
 *
 */
- (int)enableAudioFrameObserver:(bool)enable audioSource: (AliLiveAudioSource)audioSource config:(AliLiveAudioFrameObserverConfig*_Nullable)config;


/**
 * @brief 设置相机流视频编码属性
 * @details 该方法用于设置相机流视频编码属性对应的视频参数，如分辨率、帧率、码率等
 * 所有设置的参数都有相应的范围限制，如果设置的参数不在有效范围内，SDK会自动调节
 * @param config 预定义的编码属性，详见 {@link AliLiveVideoEncoderConfiguration}
*/

- (void)setVideoEncoderConfiguration:(AliLiveVideoEncoderConfiguration* _Nonnull)config;

/**
 * @brief 设置自定义参数
 * @param param   自定义参数
 * @return
 * - 0: 成功
 * - 非0: 失败
 */

- (int)setParameter:(NSString * _Nonnull)param;


/**
 * @brief 订阅视频数据
*/
- (void)registerVideoSampleObserver;

/**
 * @brief 取消订阅视频数据，调用后onProcessVideoSampleBuffer不回回调
*/
- (void)unregisterVideoSampleObserver;

/**
 * @brief 设置预览和推流镜像能力
 * @param mirrorMode 设置镜像的模式
 * @return
 * - 0: 设置成功
 * - <0: 设置失败
 *
 * @note
 * - 此接口在入会前和入会后均可以动态设置，SDK内部会记录状态，并在可以操作预览及编码的时候对视频进行操作；
 * - 此接口与setPreviewMirror & setPushMirror里面的mirror重合，使用时只要使用其中一个即可
 */

- (int)setVideoMirrorMode:(AliLiveVideoPipelineMirrorMode)mirrorMode;

#pragma mark - "音乐伴奏音效"
/**
 * @brief 设置变调参数
 * @param value 变调参数，范围：[0.5, 2.0]，1.0表示音调不变，小于1.0表示音调降低，大于1.0表示音调升高，默认1.0
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)setAudioEffectPitchValue:(double)value;

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

- (int)setAudioEffectVoiceChangeMode:(AlivcLivePushAudioEffectVoiceChangeMode)mode;

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

- (int)setAudioEffectReverbMode:(AlivcLivePushAudioEffectReverbMode)mode;

/**
 * @brief 设置美声音效模式
 * @param mode 参考 AliLiveAudioEffectBeautifyMode 对应的美声模式
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)setAudioEffectBeautifyMode:(AliLiveAudioEffectBeautifyMode)mode;

/**
 * @brief 设置混响音效类型
 * @param type 参考AliLiveAudioEffectReverbParamType 对应的混响类型
 * @param value 混响参数值，不同混响类型的取值范围参考 AliLiveAudioEffectReverbParamType中取值说明
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 需要在 setAudioEffectReverbMode之后调用
 */

- (int)setAudioEffectReverbParamType:(AliLiveAudioEffectReverbParamType)type value:(float)value;

/**
 * @brief 设置均衡器参数
 * @param bandIndex 均衡器段数[0,9]  center frequency [31,62,125,250,500,1000,2000,4000,8000,16000] Hz AliLiveAudioEffectEqualizationBandFrequency
 * @param gain 均衡器增益db   [-15,15]  default 0
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 需要在 setAudioEffectBeautifyMode 之后调用
 */
- (int)setAudioEffectEqualizationParam:(AliLiveAudioEffectEqualizationBandFrequency)bandIndex gain:(float)gain;


/**
 * @brief 预加载音效文件
 * @param soundId 用户给该音效文件分配的ID
 * @param filePath 音效文件路径，支持本地文件和网络url
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 音效相关接口为同步接口, 建议使用本地文件
 */

- (int)preloadAudioEffectWithSoundId:(NSInteger)soundId filePath:(NSString *_Nonnull)filePath;

/**
 * @brief 删除预加载的音效文件
 * @param soundId 用户给该音效文件分配的ID
 * @return
 * - 0：成功
 * - !=0：失败
 * @note 音效soundId应与预加载 {@link preloadAudioEffectWithSoundId:filePath:} 时传入的ID相同
 */

- (int)unloadAudioEffectWithSoundId:(NSInteger)soundId;

/**
 * @brief 开始播放音效
 * @details 开始播放音效接口，可以多次调用该方法传入不同的soundId和filePath，同时播放多个音效文件，音效文件播放结束后，SDK 会触发 {@link onAudioEffectFinished:} 回调
 * @param soundId 用户给该音效文件分配的ID，每个音效均有唯一的ID，如果你已通过 {@link preloadAudioEffectWithSoundId:filePath:} 将音效加载至内存，确保这里的soundId与 {@link preloadAudioEffectWithSoundId:filePath:} 设置的soundId相同
 * @param filePath 文件路径，支持本地文件和网络url
 * @param config 音效播放配置，详见{@link AliLiveAudioEffectConfig}
 * @return
 * - 0：成功
 * - 非0：失败
 */


- (int)playAudioEffectWithSoundId:(NSInteger)soundId filePath:(NSString *_Nonnull)filePath config:(AliLiveAudioEffectConfig *_Nonnull)config;


/**
 * @brief 停止播放音效
 * @param soundId 用户给该音效文件分配的ID，每个音效均有唯一的ID，如果你已通过 {@link preloadAudioEffectWithSoundId:filePath:} 将音效加载至内存，确保这里的soundId与 {@link preloadAudioEffectWithSoundId:filePath:} 设置的soundId相同
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)stopAudioEffectWithSoundId:(NSInteger)soundId;

/**
 * @brief 停止播放所有音效
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)stopAllAudioEffects;

/**
 * @brief 设置音效推流混音音量
 * @param soundId 用户给该音效文件分配的ID
 * @param volume 推流混音音量，范围是：[0, 100]，默认值：50
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 该方法需要在 {@link playAudioEffectWithSoundId:filePath:config:} 后调用
 */

- (int)setAudioEffectPublishVolumeWithSoundId:(NSInteger)soundId volume:(NSInteger)volume;

/**
 * @brief 获取音效推流混音音量
 * @param soundId 用户给该音效文件分配的ID
 * @return
 * - [0, 100]：音效推流混音音量
 * - 其他：错误值
 * @note 音效推流混音音量有效范围为：[0, 100]，该方法需要在  {@link playAudioEffectWithSoundId:filePath:config:} 后调用
 */

- (int)getAudioEffectPublishVolumeWithSoundId:(NSInteger)soundId;

/**
 * @brief 设置音效本地播放音量
 * @param soundId 用户给该音效文件分配的ID
 * @param volume 音效本地播放音量，范围：[0, 100]，默认值：50
 * @return
 * - 0：成功
 * - 非0：失败
 * @note 该方法需要在 {@link playAudioEffectWithSoundId:filePath:cycles:publish:} 后调用
 */

- (int)setAudioEffectPlayoutVolumeWithSoundId:(NSInteger)soundId volume:(NSInteger)volume;

/**
 * @brief 获取音效本地播放音量
 * @param soundId 用户给该音效文件分配的ID
 * @return
 * - [0, 100]：音效本地播放音量
 * - 其他：错误值
 * @note 音效本地播放音量有效范围为：[0, 100]，该方法需要在 {@link playAudioEffectWithSoundId:filePath:cycles:publish:} 后调用
 */

- (int)getAudioEffectPlayoutVolumeWithSoundId:(NSInteger)soundId;

/**
 * @brief 设置所有音效本地播音量
 * @param volume 音效本地播放音量，范围：[0, 100]，默认值：50
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)setAllAudioEffectsPlayoutVolume:(NSInteger)volume;

/**
 * @brief 设置所有音效推流混音音量
 * @param volume 推流混音音量，范围是：[0, 100]，默认值：50
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)setAllAudioEffectsPublishVolume:(NSInteger)volume;

/**
 * @brief 暂停音效
 * @param soundId 用户给该音效文件分配的ID
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)pauseAudioEffectWithSoundId:(NSInteger)soundId;

/**
 * @brief 暂停所有音效
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)pauseAllAudioEffects;

/**
 * @brief 恢复指定音效文件
 * @param soundId 用户给该音效文件分配的ID
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)resumeAudioEffectWithSoundId:(NSInteger)soundId;

/**
 * @brief 恢复所有音效文件
 * @return
 * - 0：成功
 * - 非0：失败
 */

- (int)resumeAllAudioEffects;

#pragma mark - "网络测试"

/**
 * @brief 开始网络质量探测
 * @param config 网络探测配置，AliLiveNetworkQualityProbeConfig
 * @details 网络质量探测需要在未推流 startPush之前调用，探测结果，开始推流后不能调用startLastmileDetect
 * @note 在3s左右，粗略的结果会在  {@link AlivcLivePusherNetworkDelegate::onLastmileDetectResultWithQuality:networkQuality:} 中回调
 * @note 在30s左右，更多的结果会在 {@link AlivcLivePusherNetworkDelegate::onLastmileDetectResultWithBandWidth:code:result:} 中回调
 * @return
 * - 0: 成功
 * - <0: 失败
 */

- (int)startLastmileDetect:(AliLiveNetworkQualityProbeConfig *_Nonnull)config;

/**
 * @brief 停止网络质量探测
 * @return
 * - 0: 成功
 * - <0: 失败
 */

- (int)stopLastmileDetect;


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//      美颜相关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
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//        从v6.10.0版本开始，Debug悬浮窗相关接口废弃，此块功能已移植到最新的源码demo中，请下载最新的源码demo查看
//        详见：https://help.aliyun.com/zh/live/developer-reference/sdk-download-and-release-notes
//
//        Starting from version v6.10.0, the interface related to the Debug floating window is abandoned. This
//        function has been transplanted to the latest source code demo. Please download the latest source code
//        demo to view. See:https://help.aliyun.com/zh/live/developer-reference/sdk-download-and-release-notes
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * @brief 显示调试悬浮窗(已废弃)
 * @note 已废弃使用
 * @deprecated
 */

+ (void)showDebugView;



/**
 * @brief 隐藏调试悬浮窗(已废弃)
 * @note 已废弃使用
 * @deprecated
 */

+ (void)hideDebugView;

@end

/** @} */


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


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

@protocol AlivcLivePusherErrorDelegate <NSObject>

@required

/**
 * @brief 系统设备异常回调
 * @param pusher 推流引擎对象
 * @param error 错误信息，参考 AlivcPusherErrorCode
 * @note 系统设备异常回调，需要销毁引擎重新尝试(stopPush & destory)。
 */

- (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，参考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;

/**
 * @brief 网络连接状态改变的回调
 * @param pusher pusher 推流引擎对象
 * @param status 当前状态值, 对应值参考枚举 AliLiveConnectionStatus
 * @param reason 引起状态变化的具体原因, 对应值参考枚举AliLiveConnectionStatusChangeReason
 * @note 此回调只在互动模式下生效
 */

- (void)onConnectionStatusChange:(AlivcLivePusher *)pusher
                connectionStatus:(AliLiveConnectionStatus)status reason:(AliLiveConnectionStatusChangeReason)reason;

/**
 * @brief 网络质量探测回调
 * @param pusher pusher 推流引擎对象
 * @param networkQuality 网络质量 AlivcLiveNetworkQuality
 * @note 在开始推流前调用 startLastmileDetect 后会触发该回调,  此回调只在互动模式下生效
 */

- (void)onLastmileDetectResultWithQuality:(AlivcLivePusher *)pusher networkQuality:(AlivcLiveNetworkQuality)networkQuality;

/**
 * @brief 网络质量探测结果的回调
 * @param pusher pusher 推流引擎对象
 * @param code 探测结果，0: 成功，-1: DNS获取失败，-2: ICMP模块初始化失败,  -3: ICMP 发送长时间失败, -4: ICMP 无法接收(建议允许开播)
 * @param result 网络质量 AliLiveNetworkQualityProbeResult
 * @note 当调用 startLastmileDetect后会触发该回调, 此回调只在互动模式下生效
 * @details code 错误码处理建议：
 * 1. 如果是直接回抛了-1、-2、-3错误码，可以阻止开播；
 * 2. 由于有些特定网络可能设置阻止网络探测，会返回-4错误码，为了避免探测误伤导致主播无法开播，因此返回-4错误码也建议允许开播推流
 */

- (void)onLastmileDetectResultWithBandWidth:(AlivcLivePusher *)pusher code:(int)code result:(AliLiveNetworkQualityProbeResult* _Nonnull)result;

@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  调用 enableAudioVolumeIndication 打开音量回调频率后，会收到这个回调通知。
 */

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


/**
 * @brief 加入频道回调
 * @details 互动模式下调用startPushWithURL时，会先加入RTC频道，该回调表示成功/失败加入频道，并且返回频道加入的相关信息
 * @param pusher 推流引擎对象
 * @param result 加入频道结果
 * - 0：成功
 * - 非0：失败
 * @param channel 加入频道名
 * @param userId   用户ID
 */

- (void)onJoinChannelResult:(AlivcLivePusher *)pusher result:(int)result channel:(NSString *_Nonnull)channel userId:(NSString *_Nonnull)userId;

/**
 * @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 有用户在房间内成员推送音频流回调(只针对直播连麦场景生效)
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param userId 加入房间的用户ID
 * @param isPushing 推流状态：YES表示开始推流，NO表示停止推流
 * @note
 */

- (void)onRemoteUserAudioStream:(AlivcLivePusher *)pusher userId:(NSString *)userId  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 oldState 之前的推流状态，详见  AliLivePublishState
 * @param newState 当前的推流状态，详见 AliLivePublishState
 */

- (void)onAudioPublishStateChanged:(AlivcLivePusher *)pusher oldState:(AliLivePublishState)oldState newState:(AliLivePublishState)newState;

/**
 * @brief 视频推流变更回调
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param oldState 之前的推流状态，详见  AliLivePublishState
 * @param newState 当前的推流状态，详见 AliLivePublishState
 */

- (void)onVideoPublishStateChanged:(AlivcLivePusher *)pusher oldState:(AliLivePublishState)oldState newState:(AliLivePublishState)newState;

/**
 * @brief 屏幕分享推流变更回调
 * 注：此回调只在livePushMode为AlivcLivePushInteractiveMode，即只在直播SDK工作在互动模式下才可以使用
 * @param pusher 推流引擎对象
 * @param oldState 之前的推流状态，详见  AliLivePublishState
 * @param newState 当前的推流状态，详见 AliLivePublishState
 */

- (void)onScreenSharePublishStateChanged:(AlivcLivePusher *)pusher oldState:(AliLivePublishState)oldState newState:(AliLivePublishState)newState;

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

- (void)onLocalDualAudioStreamPushState:(AlivcLivePusher *)pusher state:(BOOL)isPushing;

/**
 * @brief 本地音频采集设备状态回调
 * @param pusher 推流引擎对象
 * @param state  设备状态，AliLiveLocalAudioStateType类型
 * @note startAudioCapture 和 stopAudioCapture的结果回调
 */

- (void)onLocalAudioStateChanged:(AlivcLivePusher *)pusher state:(AliLiveLocalAudioStateType)state message:(NSString *_Nullable)msg;

/**
 * @brief 本地视频采集设备状态回调
 * @param pusher 推流引擎对象
 * @param state  设备状态，AliLiveLocalVideoStateType类型
 * @note enableLocalCamera的结果回调
 */

- (void)onLocalVideoStateChanged:(AlivcLivePusher *)pusher state:(AliLiveLocalVideoStateType)state message:(NSString *_Nullable)msg;
@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;


/**
 * @brief 本地音效播放结束回调
 * @param soundId 用户给该音效文件分配的唯一ID
 */

- (void)onAudioEffectFinished:(int)soundId;
@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
 * @note 互动模式下默认是回抛CVPixelBuffer用于美颜，如果想要回调纹理ID，需要设置enableLocalVideoTexture，设置后，互动模式会回抛纹理ID
 */

- (int)onProcess:(AlivcLivePusher *)pusher texture:(int)texture textureWidth:(int)width textureHeight:(int)height extra:(long)extra;
/**
 * @brief 通知外置滤镜处理回调，当前版本SDK在互动模式下默认回抛CVPixelBuffer，需要使用onProcessVideoSampleBuffer处理美颜，如果想要回抛纹理ID，需要设置enableLocalVideoTexture
 * @param pusher 推流引擎对象
 * @param sampleBuffer 视频sample data {@link AlivcLiveVideoDataSample}
 * @note 美颜SDK有两种处理方式：1.在SDK抛出的sampleBuffer.pixelBuffer上直接处理数据，不生成新的pixbuffer; 2.生成新的newPixelBuffer，在新的newPixelBuffer上处理美颜，这种情况需要将新生成的newPixelBuffer写会SDK，可以参考如下示例代码：
 *  - (BOOL)onProcessVideoSampleBuffer:(AlivcLivePusher *)pusher sampleBuffer:(AlivcLiveVideoDataSample *)sampleBuffer{
 *       CVPixelBufferRef newPixelBuffer = thirdparty_process(sampleBuffer.pixelBuffer);
        sampleBuffer.pixelBuffer = newPixelBuffer;
        return YES;
 *  }
 * @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 图像格式
 * @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 设备采集的原始音频数据，支持修改，采集裸数据回调
 * @details 默认关闭，需要通过enableAudioFrameObserver : YES audioSource: AliLiveAudioSourceCaptured 开启
 *
 *  - 该接口支持设置采样率、声道数
 *  - 该接口支持读写模式
 *
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 * @note 请不要在此回调函数中做任何耗时操作，否则可能导致声音异常
 */

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

/**
 * @brief 3A后数据回调
 * @details 默认关闭，需要通过enableAudioFrameObserver : YES audioSource: AliLiveAudioSourceProcessCaptured 开启
 *
 *  - 该接口支持设置采样率、声道数
 *  - 该接口支持读写模式
 *
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 * @note 请不要在此回调函数中做任何耗时操作，否则可能导致声音异常
 */

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

/**
 * @brief 推流数据回调
 * @details 默认关闭，需要通过enableAudioFrameObserver : YES audioSource: AliLiveAudioSourcePub 开启
 *
 *  - 该接口支持设置采样率、声道数
 *  - 该接口只支持只读模式
 *
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 * @note 请不要在此回调函数中做任何耗时操作，否则可能导致声音异常
 */

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

/**
 * @brief 播放数据回调
 * @details 默认关闭，需要通过enableAudioFrameObserver : YES audioSource: AliLiveAudioSourcePlayback 开启
 *
 *  - 该接口支持设置采样率、声道数
 *  - 该接口只支持只读模式
 *
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 * @note 请不要在此回调函数中做任何耗时操作，否则可能导致声音异常
 */

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

/**
 * @brief 推流数据和播放数据混音后回调
 * @details 默认关闭，需要通过enableAudioFrameObserver : YES audioSource: AliLiveAudioSourceMixedAll 开启
 *
 *  - 该接口支持设置采样率、声道数
 *  - 该接口只支持只读模式
 *
 * @param pusher 推流引擎对象
 * @param audioSample 音频数据sample, {@link AlivcLivePusherAudioDataSample}
 * @note 请不要在此回调函数中做任何耗时操作，否则可能导致声音异常
 */

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


@end

/** @} */

