//
//  AliPlayer.h
//  AliPlayer
//
//  Created by shiping.csp on 2018/11/16.
//  Copyright © 2018 com.alibaba.AliyunPlayer. All rights reserved.
//

#import "AVPCacheConfig.h"
#import "AVPConfig.h"
#import "AVPDef.h"
#import "AVPDelegate.h"
#import "AVPFilterConfig.h"
#import "AVPMediaInfo.h"
#import "AVPSource.h"
#import <Foundation/Foundation.h>

@protocol AVPDrmDelegate;
@protocol CicadaAudioSessionDelegate;
@protocol CicadaRenderDelegate;
@protocol CicadaRenderingDelegate;
@protocol AliPlayerPictureInPictureDelegate;

@class AVPFilterConfig;
@class AVPFilterOptions;


OBJC_EXPORT
@interface AliPlayer : NSObject

/**
 @brief 初始化播放器
 */
- (instancetype)init;

/**
 @brief 初始化播放器
 @param traceID 便于跟踪日志，设为"DisableAnalytics"可关闭日志分析系统（不推荐）。
 */
- (instancetype)init:(NSString*)traceID;

- (void *)getPlayer;

/**
 @brief 使用url方式来播放视频
 @param source AVPUrlSource的输入类型
 @see AVPUrlSource
 */
- (void)setUrlSource:(AVPUrlSource*)source;

/**
 @brief 使用bitstream方式来播放视频
 @param source AVPBitStreamSource的输入类型
 @see AVPBitStreamSource
 */
- (void)setBitStreamSource:(AVPBitStreamSource *)source;

/**
 @brief 用vid和sts来播放视频，sts可参考：https://help.aliyun.com/document_detail/28756.html
 @param source AVPVidStsSource的输入类型
 @see AVPVidStsSource
 */
- (void)setStsSource:(AVPVidStsSource*)source;

/**
 @brief 用vid和MPS信息来播放视频。可参考：https://help.aliyun.com/document_detail/53522.html
 @param source AVPVidMpsSource的输入类型
 @see AVPVidMpsSource
 */
- (void)setMpsSource:(AVPVidMpsSource*)source
__attribute__((deprecated("This method is deprecated, please use setAuthSource instead")));

/**
 @brief 使用vid+playauth方式播放。可参考：https://help.aliyun.com/document_detail/57294.html
 @param source AVPVidAuthSource的输入类型
 @see AVPVidAuthSource
 */
- (void)setAuthSource:(AVPVidAuthSource*)source;

/**
 @brief 使用LiveSts 方式播放直播流
 @param source  AVPLiveStsSource的输入类型
 */
- (void)setLiveStsSource:(AVPLiveStsSource*)source;

/**
 @brief 更新LiveStsInfo
 @param accId 鉴权id
 @param accKey 鉴权秘钥
 @param token 安全token
 @param region 地域
 */
- (void)updateLiveStsInfo:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;

/**
 @brief 播放准备，异步
 */
-(void)prepare;

/**
 @brief 开始播放
 */
-(void)start;

/**
 @brief 暂停播放
 */
-(void)pause;

/**
 @brief 刷新view，例如view size变化时。
 */
- (void)redraw DEPRECATED_MSG_ATTRIBUTE("will not take effect");

/**
 @brief 清空画面。
 */
- (void)clearScreen;

/**
 @brief 同步清空画面。
 */
- (void)clearScreenSync;

/**
 @brief 重置播放
 */
-(void)reset DEPRECATED_ATTRIBUTE;

/**
 @brief 停止播放
 */
-(void)stop;

/**
 @brief 同步销毁播放器
 */
-(void)destroy;

/**
 @brief 异步销毁播放器。当实例不再需要时，省去stop的调用并使用destroyAsync进行异步释放，可以加快页面响应速度，提高体验，释放后不要再调用prepare进行新的起播，否则调用效果不可预知。
 */
-(void)destroyAsync;

/**
 @brief 以指定位置起播，每次prepare前调用，仅生效一次。（用于代替原先的起播前seek的方案）
 @param time 新的播放位置，单位毫秒
 @param seekMode seek模式
 @see AVPSeekMode
 */
