MagicEngine.framework
为特效引擎静态frameworkopencv2.framework
依赖库libtensorflowlite.a
依赖库CoreML.framework
依赖库Accelerate.framework
依赖库MetalKit.framework
依赖库MetalPerformanceShader.framework
依赖库AssetsLibrary.framework
依赖库StreamLakeLicensing.framework
鉴权库StreamLakeOpenAPI.framework
鉴权库MagicEngine.bundle
智能特效SDK内置素材,细条特效需要用到,实例化sdk时设到MEEngineConfig
的builtinPath
ycnn_metal.bundle
AI推理所需的资源文件,需要内置放在打包的.ipa
根目录target->Build Phases->Link Binary With Libraries
。+
再从弹窗最下面选择Add Other
按钮,点击Add Files
从弹出的文件选择框中选择你本地的MagicEngine.framework
,opencv2.framework
,StreamLakeLicensing.framework
,StreamLakeOpenAPI.framework
,libtensorflowlite.a
进行添加。+
再从弹窗最下面选择Add Other
按钮,点击Add Files
从弹出的文件选择框中选择你本地的``进行添加。+
再弹窗中依次搜搜CoreML.framework
,MetalPerformanceShader.framework
点击Add
进行添加依赖库。target->Build Settings
搜 Other Linker Flags
, 双击点击底下加号添加 $(inherited)
,-ObjC
, -l"c++"
bitcode
/**
* 业务类型
*/
typedef enum MEBusinessType
{
MEBusinessType_Camera = 0, ///< 相机业务
MEBusinessType_Video, ///< 视频业务
MEBusinessType_Image ///< 图片业务
} MEBusinessType;
/**
* 引擎配置
*/
typedef struct MEEngineConfig
{
char builtinPath[ME_PATH_MAX]; ///< 内置资源跟目录
MEBusinessType businessType; ///< 业务类型
int width; ///< 渲染尺寸
int height; ///< 渲染尺寸
} MEEngineConfig;
/**
* 色域类型
*/
typedef enum MEColorSpace
{
MEColorSpace_601VideoRange = 0,
MEColorSpace_601FullRange,
MEColorSpace_709VideoRange,
MEColorSpace_709FullRange,
MEColorSpace_2020VideoRange,
MEColorSpace_2020FullRange
} MEColorSpace;
/**
* YUV数据类型
*/
typedef enum MEInputDataFormat
{
MEInputDataFormat_NV21,
MEInputDataFormat_NV12,
MEInputDataFormat_I420,
MEInputDataFormat_Texture2D
} MEInputDataFormat;
/**
* 相机位置
*/
typedef enum MECameraPosition
{
MECameraPosition_Unknown = 0, ///< 未定义的相机位置
MECameraPosition_Front, ///< 前置
MECameraPosition_Back ///< 后置
} MECameraPosition;
typedef struct MEFrameData
{
const unsigned char* data[3]; ///< YUV像素数据
int stride[3]; ///< YUV平面stride
MECameraPosition position; ///< 相机位置(前置,后置)
MEColorSpace colorSpace; ///< 色域类型
MEInputDataFormat format; ///< 像素数据格式
int texture; ///< 纹理ID
int width; ///< 宽度
int height; ///< 高度
int rotation; ///< 顺时针旋转这个角度后为正图
float fov; ///< 相机视野角度
bool mirror; ///< 镜像
void* extraData; ///< 额外数据
} MEFrameData;
/**
* 特效类型
*/
typedef enum MEEffectType
{
MEEffectType_Beautify = 0, ///< 美颜
MEEffectType_Makeup, ///< 美妆
MEEffectType_Deform, ///< 美型
MEEffectType_Lookup, ///< 滤镜
MEEffectType_BodySlimming ///< 美体
} MEEffectType;
/**
* 滤镜Lut类型
*/
typedef enum MELookupType
{
MELookupType_NxN = 0, ///< 方形NxN的Lut
MELookupType_Nx1 ///< 横向Nx1的Lut
} MELookupType;
/**
* 滤镜配置
*/
typedef struct MELookupInfo
{
char path[ME_PATH_MAX]; ///< Lut图路径
float intensity; ///< 强度
int dimension; ///< 维数
MELookupType type; ///< Lut类型
} MELookupInfo;
/**
* 美妆配置
*/
typedef struct MEMakeupInfo
{
char resourceDir[ME_PATH_MAX]; ///< 资源路径
char key[ME_PATH_MAX]; ///< 资源key, 用于替换
float intensity; ///< 强度
} MEMakeupInfo;
/**
* 美颜调节类型
*/
typedef enum MEBeautyType
{
MEBeautyType_Bright = 0, ///< 美白
MEBeautyType_Soften, ///< 磨皮
MEBeautyType_WrinkleRemove, ///< 法令纹
MEBeautyType_EyeBagRemove, ///< 黑眼圈
MEBeautyType_Teeth, ///< 白牙
MEBeautyType_EyeBrighten, ///< 亮眼
MEBeautyType_FaceShadow, ///< 立体
MEBeautyType_Clarity, ///< 清晰
MEBeautyType_EvenSkin, ///< 匀肤
} MEBeautyType;
/**
* 美体调节
*/
typedef enum MEBodySlimmingType
{
MEBodySlimmingType_Head = 0, ///< 小头
MEBodySlimmingType_Neck, ///< 天鹅颈
MEBodySlimmingType_Waist, ///< 瘦腰
MEBodySlimmingType_Hip, ///< 美胯
MEBodySlimmingType_Leg, ///< 长腿
MEBodySlimmingType_Shoulder, ///< 瘦肩
MEBodySlimmingType_Breast, ///< 丰胸
} MEBodySlimmingType;
/**
* 魔表状态
*/
typedef enum MEEffectState
{
MEEffectState_Pause, ///< 暂停
MEEffectState_Resume, ///< 恢复
MEEffectState_Reset, ///< 重置
} MEEffectState;
/**
* 触摸手势状态
*/
typedef enum MEInteractionType
{
MEInteractionType_None = 0, ///< 未知
MEInteractionType_TouchBegin, ///< 开始
MEInteractionType_TouchMoved, ///< 移动
MEInteractionType_TouchEnd, ///< 结束或者取消
} MEInteractionType;
/**
* 传感器配置类型
*/
typedef enum MESensorConfigType
{
MESensorConfigType_Reset = 0, ///<重置
MESensorConfigType_Remove ///<移除
} MESensorConfigType;
/**
* 传感器配置
*/
typedef struct MESensorConfig
{
float updateInterval; ///< 更新时间间隔
MESensorConfigType configType; ///< 传感器配置配型
} MESensorConfig;
/**
* 传感器数据
*/
typedef struct MESensorData
{
double timestamp; ///< 传感器时间戳
float rotation; ///< 旋转角度
double attitude[4]; ///< 设备姿态
double acceleration[3]; ///< 加速度
} MESensorData;
/**
* 日志类型
*/
typedef enum MELogType
{
MELogType_Debug = 0, ///< 调试
MELogType_Info, ///< 信息
MELogType_Warning, ///< 警告
MELogType_Error, ///< 错误
} MELogType;
/**
* 媒体类型
*/
typedef enum MEMediaType
{
MEMediaType_Image = 0, ///< 图片
MEMediaType_Video, ///< 视频
} MEMediaType;
/**
* 外部传入的所选素材的信息
*/
typedef struct MEMediaResource
{
MEMediaType type; ///< 类型
char mediaPath[ME_PATH_MAX]; ///< 路径
} MEMediaResource;
/**
* 回传给客户端的提示信息内容
*/
typedef struct MEEffectHint
{
bool mediaResult; ///< 选图/视频结果。true:应用成功;false:应用失败,失败原因为errorMessage;
char mediaPath[ME_PATH_MAX]; ///< 所选图路径
char errorMessage[ME_PATH_MAX]; ///< 失败原因
} MEEffectHint;
/**
* 魔表素材强度调节
*/
typedef enum MEEffectAdjustType
{
MEEffectAdjustType_Default = 0, ///< 调节全部
MEEffectAdjustType_Makeup, ///< 美妆
MEEffectAdjustType_Lookup, ///< 美型
} MEEffectAdjustType;
智能特效SDK的使用依赖StreamlakeLicensing,请务必先初始化Licensing SDK,否则智能特效SDK会调用失败,不生效
OpenAPI 网络库配置:
https://vod.streamlakeapi.com
#import <StreamLakeOpenAPI/SLONetworkingSetupConfig.h>
@interface SLAppDelegate()<SLONetworkingSetup>
@end
@implementation SLAppDelegate
// 填写申请的AK
+ (NSString *)openAPI_AccessKey {
return @"xx";
}
+ (NSString *)openAPI_DeployVersion {
return @"2022-02-10";
}
+ (NSArray<NSString *> *)openAPI_OnlineHosts {
return @[@"https://vod.streamlakeapi.com"];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 尽早设置 配置实现类
[SLONetworkingSetupConfig setupNetworking:self.class];
return YES;
}
ProdCode传入"y-tech"
RSAPublicKey传入申请好的公钥。注意公钥格式换行
举个例子:每行都需要换行,第2行-第8行需要靠左顶到头,不要多余空格
NSString *publicKey = @"-----BEGIN RSA PUBLIC KEY-----\n\
MIIBCgKCAQEA6l1y9YEIxzJ7ZaVyQQZbi0FyNTDom0Bhe68Vb5ep8/jqsL4pHvDc\n\
tc5b5jiqmW8mNXNP6dQ4wHmDeq/YtDk27bGTJ/vKTtqrGf6iZrpTwcDoq4+1fsgv\n\
KsO2c3Mw7mo7t/4Z4R2gW8qng1ZSU27WlWJakcDUcV3NJW1znIdkLzxbadX2apWl\n\
FBjfon6TLK/VTmbwYxavKPBfmqAmMeh9e1jfP/swk7O5BT3KhfYaltflMaUODZ2D\n\
YO88uVslHCX4WhGlCLrbDgVhCNMQ6ANEKOr1U6iEujC98h+2oKgw41Pj0f6rcii6\n\
ksCBQBpc5ngug/dOgVT8e2sB6xDpPzppmQIDAQAB\n\
-----END RSA PUBLIC KEY-----";
_ytechLicensingMgr = [[SLLicensingManager alloc] initWithRSAPublicKey:publicKey prodCode:@"y-tech"];
[_ytechLicensingMgr setupWithCompletion:^(BOOL success) {
NSLog(@"y-tech setup %@, begin verify", @(success));
}];
智能特效SDK需要引以下的头文件:
#import <MagicEngine/MagicEngine.h>
API中的参数和返回值类型以及每个属性的含义请看上面的**3.数据结构与枚举
**
智能特效SDK主要分为两个大模块:
setMagicEffectWithPath:
方法设定素材路径并渲染。ps:如果智能特效素材中存在跟细调一样的效果,加载的时候会按照配置去重。
/**
* @brief 实例化纯数据同步渲染引擎,没必要在GL上下文中调用
* @param config 引擎的配置数据
* @return 引擎实例
* @note 此模式下内部自己创建GL上下文,跟外面进行数据交换,MEBusinessType非MEBusinessType_Image时会压帧,总返回上一帧的结果
*/
+ (id<MagicEngineSync>)createSyncMagicEngine:(MEEngineConfig*)config;
/**
* @brief 实例化纯纹理同步渲染引擎,务必在GL上下文中调用
* @param config 引擎的配置数据
* @return 引擎实例
* @note 此模式下内部共享外部GL上下文,跟外面进行纹理交换,MEBusinessType非MEBusinessType_Image时会压帧,总返回上一帧的结果
*/
+ (id<MagicEngineSyncTexture>)createSyncTextureMagicEngine:(MEEngineConfig*)config;
/**
* @brief 实例化异步渲染引擎,务必在GL上下文中调用
* @param config 引擎的配置数据
* @return 引擎实例
* @note 此模式下内部内部不维护GL上下文,因此需要在GL环境中创建SDL实例
*/
+ (id<MagicEngineAsync>)createAsyncMagicEngine:(MEEngineConfig*)config;
/**
* @brief 同步渲染接口,结果写入返回值frameData中,不要求在GL上下文中调用
* @param frameData 帧数据描述
* @return 带渲染结果的MEFrameData
* @note
* 如果输入数据的高度不为8的倍数时会触发cpu转码,影响一些性能。建议关注一下高度尽量使用高度为8的倍数的分辨率
* 当输入尺寸发生变化时返回值的尺寸不一定会跟输入的frameData一致,不能有这个假设,使用返回值时使用返回值自身的尺寸 或者 要改变画面尺寸时调用clearFrameQueue方法来清理内部历史数据才能确保返回和输入大小一致
*/
- (MEFrameData*)processWithFrameData:(MEFrameData*)frameData;
/**
* @brief 同步渲染接口,结果写入返回值frameData中,要求在GL上下文中调用
* @param frameData 一帧数据,必须得设里面texture
* @note 不用传 data[3], stride[3], colorSpace等数据,, format传MEInputDataFormat_Texture2D,处理结果会写入返回结果中的texture中
* @return 带渲染结果的MEFrameData
*/
- (MEFrameData*)processWithTexture:(MEFrameData*)frameData;
/**
* @brief 异步渲染所用,更新原始数据,需要在非渲染线程调用
* @param frameData 原始YUV数据
* @return 如果返回false说明内部渲染队列满了,需要丢帧
* @note: SDK内部维护了一个队列,在采集线程调用这个API时会放到队列中,render时从队列前端取数据进行渲染
*/
- (BOOL)updateFrameData:(const MEFrameData*)frameData;
/**
* @brief 异步渲染所用,渲染到目标纹理 (适用于调用者管理渲染资源的情况),要求在GL上下文中调用
* @param inputTexture 输入纹理的ID
* @param outputFBO 已经绑好输出纹理的FBO ID.
* @param rotation 输入顺时针旋转rotation角度后为正图 取值:0, 90, 180, 270
* @return 返回值为 NO 时, 表示该帧被跳过, 什么操作都没执行. 请根据返回值做出合理的逻辑.
*/
- (BOOL)renderWithInputTexture:(unsigned int)inputTexture outputFBO:(unsigned int)outputFBO rotation:(int)rotation;
下面这些接口主要是用来设定魔法表情,调节美颜,美型,美妆,美体,滤镜等。
/**
* @brief 智能特效协议协议
*/
@property (nonatomic, weak) id<MagicEngineDelegate> delegate;
/**
* @brief 设定模型路径
* @param pathDic 模型key和path的字典
*/
- (void)setModelPathDic:(NSDictionary<NSString*, NSString*>*)pathDic;
/**
* @brief 开启/关闭 单个特效
* @param effectType 需要开启的特效类型
* @param enable 开启或者关闭状态
*/
- (void)setEffectEnabledWidthEffectType:(MEEffectType)effectType enable:(bool)enable;
/**
* @brief 设定滤镜资源
* @param lookupInfo 需要设定的拍前滤镜信息
*/
- (void)setLookupInfo:(MELookupInfo)lookupInfo;
/**
* @brief 设定滤镜强度
* @param intensity 滤镜强度
*/
- (void)setLookupIntensity:(float)intensity;
/**
* @brief 设定美妆资源
* @param makeupInfo 需要设定的美妆信息,每个部分都是一个MakeupInfo结构
*/
- (void)setMakeupInfo:(NSArray<NSValue*>*)makeupInfo;
/**
* @brief 设定美妆强度
* @param key 需要调整的美妆key(设定美妆时用户自定义)
* @param intensity 强度
*/
- (void)setMakeupIntensityWithKey:(NSString*)key intensity:(float)intensity;
/**
* @brief 设定美颜强度
* @param type 需要调节的美颜类型
* @param intensity 强度
*/
- (void)setBeautyIntensityWithType:(MEBeautyType)type intensity:(float)intensity;
/**
* @brief 设定美型强度
* @param mode 美型类型
* @param intensity 强度
*/
- (void)setDeformIntensityWithMode:(int)mode intensity:(float)intensity;
/**
* @brief 设定美体强度
* @param type 需要调整的美体类型
* @param intensity 强度
*/
- (void)setBodySlimmingIntensityWithType:(MEBodySlimmingType)type intensity:(float)intensity;
/**
* @brief 设定魔表素材
* @param path 需要设定的素材路径
*/
- (void)setMagicEffectWithPath:(NSString*)path;
/**
* @brief 取消魔表素材
*/
- (void)cancelMagicEffect;
/**
* 设定特效状态
* effectState: 特效状态支持 暂停,恢复,重置
*/
- (void)setEffectStateWithState:(MEEffectState)effectState;
/**
* 设定素材强度
* type: 调节类型
* intensity: 强度
*/
- (void)setEffectIntensityWithType:(MEEffectAdjustType)type intensity:(float)intensity;
/**
* 设定媒体资源
*/
- (void)setMediaResource:(MEMediaResource)mediaResource;
/**
* @brief 设定手势数据
* @param points 触碰点坐标
* @param type 触碰类型
*/
- (void)setInteractionResponseWithPoints:(NSArray<NSValue*>*)points type:(MEInteractionType)type;
/**
* 更新传感器数据
* @param sensorData 传感器数据
*/
- (void)setSensorData:(MESensorData)sensorData;
/**
* 清理内部正在处理的数据帧队列
*/
- (void)clearFrameQueue;
/**
* @brief 销毁引擎. 调用之后此实例不可再使用. 此方法主要用于保障 MagicEngine 在合适的时机合适的线程释放资源.
*/
- (void)destroy;
大部分素材和美颜美型等都需要一些AI模型的支持。模型的路径通过上面所说的setModelPathDic
方法设定。模型资源都放在了resource目录中的model.7z
中,解压之后就能看到。其中模型的key为文件夹名字,path设此文件夹的路径。例如:key为magic_ycnn_model_landmark
的路径设为/path/to/magic_ycnn_model_landmark
。
当前所有的模型为:
magic_mmu_model_animoji1
magic_mmu_model_basewhite
magic_ycnn_model_cloth_seg
magic_ycnn_model_face_attributes
magic_ycnn_model_face_seg
magic_ycnn_model_finger
magic_ycnn_model_general_handpose
magic_ycnn_model_gesture
magic_ycnn_model_hair
magic_ycnn_model_head_seg
magic_ycnn_model_humanpose
magic_ycnn_model_landmark
magic_ycnn_model_matting
magic_ycnn_model_skin_seg
magic_ycnn_model_landmark
magic_ycnn_model_landmark
magic_ycnn_model_face_attributes
magic_ycnn_model_face_seg
magic_ycnn_model_landmark
magic_ycnn_model_landmark
magic_ycnn_model_humanpose
不需要AI模型
不同素材需要不同的模型,请线下获取素材/模型列表,并在应用某个素材之前确保设定的路径中存在对应的模型文件
每个素材有自己的所需的模型类型,如果内置素材可以把模型也内置。如果下发素材需要确保能够下载好对应的模型再应用素材。素材所需的模型跟素材本身有关。提供素材包时会标注对应的模型名字。开发阶段可以把模型都内置。
通过setModelPathDic
可以多次设定或刚开始把模型key和对应的路径先设定,应用对应功能之前确保再该路径中下载好或者放好对应模型。原则上需要模型的功能在被调用之前把对应的key和path通过这个dictionary设进去即可。
例如:刚开始只调用美颜和美型可以设定magic_ycnn_model_landmark
,magic_ycnn_model_face_attributes
,后面调节美体可以在之前的基础上添加magic_ycnn_model_humanpose
三个一起设进去。素材也是如此,可以一直累加,外部维护一个dictionary,或者全部一起设定,之后在确保模型存于早先设定的路径。
素材对应的模型列表请线下获取素材模型列表.xlsx
文件
在上面的接口文档中有提到有下面这个函数。这个函数主要是会把智能特效素材中的一些配置信息在智能特效被应用后回调出来。第一个参数是 String description
是配置信息的json字符串。客户端需要解析并获取所需信息。第二个参数是 Boolean loadSucceed
素材加载成功和失败的状态。
@protocol MagicEngineDelegate<NSObject>
@required
/**
* @brief 智能特效加载回调
* @param jsonStr 智能特效描述json数据
* @param loadSuccess 表示加载状态,如果成功则为true否则为false
*/
- (void)onEffectDescriptionUpdate:(NSString*)jsonStr loadSuccess:(bool)loadSuccess;
/**
* @brief 传感器配置回调
* @param sensorConfig 传感器配置。
* @note 如果config中的type为 `MESensorConfigType_Reset`则需要传递传感器数据,如果为`MESensorConfigType_Remove `则不需要传感器,可以暂停。里面updateInterval是传感器更新时间间隔推荐值
*/
- (void)onSensorConfigUpdate:(MESensorConfig)sensorConfig;
/**
* @brief 魔表提示回调,在支持本地选图类素材中使用
* @param effectHint 提示信息
*/
- (void)onReceivedEffectHint:(MEEffectHint)effectHint;
@end
{
"disableCustomBeautify": true,
"disableCustomDeform": true,
"disableCustomMakeup": true,
"disableCustomColorFilter": true,
"disableCustomSlimming": true,
}
由于细调和素材中都有美妆,美型,美体,美颜,滤镜特效。所以有美妆的素材一般会配置禁用细调美妆,其他细调项同理。
客户端在加载成功后需要看一下description json中以下几个字段。如果 disableCustomXXX
为 true
表示素材加载后会禁用细调中的相关调节项。客户端从外面调节强度也不会生效。因此客户端需要把调节UI置灰 避免用户去做无用的操作。
{
"needTouch": true,
"needSwipe": true,
"needPinch": true
}
客户端在加载成功后需要看一下description json中以下几个字段。如果 needTouch
或 needSwipe
或 needPinch
为true客户端需要通过一下接口把用户的触摸信息传递进来。否则相关素材的点击交互不会生效。
- (void)setInteractionResponseWithPoints:(NSArray<NSValue*>*)points type:(MEInteractionType)type;
{
"needPickFirstMedia": true,
"needPickMediaResourceType": 1,
"embeddingMedias": [
{
"iconPath": "/path/to/icon.png",
"mediaPath": "/path/to/media.png",
"type": 0
}
]
}
客户端在加载成功后需要查看description json中是否有以上json字段。当needPickMediaResourceType
大于0时,说明此素材支持从本地选择媒体资源(图片/视频)。embeddingMedias
中返回了素材中内置的美体资源icon,路径和类型。客户端可以按需展示出来供用户选择替换。当needPickFirstMedia
为true时说明客户端在拿到description json的第一时间把embeddingMedias
中的第一个资源通过上面的- (void)setMediaResouce:(MEMediaResource)mediaResouce;
api来设到智能引擎中。
ps: 如果为异步模式的接入方式setMediaResouce:
务必在gl上下文中调用,否则行为是未定义的。
调用setMediaResouce:
之后设定结果会在 onReceivedEffectHint
回调中通知客户端。该结构中记录了哪个路径下的媒体资源应用成功或者失败。如果失败则附带错误信息。
"adjustIntensityConfig": {
"enabled": true,
"defaultIntensity": 0.800000011920929,
"defaultLookupIntensity": 0.5,
"defaultMaleMakeupIntensityEnabled": false,
"defaultMaleMakeupIntensity": 0.800000011920929,
"effectTypes": [
"makeup"
]
}
客户端在加载成功后需要查看description json中是否有以上json字段。当存在adjustIntensityConfig
时,需要先解析里面的enabled
字段,如果该字段为true表示本素材支持做调节。其中effectTypes
表示支持调节的效果类型makeup
为美妆,lookup
为滤镜。defaultLookupIntensity
是默认滤镜强度,defaultIntensity
为默认强度,如果存在美妆则为美妆的强度。否则为素材默认强调。有时候素材中也有有一些逻辑支持调节会用到。
外部需要调整时需要调用- (void)setEffectIntensityWithType:(MEEffectAdjustType)type intensity:(float)intensity;
来进行调节。传对应的type和强度就行。需要注意的是类型MEEffectAdjustType
必须对上上面返回的json内容。
"localeTips":{
"en":"",
"hi":"",
"id":"",
"ko":"",
"ms":"",
"pt":"",
"ru":"",
"tr":"",
"vi":"",
"zh":"低头有惊喜",
"zh-HK":"",
"zh-TW":""
}
通过回调中的localeTips获取一些素材中的玩儿法提示,不一定每个素材都有这个字段
1.调用鉴权API
进行授权
2.按需调用4.2.1中的实例化方法创建智能特效实例
3.按需调用4.2.2中对应的数据处理方法进行数据处理
4.准备退出时调用 destroy
方法销毁SDK,非MagicEngineSync
模式下需要在GL线程调用Destroy方法.
渲染都封装在了FMEffectRenderView
里,只需要引入头文件 #import <MagicEngine/MEEffectRenderView.h> 调用下面的素材设定接口即可。FMEffectRenderView 继承自UIView,表现跟UIView一致。
/**
* 手势触摸状态
*/
typedef NS_ENUM(NSInteger, FMTouchType) {
FMTouchUnknown = 0, ///< 未知
FMTouchBegin, ///< 开始
FMTouchMove, ///< 移动
FMTouchEnd ///< 结束或者取消
};
/**
* @brief 设定View创建回调
* @param block view渲染准备好之后主线程回调给客户端,接下来的所有view相关API需要在这个block回调之后进行
*/
- (void)setCreateOverBlock:(RunableBlock)block;
/**
* @brief 设定智能特效素材
* @param path 智能特效素材绝对路径
* @note 如果想取消当前素材可以传nil或空字符
*/
- (void)setEffectPath:(NSString*)path;
/**
* @brief 设定视频贴纸
* @param path 视频贴纸mp4路径
* @param playCount 播放此时,如果设 0 表示无限循环播放
* @note 如果想取消当前视频贴纸可以传nil或空字符,跟setEffectPath互斥
*/
- (void)setVideoBlendWith:(NSString*)path playCount:(int)playCount;
/**
* @brief 设定素材游戏数据
* @param gameData 游戏数据json字符串
*/
- (void)setBoomGameData:(NSString*)gameData;
/**
* @brief 设定手势数据
* @param point 相对于view的归一化坐标数据,左上角为{0.0, 0.0} 右下角为{1.0, 1.0}
* @param type 手势触碰类型
* @note 推荐实现touches[Began][Moved][Ended][Cancelled]:withEvent:方法来传递。
* 备注:当前加载的智能特效是否需要手势传递取决于onReceivedEffectDescription:loadSuccess:回调。
*/
- (void)touchWith:(CGPoint)point type:(FMTouchType)type;
/**
* @brief 暂停智能渲染,如果APP进后台务必需要暂停
*/
- (void)pause;
/**
* @brief 恢复智能特效渲染
*/
- (void)resume;
/**
* @brief 重置智能特效渲染
* @note 会重新开始当前的智能特效素材
*/
- (void)reset;
/**
* @brief 设定渲染轮训的displayLink的frameInterval
* @param frameInterval 表示隔多少帧进行渲染一次,默认值2,如果想提高帧率可以设为1
*/
- (void)setDisplayLinkFrameInterval:(NSInteger)frameInterval;
/**
* @brief 释放GL资源
* @note 需要客户端在释放本view之前调用,确保资源的准确释放
*/
- (void)releaseGLResources;
客户端可以通过实现MEEffectRenderView 的delegate(MEEffectRenderViewDelegate)来获取智能特效素材的加载状态。
备注:这两个回调都在渲染线程回调。
/**
* @brief 素材加载回调
* @param jsonStr 素材描述json数据,是否需要touch事件取决于json中的needTouch字段。后续可能会新增别的描述
* @param loadSuccess 表示加载状态,如果成功则为true否则为false
*/
- (void)onReceivedEffectDescription:(NSString*)jsonStr loadSuccess:(bool)loadSuccess;
/**
* @brief 素材游戏数据回调
* @param jsonStr 素材游戏json数据
*/
- (void)onReceivedBoomGameInfo:(NSString*)jsonStr;
/**
* @brief 调用 setVideoBlendWith来播放视频时播放结束回调
*/
- (void)onVideoBlendPlayingComplete:(NSString*)path;
/**
* @brief 礼物素材播放完毕时回调
*/
- (void)onGiftRenderingComplete:(NSString*)path;