-(void)setStartTime:(int64_t)time seekMode:(AVPSeekMode)seekMode;

/**
 @brief 跳转到指定的播放位置
 @param time 新的播放位置，单位毫秒
 @param seekMode seek模式
 @see AVPSeekMode
 */
-(void)seekToTime:(int64_t)time seekMode:(AVPSeekMode)seekMode;

/**
 * 设置精准seek的最大间隔。
 * @param delta 间隔时间，单位毫秒
 */
-(void)setMaxAccurateSeekDelta:(int)delta;

/**
 @brief 截取当前画面。截图结果通过{@link AVPDelegate::onCaptureScreen}回调。 
 */
-(void) snapShot;

/**
 @brief 根据url进行多清晰度切换，选择成功与否的结果通过AVPDelegate onStreamSwitchedSuccess/onStreamSwitchedFail回调。
 * 注意：
 * 1. 必须是阿里云的直播地址。
 * 2. 必须是直播流的不同清晰度。
 * 3. 切换到无关流地址可能会失败。
 @param url 新流的url地址
 */
-(void)switchStream:(NSString *)URL;

/**
 @brief 根据轨道索引切换视频清晰度。支持手动指定清晰度或开启自适应码率模式。
 @param trackIndex 目标清晰度的轨道索引。使用SELECT_AVPTRACK_TYPE_VIDEO_AUTO表示开启自适应码率
 */
-(void)selectTrack:(int)trackIndex;

/**
 @brief 根据轨道索引切换视频清晰度，支持精准跳转选项。
 @param trackIndex 目标清晰度的轨道索引。使用SELECT_AVPTRACK_TYPE_VIDEO_AUTO表示开启自适应码率
 @param accurate 是否使用精准跳转模式进行切换。YES表示精准跳转，NO表示快速跳转
 */
-(void)selectTrack:(int)trackIndex accurate:(BOOL)accurate;

/**
 @brief 获取媒体信息，包括track信息
 */
-(AVPMediaInfo*) getMediaInfo;

/**
 @brief 获取媒体子流信息，包括track信息
 */
-(AVPMediaInfo*) getSubMediaInfo;

/**
 @brief 获取当前播放track
 @param type track类型
 @see AVPTrackType
 */
-(AVPTrackInfo*) getCurrentTrack:(AVPTrackType)type;

/**
 @brief 设置缩略图URL
 @param URL 缩略图URL
 */
-(void) setThumbnailUrl:(NSString *)URL;

/**
 @brief 获取指定位置的缩略图
 @param positionMs 代表在哪个指定位置的缩略图
 */
-(void)getThumbnail:(int64_t)positionMs;

/**
 @brief 用于跟踪debug信息
 @param traceID 指定和其他客户端连接可跟踪的id
 */
- (void) setTraceID:(NSString*)traceID;


/**
 @brief 设置转换播放的url的回调函数，一般用于p2p中的url地址转换
 @param callback 回调函数指针
 */
- (void) setPlayUrlConvertCallback:(PlayURLConverCallback)callback;
/**
 @brief 播放器设置
 @param config AVPConfig类型
 @see AVPConfig
 */
-(void) setConfig:(AVPConfig*)config;

/**
 @brief 设置播放器场景
 @param scene 播放器场景
 @see AVPScene
 */
-(void) setPlayerScene:(AVPScene)scene;

/**
 @brief 播放器降级设置
 @param source 降级url
 @param config 降级配置
 */
-(void) enableDowngrade:(AVPUrlSource*)source config:(AVPConfig*)config;

/**
 @brief 获取播放器设置
 @see AVPConfig
 */
-(AVPConfig*) getConfig;

/**
 @brief 设置缓存配置
 @param AVPCacheConfig 缓存配置。{@link AVPCacheConfig}。
 @return 设置成功返回YES
 @deprecated 从7.0.0版本开始，该接口已废弃。请使用 `AliPlayerGlobalSettings::enableLocalCache:(bool)enable` 替代。
 */
-(BOOL) setCacheConfig:(AVPCacheConfig *)cacheConfig
__attribute__((deprecated("Use +[AliPlayerGlobalSettings enableLocalCache:] instead")));

/**
 @brief  设置滤镜配置。在prepare之前调用此方法。如果想更新，调用updateFilterConfig()
 @param filterConfig
 */
- (void)setFilterConfig:(AVPFilterConfig *)filterConfig;

/**
 @brief更新滤镜配置
 @param target
 @param options
 */
- (void)updateFilterConfig:(NSString *)target options:(AVPFilterOptions *)options;
/**
 @brief 开启关闭滤镜.
 @param target  如果为空，则对所有滤镜生效
 @param invalid  true: 开启; false: 关闭
 */
- (void)setFilterInvalid:(NSString *)target invalid:(BOOL)invalid;

/**
 @brief 根据url获取缓存的文件名。如果有自定义的规则，请实现delegate {@link onGetCacheNameByURL}。
 @brief 如果没有实现delegate，将会采用默认逻辑生成文件名。
 @param URL URL
 @return 最终缓存的文件名（不包括后缀。缓存文件的后缀名统一为.alv）。
 @deprecated 从7.0.0版本开始，该方法已废弃。
 */
-(NSString *) getCacheFilePath:(NSString *)URL
__attribute__((deprecated("This method is deprecated")));

/**
 @brief 根据url获取缓存的文件名。如果有自定义的规则，请实现delegate {@link onCacheNameByVidCallback}。
 @brief 如果没有实现delegate，将会采用默认逻辑生成文件名。
 @param vid        视频id
 @param format     视频格式
 @param definition 视频清晰度
 @return 最终缓存的文件名（不包括后缀。缓存文件的后缀名统一为.alv）。
 @deprecated 从7.0.0版本开始，该方法已废弃。
 */
-(NSString *) getCacheFilePath:(NSString *)vid format:(NSString *)format definition:(NSString *)definition
__attribute__((deprecated("This method is deprecated")));

/**
 @brief 根据url获取缓存的文件名。如果有自定义的规则，请实现delegate {@link onCacheNameByVidCallback}。
 @brief 如果没有实现delegate，将会采用默认逻辑生成文件名。
 @param vid        视频id
 @param format     视频格式
 @param definition 视频清晰度
 @param previewTime 试看时长
 @return 最终缓存的文件名（不包括后缀。缓存文件的后缀名统一为.alv）。
 */
-(NSString *) getCacheFilePath:(NSString *)vid format:(NSString *)format definition:(NSString *)definition previewTime:(int)previewTime;

/**
 @brief 添加外挂字幕文件。支持多种字幕格式，如SRT、ASS、VTT等。
 @param URL 字幕文件的URL地址，支持本地文件路径或网络地址
 */
-(void) addExtSubtitle:(NSString *)URL;

/**
 @brief 选择或关闭指定的外挂字幕轨道。
 @param trackIndex 字幕轨道索引，通过媒体信息获取可用的字幕轨道列表
 @param enable YES表示选择并显示该字幕轨道，NO表示关闭字幕显示
 */
-(void) selectExtSubtitle:(int)trackIndex enable:(BOOL)enable;



/**
 @brief 是否关闭字幕渲染
 @param enable true：开启，false：关闭
 */
- (void)setEnableSubtitleRender:(BOOL)enable;



- (BOOL)isEnableSubtitleRender;

/**
 * @brief 设置某路流相对于主时钟的延时时间，默认是0, 目前只支持外挂字幕
 * @param index 流的索引
 * @param time  延时，单位毫秒
 * @deprecated
 */

- (void)setStreamDelayTime:(int)index time:(int)time
__attribute__((deprecated("This method is deprecated")));


/**
 @brief 重新加载。比如网络超时时，可以重新加载。
 */
-(void) reload;

/**
 @brief 根据key获取相应的信息。
 @param key 关键字枚举值
 * @return 相应信息（找不到相应信息返回空字符串）。
 */
-(NSString *) getPropertyString:(AVPPropertyKey)key;

/**
 @brief 设置多码率播放时的默认起播码率。播放器将选择与指定码率最接近的流进行播放。
 @param bandWidth 默认播放码率值，单位为bps
 */
-(void) setDefaultBandWidth:(int)bandWidth;


/**
 @brief 设置多码率播放时的默认起播清晰度。通过分辨率乘积值选择最接近的清晰度流进行播放。
 @param resolutionProduct 目标清晰度对应的宽度和高度的乘积值。播放器将选择与此值最接近的清晰度进行起播。
                          例如：传入1920 * 1080 = 2073600，播放器会选择最接近1920x1080分辨率的流进行播放
 */
-(void) setDefaultResolution:(int)resolutionProduct;



/**
 @brief 设置多码率播放时是否开启自适应选择起播清晰度功能。注意：该接口仅影响起播时的清晰度选择，起播后不会动态调整清晰度。可通过AVPConfig.maxAllowedAbrVideoPixelNumber限制自适应选择的最大清晰度。
 @param enable YES表示开启自适应选择起播清晰度，NO表示关闭
 @see AVPConfig.maxAllowedAbrVideoPixelNumber
 */
-(void) setAutoBandWidth:(BOOL)enable;

/**
 @brief 获取当前是否开启了多码率播放时自适应选择起播清晰度的功能状态。
 @return YES表示已开启自适应选择起播清晰度，NO表示未开启
 */
-(BOOL) isAutoBandWidth;


#if TARGET_OS_IPHONE
/**
 @brief 设置视频的背景色
 @param color  ARGB，默认值0xFF000000
 */
-(void) setVideoBackgroundColor:(UIColor *)color;

/**
 @brief 设置创建解码器的时机，为true时，在收到{@link AVPEventType::AVPEventPrepareDone}时，就已经创建好了，这样{@link start}调用就很快能起播；为false时，在调用{@link start}时才会创建，但可以加速{@link AVPEventType::AVPEventPrepareDone}事件的回调，若是自动播放，总体首帧无区别。
 @param enable  true：开启，false：关闭；默认值是true
 */
-(void) setFastStart:(BOOL)enable;

/**
 * @brief 设置网络IPv4/IPv6解析类型
 * @param type 见 {@link IPResolveType}，默认值都支持，谁响应快速，就优先使用
 */
-(void) setIPResolveType:(AVPIpResolveType)type;
#endif

/**
 @brief 设置代理 参考AVPEventReportParamsDelegate
 @see AVPEventReportParamsDelegate
 */
-(void) setEventReportParamsDelegate:(id<AVPEventReportParamsDelegate>)delegate;


/**
 * @brief 为画中画功能设置代理
 *
 * @param delegate 画中画代理
 */
-(void) setPictureinPictureDelegate:(id<AliPlayerPictureInPictureDelegate>)delegate;


/**
 * @brief 为画中画功能设置显示模式
 *
 * @param delegate 画中画显示模式
 */
- (void)setPictureInPictureShowMode:(AVPPIPShowMode)pipShowMode;

/**
 * @brief 获取播放器的参数
 *
 * @param key 参数值
 * @return 相关信息
 */
-(NSString *) getOption:(AVPOption)key;


/**
 @brief 向播放器的组件发送命令。
 @param content 命令内容。
 @return 命令执行结果， < 0 失败。
 */

- (int)invokeComponent:(NSString *)content
__attribute__((deprecated("This method is deprecated")));
/**
 @brief 获取SDK版本号信息
 */
+ (NSString *)getSDKVersion;

/**
 @brief 获取设备UUID
 */
+ (NSString *)getDeviceUUID;

/**
 @brief 返回某项功能是否支持
 @param type 是否支持的功能的类型。 参考SupportFeatureType。
 */
+ (BOOL)isFeatureSupport:(SupportFeatureType)type;

/**
 @brief 初始化播放器组件。这些组件是可裁剪的。App可删除相应动态库，去掉初始化组件代码，实现裁剪。
 */
+ (void)initPlayerComponent:(NSString *)functionName function:(void *)function;

/**
 @brief 设置是否静音，支持KVO
 */
@property(nonatomic, getter=isMuted) BOOL muted;

/**
 @brief 播放速率，0.5-2.0之间，1为正常播放，支持KVO
 */
@property(nonatomic) float rate;

/**
 @brief 是否启用硬解码，默认开启。
 * 失败后降级软解，若设置了自适应降级{@link AliPlayerGlobalSettings::setAdaptiveDecoderGetBackupURLCallback} ，可降级播放不同编码的视频，如H265->H264。
 */
@property(nonatomic) BOOL enableHardwareDecoder;

/**
 @brief 设置是否循环播放，支持KVO
 */
@property(nonatomic, getter=isLoop) BOOL loop;

/**
 @brief 设置是否自动播放，支持KVO
 */
@property(nonatomic, getter=isAutoPlay) BOOL autoPlay;

/**
 @brief 渲染镜像模式，支持KVO
 @see AVPMirrorMode
 */
@property(nonatomic) AVPMirrorMode mirrorMode;

/**
 @brief
 * 设置透明渲染模式，支持如直播礼物播放等场景。详细用法参考：<a href="https://help.aliyun.com/vod/developer-reference/advanced-features#7a4b2891e3oca">doc</a>
 @see AVPAlphaRenderMode 默认值{@link AVPAlphaRenderMode.AVP_RENDERMODE_ALPHA_NONE}
 */
@property(nonatomic) AVPAlphaRenderMode alphaRenderMode;

/**
 @brief 渲染旋转模式，支持KVO
 @see AVPRotateMode
 */
@property(nonatomic) AVPRotateMode rotateMode;

/**
 @brief 渲染填充模式，支持KVO
 @see AVPScalingMode
 */
@property(nonatomic) AVPScalingMode scalingMode;


/**
 @brief 设置输出声道，若输入源是双声道，则支持切换为左声道、右声道；若输入源是单声道，则设置无效。该设置会同时影响音频渲染及PCM数据回调
 @see AVPOutputAudioChannel
 */
@property(nonatomic) AVPOutputAudioChannel outputAudioChannel;

/**
 @brief 设置播放器的视图playerView
 * AVPView: mac下为NSOpenGLView，iOS下为UIView
 */
@property(nonatomic, strong) AVPView* playerView;

/**
 @brief 获取视频的宽度，支持KVO
 */
@property (nonatomic, readonly) int width;

/**
 @brief 获取视频的高度，支持KVO
 */
@property (nonatomic, readonly) int height;

/**
 @brief 获取视频的旋转角度，从metadata中获取出来，支持KVO
 */
@property (nonatomic, readonly) int rotation;

/**
 @brief 获取/设置播放器的音量（非系统音量），支持KVO，范围0.0~2.0，当音量大于1.0时，可能出现噪音，不推荐使用。
 */
@property (nonatomic, assign) float volume;

/**
 @brief 获取视频的长度，支持KVO
 */
@property (nonatomic, readonly) int64_t duration;

/**
 @brief 获取当前播放位置，支持KVO
 */
@property (nonatomic, readonly) int64_t currentPosition;

/**
@brief 获取当前播放位置的utc时间，支持KVO
*/
@property(nonatomic, readonly) int64_t currentUtcTime;


/**
@brief 获取当前播放命中的缓存文件大小，支持KVO
*/
@property(nonatomic, readonly) int64_t localCacheLoadedSize;

/**
 @brief 获取当前下载速度，支持KVO
 */
@property(nonatomic, readonly) int64_t currentDownloadSpeed;

/**
 @brief 获取已经缓存的位置，支持KVO
 */
@property (nonatomic, readonly) int64_t bufferedPosition;

/**
 @brief 获取播放器状态，支持KVO
 */
@property (nonatomic, readonly) AVPStatus playerStatus;

/**
 @brief 设置代理，参考AVPDelegate
 @see AVPDelegate
 */
@property (nonatomic, weak) id<AVPDelegate> delegate;

/**
 @brief 设置渲染回调。废弃，使用renderingDelegate。
 */
@property(nonatomic, weak) id<CicadaRenderDelegate> renderDelegate __deprecated;

/**
 @brief 设置渲染回调。
 */
@property(nonatomic, weak) id<CicadaRenderingDelegate> renderingDelegate;

/**
 @brief 设置DRM的请求回调，该回调只会在通过URL{@link setUrlSource}起播时会触发，通过VidAuth、VidSts不会触发，目前只支持Fairplay。
 */
@property(nonatomic, weak) id<AVPDrmDelegate> drmDelegate;

/**
 @brief 设置埋点事件回调。
 */
@property (nonatomic, weak) id <AVPEventReportParamsDelegate> eventReportParamsDelegate;

/**
 @brief 设置AudioSession的Delegate
 @param delegate Delegate对象
 */
+ (void)setAudioSessionDelegate:(id<CicadaAudioSessionDelegate>)delegate;

/**
 @brief 是否打开log输出
 @param enableLog true表示输出log
 @see 使用setLogCallbackInfo
 */
+(void)setEnableLog:(BOOL)enableLog;

/**
 @brief 设置日志打印回调block，异步
 @param logLevel log输出级别
 @param callbackBlock log回调block，可以为nil
 */
+(void) setLogCallbackInfo:(AVPLogLevel)logLevel callbackBlock:(void (^)(AVPLogLevel logLevel,NSString* strLog))block;

/**
 @brief 设置日志打印选项
 @param logOption logOption
 @param value 选项value 0代表关闭 1代表打开
 */
 + (void)setLogOption:(AVPLogOption)logOption value:(int)value;

/**
 @brief 加密直播播放过程中可能会有更换加密Key的过程，换Key时则会通过STS去请求到最新的Key。开发者需要监听STS是否有效。如果无效则会影响加密直播流的播放。获取STS成功之后，需要调用{@link updateLiveStsInfo}方法去更新。
 @param callback
 */
-(void) setVerifyStsCallback:(AVPStsStatus (^)(AVPStsInfo info)) callback;
/**
 @brief 设置播放时选择的播放器内核，默认为自研内核，可切换至系统内核，调用{@link prepare}前设置。
 @param name 播放器名字,如"AppleAVPlayer" 为iOS系统播放器，默认为""。
 */
- (void)setPreferPlayerName:(NSString *)name;
/**
 @brief 获取播放时使用的播放器名字
 */
- (NSString *)getPlayerName;

/**
 @brief 设置视频标签。值范围[0,99]。
 @deprecated
 */
- (void)setVideoTag:(int *)tags size:(int)size
__attribute__((deprecated("This method is deprecated")));

/**
 @brief
 * 发送用户自定义事件，将通过{@link AVPEventReportParamsDelegate} 回调，用于将业务事件/埋点统一走播放器的埋点回调，方便业务统一流程。用户自定义事件 e = 5001，args为透传的参数。
 * @param args 自定义参数
 */
- (void)sendCustomEvent:(NSString *)args;

/**
 * @brief 设置player实例的UserData，多实例下可用于区分不同的player实例，可通过{@link AliPlayer::getUserData}获取到。
 * @param userData 用户自定义数据
 */
- (void)setUserData:(NSString *)userData;

/**
 @brief 设置特定功能选项。
 */
- (void)setOption:(PlayerOption)key value:(NSString *)value;

/**
 @brief 设置特定功能选项。
 */
- (void)setOption:(PlayerOption)key valueInt:(int)value;

/**
 @brief 获取UserData，一个实例绑定一个。
 */
- (NSString *)getUserData;

/**
 @brief 重连所有网络连接，网络路由发生变化后，调用此接口，可以让播放器所有的连接切换到新的路由上去。
 @deprecated
 */
+ (void)netWorkReConnect DEPRECATED_MSG_ATTRIBUTE("don't need use this API, reconnect internally when network state changed");

/**
 @brief 设置画中画功能开启/关闭    (目前播放器自带的画中画功能需要iOS15以上的系统，如果其他系统，可以通过播放器CicadaRenderingDelegate返回的pixelbuffer来自定义实现)
 */
- (void)setPictureInPictureEnable:(BOOL)enable;

/**
 @breif 获取当前播放时长，不受seek的影响
 */
- (int64_t) getPlayedDuration;

@end
