QVEditorKit
示例
要运行示例项目,请克隆仓库,然后首先从 Example 目录运行 pod install
。
要求
安装
QVEditorKit 可以通过 CocoaPods 获取。要安装它,只需将以下行添加到您的 Podfile 中
Podfile 文件中加上:
inhibit_all_warnings!
pod 'QVEditorKit'
pod 'SSZipArchive'
pod 'YYImage/WebP'
pod 'PromisesObjC'
小影 iOS 剪辑SDK 接入文档
一、名词解释
- 工程:分为剪辑工程(XYEngineWorkspace)和卡点视频工程(XYSlideShowEditor),后续统称workspace。其中小影提供的所有剪辑玩法,都是针对剪辑工程进行的操作。卡点视频即使用素材一键生成大片,目前仅支持片段替换和片段排序。
- 播放流:每个工程会独立的播放流,将播放器View和工程绑定后,即可完成视频流的显示。同时可以对工程的播放器做相关操作。
- 主题:theme,一系列效果的合集,包括片头、片尾、转场、音乐、滤镜等。对工程设置主题,可以实现模板视频功能。
- 片段:Clip,片段可以是图片或视频,是工程的基础组成部分。工程将按片段顺序生成一段视频。
- 转场:Transition, 转场效果是设定在两个片段之间的,是两个片段的切换效果。
- 滤镜/特效滤镜:Filter/FxFilter,是添加给单个片段的,覆盖整个片段,可以实现调色滤镜、边框滤镜、特效滤镜等。
- 效果:Effect,贴纸、画中画、字幕、特效、马赛克,都属于效果,是直接在工程上增加的效果。水印也是一种特殊的效果。
- 图层:Layer,Clip都在同一个图层中,效果和音频可以设置自己的图层,图层的层级大小将影响工程视频的实际效果。详情可以参考【基础结构和概念】中的【图层轨道】一节。
- 音频:Audio,音频也是一种特殊的效果。分为背景音乐、音效和录音。背景音乐都在同一图层中,即一个时间点不可同时存在多个音频;音效和录音则可以单独设置图层,即一个时间点可以同时存在多个音频。
- 源文件区间:sourceVeRange,片段中表示加入片段源文件的起始点和长度,效果中表示效果裁剪的起始点和长度。详情可以参考【基础结构和概念】中的【Range相关】一节。
- 裁剪区间:trimVeRange,裁剪片段的起始点和长度。详情可以参考【基础结构和概念】中的【Range相关】一节。
- 出入区间:destVeRange,效果在工程上的起始点和长度。详情可以参考【基础结构和概念】中的【Range相关】一节。
- 导出:Export,将工程以指定分辨率、码率、帧速率和压缩格式输出文件。
- 码率:Bitrate,每秒传送的比特数,码率越高,导出视频质量越好。
- 帧速率:FPS,每秒刷新图像的帧数,帧速率越高,视频的连续性越好。
- 素材包:一种资源文件,用于给工程添加效果使用。特有效果有特地的素材包,主题和卡点视频主题也都有素材包。详情可以参考【素材管理】一节。
- 素材包ID:素材包的唯一标识,安装素材后,可以通过解析素材获取。详情可以参考【素材管理】一节。
二、基础结构与概念
1. 支持格式
- 输入规范:
视频格式:MP4、MOV、WMV 音频格式:MP3、AAC、M4A 图片格式:JPG、PNG 视频编码:H264、WMV、MPEG4 音频编码:MP3、AAC
- 输出规范:
视频格式:MP4、MOV 视频编码:H264 音频编码:AAC
2. 模块结构
剪辑SDK核心模块包括剪辑工程、片段、音频、效果、播放器等。
剪辑工程是SDK中最基础的模块,它负责生成、保存并维护SDK引擎剪辑的上下文环境。片段是工程的基础,是导出视频的组成元素。效果包括贴纸、画中画、字幕、特效、水印、马赛克等,各种效果、音频和片段共同组合形成最终的视频输出。片段上可以添加各种滤镜,片段之间可以设置不同的转场效果。
3. 图层轨道
效果和音频可以在指定区间设置自己的图层(水印和背景音乐除外),高图层的效果可以对低图层的效果起作用或遮挡低图层效果。当两个效果在同一图层时,如果出入点时间不覆盖,则不互相影响;如果出入点时间覆盖,则覆盖时间区间的效果将无法预期。所以尽量给每个效果设定独立的图层,以免最终视频效果不符合预期。
图层限制区间: 音效/录音图层:[10,10000),左边闭区间,右边开区间。 效果图层:[10000,1000000),左边闭区间,右边开区间。(贴纸、字幕、画中画、特效、马赛克)
例: 1)贴纸1位于图层100000,贴纸2位于图层90000。如果贴纸1和贴纸2的位置和时间相同,则贴纸1会遮挡贴纸2。 2)特效1位于图层100000,贴纸1位于图层90000,贴纸2位于图层110000。如果特效1、贴纸1和贴纸2的时间相同,则特效对贴纸1产生影响,对贴纸2无影响。
4. 区间Range相关:
srcRange:源文件区间,视频源文件选择的时间区间。trimRange:裁剪区间,裁剪片段的起始点和长度。destRange:出入区间,效果在工程上的起始点和长度。
5. 坐标系:
剪辑中使用的坐标系,统一使用视频流(stream)的坐标系,即视频流的左上角为(0, 0),右下角为(stream.width,stream.height)。角度水平向右为0度,顺时针为增大。
2 运行环境
运行环境如下:iOS 9.0以上
3 前期准备
- 向小影对接人申请license
- 申请最新版本的小影编辑SDK。
三、项目搭建
1.新建工程(如已有工程则无需新建)
(a)选择File->New->Project来新建工程 (b)在工程类型界面选择适合的工程类型,点击“Next” (c)输入工程名,点击“Next” (d)输入工程路径,点击“Create”
2. 禁用Bitcode
(a)在工程设置界面,选择“构建设置”。 (b)在搜索框输入“bitcode”。 (c)在“启用Bitcode”选项卡中选择“No”
3. 添加SDK
在Podfile文件中添加pod 'QVEditorKit'
然后执行pod update
3. 剪辑SDK初始化
QVEditor是趣维SDK的初始化类。 QVEditor初始化代码如下:
//editor sdk 初始化
QVEditorConfiguration *editorConfig = [[QVEditorConfiguration alloc] init];
editorConfig.licensePath = [[NSBundle mainBundle] pathForResource:@"license" ofType:@"txt"];
editorConfig.defaultTemplateVersion = 1;//默认是1 如果有升级默认素材 往上升级
editorConfig.corruptImgPath = [[NSBundle mainBundle] pathForResource:@"vivavideo_default_corrupt_image" ofType:@"png"];
[QVEditor initializeWithConfig:editorConfig delegate:self];
2.1.2 QVEditorConfiguration类 QVEditorConfiguration是初始化配置参数类
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
licensePath | 证书路径 | NSString | 是 |
corruptImgPath | clip错误时显示图片的地址。如相册的图片被删除或者上传到iCloud等 | NSString | 是 |
isUseStuffClip | 是否末尾补黑帧,默认false(详见【高级玩法-自由黑帧模式】章节说明) | BOOL | 非 |
defaultTemplateVersion | 默认素材的版本 如果有升级素材 需要修改版本号 加1向上即可 默认值是1 | NSInteger | 非 |
2.1.3 QVEngineDataSourceProtocol协议 QVEngineDataSourceProtocol提供用户实现设置语言代码、及主题的转录。 代码如下
/// 可选参数 默认获取系统的语言编码
- (NSString *)languageCode {
return @"zh-Hans";
}
/// 主题的字幕的转译
/// @param textPrepareMode 根据textPrepareMode类型设置参数
- (QVTextPrepareModel *)textPrepare:(QVTextPrepareMode)textPrepareMode {
QVTextPrepareModel *textModel = [QVTextPrepareModel new];
if (QVTextPrepareModeLocation == textPrepareMode) {
textModel.location = @"location";
}
return textModel;
}
四、素材管理开发接入
1. 素材安装
- 默认的本地素材和引擎的模板安装
1.在工程目录下建立private实际目录文件夹的名字一定要是private这个名字
2.引擎的模板放在Engine目录下 此目录可自定义
3.将默认的本地素材放在DefaultTemplate目录下 此目录可自定义
/** 安装单个素材文件 */
[[XYTemplateDataMgr sharedInstance] install:strTemplateFile];
2. 素材信息查询
/**
* 通过素材id查询素材信息
*/
XYTemplateItemData *itemData = [[XYTemplateDataMgr sharedInstance] getByID:ttId]
/**
* 通过素材路径查询素材信息
*/
XYTemplateItemData *itemData = [[XYTemplateDataMgr sharedInstance] getByPath:xytPath]
XYTemplateItemData参数说明:
名称 | 解释 | 类型 |
---|---|---|
lID | 素材id | NSInteger |
strPath | 素材路径 | NSString |
strTitle | 素材名称 | NSString |
五、剪辑功能开发接入
- taskID 操作ID说明
- taskID是每个操作的唯一ID
- 与runTask配合使用,每次runTask都需要传递是什么操作,如添加主题
// themePath表示主题素材路径
XYStoryboardModel *sbModel = [XYEngineWorkspace stordboardMgr].currentStbModel;
sbModel.taskID = XYCommonEngineTaskIDStoryboardAddTheme;
sbModel.themePath = themePath;
[[XYEngineWorkspace stordboardMgr] runTask:sbModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
效果分类groupId说明
typedef NS_ENUM(MDWord, XYCommonEngineGroupID) {
XYCommonEngineGroupIDBgmMusic = GROUP_ID_BGMUSIC,//背景音乐分类
XYCommonEngineGroupIDDubbing = GROUP_ID_DUBBING,//音效分类
XYCommonEngineGroupIDRecord = GROUP_ID_RECORD,//录音分类
XYCommonEngineGroupIDSticker = GROUP_STICKER,//贴纸
XYCommonEngineGroupIDMosaic = GROUP_ID_MOSAIC,//马赛克
XYCommonEngineGroupIDWatermark = GROUP_ID_WATERMARK,//水印
XYCommonEngineGroupIDText = GROUP_TEXT_FRAME,//字幕
XYCommonEngineGroupIDCollage = GROUP_ID_COLLAGE,//画中画
XYCommonEngineGroupIDAnimatedFrame = GROUP_ANIMATED_FRAME,//特效 全屏的特效。
XYCommonEngineGroupIDColorFilter = GROUP_IMAGING_EFFECT,//调色滤镜
XYCommonEngineGroupIDThemeFilter = GROUP_ID_THEME_FILTER,//主题滤镜group
XYCommonEngineGroupIDFXFilter = GROUP_ID_FX_FILTER,//特效滤镜。
};
1. 剪辑工程
创建、保存和加载工程
加入工程如果失败 需要处理错误吗 error.code
错误码说明
typedef NS_ENUM(UInt64, XYTaskLoadProjectErrorCode) {
/// 素材丢失
XYTaskLoadProjectStateTemplateMissing = QVET_ERR_COMMON_TEMPLATE_MISSING;
/// 镜头源文件丢失
XYTaskLoadProjectStateClipFileMissing = QVET_ERR_COMMON_PRJLOAD_CLIPFILE_MISSING;
};
/**
* 创建新的工程
*/
XYQprojectModel *newProject = [[XYQprojectModel alloc] init];
newProject.taskID = XYCommonEngineTaskIDQProjectCreate;
[[XYEngineWorkspace projectMgr] runTask:newProject completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
/**
* 加载工程
*/
XYQprojectModel *newProject = [[XYQprojectModel alloc] init];
newProject.prjFilePath = @"draftProjectFilePath"//保存工程的路径
newProject.taskID = XYCommonEngineTaskIDQProjectLoadProject;
[[XYEngineWorkspace projectMgr] runTask:newProject completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
/**
* 保存工程
*/
XYQprojectModel *newProject = [[XYQprojectModel alloc] init];
newProject.prjFilePath = @"draftProjectFilePath"//保存工程的路径
newProject.taskID = XYCommonEngineTaskIDQProjectSaveProject;
[[XYEngineWorkspace projectMgr] runTask:newProject completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
工程删除
方式一
/**
* 删除工程
*/
XYQprojectModel *project = [[XYQprojectModel alloc] init];
project.prjFilePath = projectFilePath;
project.taskID = XYCommonEngineTaskIDQProjectRemoveProject;
[[XYEngineWorkspace projectMgr] runTask:project];
2. 播放器
播放器 XYPlayerView类 用于播放预览剪辑后的视频,其中包含属性streamSize,如下:
@interface XYPlayerView : UIView
@property (nonatomic, assign) CGSize streamSize;
这个streamSize是播放器中引擎内容真正渲染的区域,引擎的坐标都相对于这个区域来计算,这个区域的位置是相对于XYPlayerView的位置居中的,如计算区域手势可通过这里转换得到,图层结构如图所示:蓝色边框区域为引擎渲染区域,灰色边框区域为XYPlayerView区域,其中引擎渲染蓝色区域相对XYPlayerView灰色边框居中
1)在工程加载成功后,可以绑定工程和播放器,代码如下:
XYPlayerView *editorPlayerView = [[XYPlayerView alloc] initWithFrame:CGRectMake(0, 0, wdith, height)];
[editorPlayerView addPlayDelegate:self];//设置播放器回调的代理
editorPlayerView.backgroundColor = [UIColor blackColor];
[appView addSubview:editorPlayerView];
[editorPlayerView refreshWithConfig:^XYPlayerViewConfiguration *(XYPlayerViewConfiguration *config) {
config = [XYPlayerViewConfiguration currentStoryboardSourceConfig];
config.playViewSize = playSize;
return config;
}];
2)播放回调,代码如下:
#pragma mark - 播放器的回调
- (void)playbackStateCallBack:(XYPlayerCallBackData *)playbackData {
if ((playbackData.state == XYPlayerStatePaused
|| playbackData.state == XYPlayerStateStopped)) {
//暂停 和 停止
}
NSInteger seekPos = playbackData.position;//当前的播放时间点
}
3)暂停播放,代码如下:
[]editorPlayerView pause]
4)播放,代码如下:
[]editorPlayerView play]
5)seek操作,代码如下:
NSInteger pos = 1000;
[editorPlayerView seekToPosition:pos async:NO];
6)设置播放时间区域,代码如下:
XYVeRangeModel *range = [XYVeRangeModel VeRangeModelWithPosition:0 length:1000];
[editorPlayerView setPlaybackRange:range];
7)获取播放时间区域
[editorPlayerView getPlaybackRange];
8)判断是否在播放,具体代码:
BOOL isPlaying = [editorPlayerView isPlaying]
9)获取播放的真实区域大小,具体代码:
editorPlayerView.playStreamBounds
10)设置播放器声音,具体代码:
[]editorPlayerView setVolume:1];
11 监听播放回调,具体代码:
[editorPlayerView addPlayDelegate:self];//设置播放器回调的代理
12)移除监听播放回调,具体代码:
[editorPlayerView removePlayDelegate:self]//移除监听播放回调
- 销毁播放器
/// 销毁
- (void)destroySource;
3. 获取工程相关信息
@interface XYClipOperationMgr : XYOperationMgrBase
/** 获取所有clip信息 */
@property (nonatomic, copy) NSArray <XYClipModel *> *clipModels
/** 通过当前时间,获取Clip */
- (XYClipModel *)fetchClipModelWithPosition:(NSInteger)position;
XYEffectOperationMgr信息
@interface XYEffectOperationMgr : XYOperationMgrBase
/** 获取所有效果的信息 */
@property (nonatomic, copy) NSArray <XYEffectModel *> *allEffects;
/** 根据groupID 获取效果列表 */
- (NSArray <XYEffectModel *> *)effectModels:(XYCommonEngineGroupID)groupType;//根据groupID 获取效果列表
/** 根据时间和位置来获取效果 */
- (XYEffectModel *)fetchEffectModelOnTopByTouchPoint:(CGPoint)touchPoint seekPosition:(NSInteger)seekPosition;
数据结构说明
- 片段Clip相关
XYClipModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
identifier | clip的唯一识别码 | NSString |
clipType | 类型{@see XYCommonEngineClipModuleType} | XYCommonEngineClipModuleType |
clipFilePath | 片段文件路径 | NSString |
sourceVeRange | 源文件区间 | XYVeRangeModel |
trimRange | 片段裁切区间 | XYVeRangeModel |
destRange | 片段出入区间 | XYVeRangeModel |
cropRect | 裁剪区域 | CGRect |
sourceSize | 源视频宽高,相对streamSize的尺寸 | CGSize |
rotation | 旋转角度 | NSInteger |
isMute | 是否静音 | BOOL |
volumeValue | 音量,默认100 范围 0- 200 | CGFloat |
voiceChangeValue | 变声,-60~60,正常0。{@see XYDftSoundTone}类中有提供的特定音调 | CGFloat |
speedValue | 变速值,默认1.0f,设置变速时,也会对音调产生影响 | CGFloat |
iskeepTone | 是否保持原声调 | BOOL |
mirrorMode | 镜像{@see XYClipMirrorMode} | XYClipMirrorMode |
isReversed | 是否倒放 | BOOL |
clipPropertyData | 图片动画 clip的手势 背景颜色 背景图片 属性 {@see XYEffectPropertyData} | XYEffectPropertyData |
clipEffectModel | 转场,null表示无。当前片段和下一个片段的转场数据{@see XYClipEffectModel} | CrossInfo |
clipEffectModel | 滤镜信息,null表示无{@see XYClipEffectModel} | XYClipEffectModel |
clipEffectModel | 特效滤镜信息,null表示无{@see XYClipEffectModel} | XYClipEffectModel |
adjustItems | 参数调节信息{@see XYAdjustItem} | NSArray <XYAdjustItem *> |
XYEffectPropertyData参数说明:
名称 | 解释 | 类型 |
---|---|---|
scale | 缩放 缩放是相对原始尺寸的比例 没有做缩放默认值是1 | CGFloat |
angleZ | 旋转角度 值范围是0-3360 | NSInteger |
shiftX | X轴移动 没做移动默认值都是1,shiftX 是移动的X除以播放器的的宽(streamSize.width) + 原来的shiftX | CGFloat |
shiftX | Y轴移动 没做移动默认值都是1,shiftX 是移动的X除以播放器的的宽(streamSize.width) + 原来的shiftX | CGFloat |
XYCommonEngineClipModuleType参数说明:
名称 | 解释 |
---|---|
XYCommonEngineClipModuleImage | 图片clip |
XYCommonEngineClipModuleVideo | 视频clip |
XYCommonEngineClipModuleGif | gif clip |
XYCommonEngineClipModuleThemeCoverFront | 主题片头 |
XYCommonEngineClipModuleThemeCoverBack | 主题片尾 |
XYClipEffectModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
effectConfigIndex | 有些素材包含多种效果,表示使用第几个效果,默认0 | NSInteger |
colorFilterFilePath | 调色滤镜的路径 | NSString |
colorFilterAlpha | 调色程度值 滤镜调节 范围 0-1 | colorFilterAlpha |
fxFilterFilePath | 特效滤镜的路径 | NSString |
fxFilterAlpha | 特效程度值 滤镜调节 范围 0-1 | colorFilterAlpha |
effectTransFilePath | 转场的路径 | NSString |
transDuration | 转场时长 | NSInteger |
XYAdjustItem参数说明:
名称 | 解释 | 类型 |
---|---|---|
adjustType | 调节类型,共有类型为(亮度、对比度、饱和度、锐度、色温、暗角、色调、阴影、高光、褪色、噪点) | XYCommonEngineAdjustType |
dwID | 唯一id | NSInteger |
dwCurrentValue | 当前的值 0~100,默认50 | NSInteger |
XYCommonEngineClipModuleType参数说明:
名称 | 解释 |
---|---|
XYCommonEngineClipModuleImage | 图片clip |
XYCommonEngineClipModuleVideo | 视频clip |
XYCommonEngineClipModuleGif | gif clip |
XYCommonEngineClipModuleThemeCoverFront | 主题片头 |
XYCommonEngineClipModuleThemeCoverBack | 主题片尾 |
- 效果相关信息
XYEffectModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
taskID | 执行的操作类型 | XYCommonEngineTaskID |
groupID | effect的类型 | XYCommonEngineGroupID |
filePath | 素材资源路径 | NSString |
sourceVeRange | 效果选取的时长,可以选取某一部分,默认(0, -1) | VXYVeRangeModeleRange |
destVeRange | effect在storyboard上的 mVeRange(起始点,时长) | XYVeRangeModel |
trimVeRange | 对效果时长的裁剪 | destVeRange |
layerID | 效果的层级信息,是一个浮点数,数字越大 层级越高 | CGFloat |
horizontalPosition | 层级 范围 [0 - max]的整数 | NSInteger |
layerIdSetBySelf | 业务自己直接设置layerID 而不通过 horizontalPosition参数来设置 默认通过horizontalPosition 设置layerID | BOOL |
XYEffectAudioModel参数说明:XYEffectAudioModel继承XYEffectModel
名称 | 解释 | 类型 |
---|---|---|
isFadeOutON | 是否开启淡入 | BOOL |
isFadeOutON | 是否开启淡出 | BOOL |
fadeDuration | 渐变时长,0则无效果 | CGFloat |
lyricPath | 歌曲字幕lyric文件路径 | NSString |
lyricTtid | 歌词模板的素材id | NSInteger |
XYEffectVisionModel参数说明:XYEffectVisionModel继承XYEffectModel
名称 | 解释 | 类型 |
---|---|---|
size.width | 宽度 | CGFloat |
size.height | 高度 | CGFloat |
center | 相对于播放界面的中心点坐标 | XYVe3DDataF |
degree | 旋转角度,顺时针 0 - 360 | XYVe3DDataF |
propData | 程度调节,默认1.0,范围 0 -1 | CGFloat |
verticalReversal | 竖直翻转 | BOOL |
horizontalReversal | 水平翻转 | BOOL |
isStaticPicture | 在YES的情况下,该效果将会静态展示 | BOOL |
isInstantRefresh | 在YES的情况下,该效果将会快速刷新 | BOOL |
currentScale | 根据当前宽度和default宽度自动计算当前放大倍数,只读 | CGFloat |
previewDuration | 预览时长 | CGFloat |
volume | 效果的音量(只有特效和视频画中画才有作用) | NSInteger |
overlayInfo | 画中画 透明度 | XYEffectPicInPicOverlayInfo |
maskInfo | 画中画 蒙版 | XYEffectPicInPicMaskInfo |
chromaInfo | 画中画 抠色信息数据(绿幕) | XYEffectPicInPicChromaInfo |
filterInfo | 画中画 滤镜 | XYEffectPicInPicFilterInfo |
fxInfoList | 画中画特效 | NSMutableArray < XYEffectPicInPicSubFx > |
adjustItems | 画中画 参数调节 | NSArray < XYAdjustItem > |
XYEffectPicInPicOverlayInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
overlayPath | 混合模式素材路径 | NSString |
level | 混合程度,改参数和透明度一个效果,0~100 | CGFloat |
XYEffectPicInPicMaskInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
maskType | 蒙版类型 | XYEffectMaskType |
centerPoint | 中心点 在streamSize的坐标系中,中心点尽量保持在素材位置内 | CGPoint |
radiusX | 水平方向半径,在streamSize的坐标系中 | CGFloat |
radiusY | 垂直方向半径,在streamSize的坐标系中 | CGFloat |
rotation | 旋转角度, 0~360 | CGFloat |
softness | 柔化程度,取值范围:[0~10000] | NSInteger |
reverse | 是否反选 | BOOL |
XYEffectPicInPicChromaInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
enable | 是否开启 | BOOL |
colorHexValue | 抠色的颜色值,如0xFFFFFF | NSInteger |
accuracy | 抠色的精度(0~100) | CGFloat |
isAutoMaskBgColor | 是否自动去除画中画纯背景色 | BOOL |
selectPoint | 画中画选中的坐标,相对画中画的坐标 | CGPoint |
XYEffectPicInPicFilterInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
filterPath | 滤镜路径 | NSString |
filterLevel | 滤镜程度,0~100 | NSInteger |
XYEffectPicInPicSubFx参数说明:
名称 | 解释 | 类型 |
---|---|---|
subFxPath | 子特效素材路径 | NSString |
subType | 子特效索引,不可修改,范围1000 - 2000 | NSInteger |
destRange | 子特效出入点区间,相对效果的时间 | XYVeRangeModel |
XYEffectVisionTextModel参数说明:XYEffectVisionTextModel继承XYEffectVisionModel
名称 | 解释 | 类型 |
---|---|---|
isAnimatedText | 是否动画字幕 | BOOL |
textTransparency | 字幕不透明度,全透明0,不透明100 | NSInteger |
useCustomTextInfo | 第一次添加,如果这个值是YES,则文字大小、颜色、字体、位置、阴影、描边、描边大小、对齐方式,都用外面传进来的值,否则用模板里的信息 | BOOL |
multiTextList | 多行字幕标签信息列表,单行字幕数组里只有一个 | XYEffectVisionSubTitleLabelInfoModel |
XYEffectVisionSubTitleLabelInfoModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
text | 字幕当前文字 | NSString |
textFontName | 字幕字体名称 | NSString |
textColor | 字幕颜色 | UIColor |
textLine | 字幕行数 | NSInteger |
textAlignment | 对齐方式 | XYEffectVisionTextAlignment |
textStrokeColor | 描边颜色 | UIColor |
textShadowColor | 阴影颜色 | UIColor |
textStrokeWPercent | 描边粗细,引擎那边限制可以认为是0.0~1.0,但取值范围建议 0.0~0.5 | CGFloat |
textShadowBlurRadius | 阴影模糊程度:必须>=0 | CGFloat |
textShadowXShift | 阴影X轴偏移 | CGFloat |
textShadowXShift | 阴影Y轴偏移 | CGFloat |
textRegionRect | 文字部分相对于整个字幕尺寸的万分比rect | CGRect |
XYEffectKeyFrameInfo参数说明:(由于功能复杂,后期可能调整数据结构)
名称 | 解释 | 类型 |
---|---|---|
positionList | 位置关键帧列表 {@see XYKeyPosInfo} | KeyPosInfo |
scaleList | 缩放关键帧列表 {@see XYKeyScaleInfo} | KeyScaleInfo |
rotationList | 旋转角度关键帧列表{@see XYKeyRotationInfo} | KeyRotationInfo |
alphaList | 不透明度关键帧列表{@see XYKeyAlphaInfo} | KeyAlphaInfo |
XYBaseKeyFrame参数说明:
名称 | 解释 | 类型 |
---|---|---|
keyFrameType | 关键帧类型 | XYKeyFrameType |
relativeTime | 相对于效果入点的时间 | NSInteger |
isCurvePath | 关键帧是否曲线路径 | BOOL |
mKeyBezierCurve | 关键帧缓动贝塞尔曲线点{@see XYKeyBezierCurve} | XYKeyBezierCurve |
XYKeyFrameType参数说明:
名称 | 解释 |
---|---|
XYKeyFrameTypePosition | 位置关键帧 |
XYKeyFrameTypeRotation | 旋转关键帧 |
XYKeyFrameTypeScale | 缩放关键帧 |
XYKeyFrameTypeAlpha | 透明度关键帧 |
KeyBezierCurve参数说明:
名称 | 解释 | 类型 |
---|---|---|
bezierCurveId | 贝塞尔缓动曲线Id,业务如果需要可以自己定义一个值传进来 | NSInteger |
start | 贝塞尔缓动曲线起点 | CGPoint |
stop | 贝塞尔缓动曲线终点 | CGPoint |
c0 | 贝塞尔缓动节点1 | CGPoint |
c1 | 贝塞尔缓动节点2 | CGPoint |
XYKeyPosInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
centerPoint | 在streamSize的坐标系中的中心位置 | CGPoint |
KeyScaleInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
widthScale | 宽相对于原始的宽的放大倍数 | CGFloat |
heightScale | 高相对于原始的高的放大倍数 | CGFloat |
KeyRotationInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
rotation | 旋转角度, 0~360 | CGFloat |
KeyAlphaInfo参数说明:
名称 | 解释 | 类型 |
---|---|---|
alpha | 不透明度 0~100 | NSInteger |
- 项目信息 XYStoryboardModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
outPutResolution | 分辨率 | CGSize |
videoDuration | 视频总时长 | NSInteger |
themeTextList | 主题字幕列表 | TextInfo |
themePath | 主题素材路径 | NSArray |
themeID | 主题id | NSInteger |
ratioValue | 视频比例 | CGFloat |
XYClipOperationMgr信息
4. 主题剪辑功能接口
1)应用/切换主题
// themePath表示主题素材路径
XYStoryboardModel *sbModel = [XYEngineWorkspace stordboardMgr].currentStbModel;
sbModel.taskID = XYCommonEngineTaskIDStoryboardAddTheme;
sbModel.themePath = themePath;
[[XYEngineWorkspace stordboardMgr] runTask:sbModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
2)恢复主题背景音乐设置
// 该操作将删除自己应用的背景音乐,切回主题自带的背景音乐
XYEffectModel *effectModel = [[XYEffectModel alloc] init];
effectModel.taskID = XYCommonEngineTaskIDEffectResetThemeAudio;
effectModel.groupID = XYCommonEngineGroupIDBgmMusic;
[[XYEngineWorkspace effectMgr] runTask:effectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
3)修改主题关联字幕文本
XYStoryboardModel *storyboardModel = [XYEngineWorkspace stordboardMgr].currentStbModel;
//获取所有的字幕
[storyboardModel.themeTextList enumerateObjectsUsingBlock:^(TextInfo * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.text = @"修改字幕";
}];
[XYEngineWorkspace stordboardMgr].currentStbModel.taskID = XYCommonEngineTaskIDStoryboardUpdateThemeText;
[[XYEngineWorkspace stordboardMgr] runTask:storyboardModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
TextInfo 参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
text | 字幕文本 | String | 必须 |
5. Clip剪辑功能接口
1)添加
XYClipModel *clipModel = [[XYClipModel alloc] init];
clipModel.sourceVeRange.dwPos = 0;
clipModel.sourceVeRange.dwLen = duration;
clipModel.clipFilePath = [XYClipModel getClipFilePathForEngine:phAsset];
clipModel.rotation = rotation;
clipModel.clipIndex = idx;//idx 需要添加顺序 如第一个是0 第二是1 ....
[clipArr addObject:clipModel];
XYClipModel *taskModel = [[XYClipModel alloc] init];
taskModel.taskID = XYCommonEngineTaskIDClipAddClip;
taskModel.clipModels = clipArr;
[[XYEngineWorkspace clipMgr] runTask:taskModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
}
XYClipModel参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
clipFilePath | 文件地址 如果是绝对路径直接赋值,如果是PHAsset 通过getClipFilePathForEngine 此法获取路径 | NSString | 必须 |
sourceVeRange | 源的长度 | XYVeRangeModel | 非必须 |
trimVeRange | 切入点 | XYVeRangeModel | 非必须 |
cropRect | 裁切区域 | CGRect | 非必须 |
rotation | 旋转角度 | NSInteger | 非必须 |
filterFilePath | 滤镜 | NSString | 非必须 |
2)复制 |
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
XYClipModel *newClipModel = [[XYClipModel alloc] init];
clipModel.duplicateClipModel = newClipModel;
clipModel.taskID = XYCommonEngineTaskIDClipDuplicate;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
3)删除
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipDelete;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
4)排序
XYClipModel *clipModel = [XYClipModel new];
clipModel = fromIndex;
clipModel = toIndex;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
5)静音
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipMuteState;
clipModel.isMute = isMute;
[[XYEngineWorkspace clipMgr] runTaskToMore:clipModel.isMute];
6)音量
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipUpdateVolume;
clipModel.volumeValue = volumeValue;
[[XYEngineWorkspace clipMgr] runTaskToMore:clipModel];
7)变声
// clipIndex表示第几个片段,从0开始
// voiceChangeValue表示音调,从-60~60,{@see XYDftSoundTone}枚举中有提供的特定音调
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.voiceChangeValue = value;
[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
8)镜像
// clipIndex表示第几个片段,从0开始
YClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
XYClipMirrorMode mirrorMode = XYClipMirrorModeX;
clipModel.mirrorMode = mirrorMode;
clipModel.taskID = XYCommonEngineTaskIDClipMirror;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
clipModel.mirrorMode参数说明:
名称 | 解释 |
---|---|
XYClipMirrorModeNormal | 正常 |
XYClipMirrorModeX | 沿X方向镜像 |
XYClipMirrorModeY | 沿Y方向镜像 |
XYClipMirrorModeXY | 沿XY方向镜像 |
9)旋转
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipRotation;
clipModel.rotation = rotation;
[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
10)分割
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.splitClipPostion = seekPosition;
clipModel.taskID = XYCommonEngineTaskIDClipSplit;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
11)变速
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipSpeed;
clipModel.speedValue = videoSpeedChangeValue;
clipModel.iskeepTone = NO;//是否保持原声调
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
12)倒放
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipReverse;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
13)比例
XYStoryboardModel *sbModel = [XYEngineWorkspace stordboardMgr].currentStbModel;
sbModel.taskID = XYCommonEngineTaskIDStoryboardRatio;
sbModel.ratioValue = ratioValue;
[[XYEngineWorkspace stordboardMgr] runTask:sbModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
14)裁切
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipCrop;
clipModel.cropRecte =cropRect;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
15)视频裁剪
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipTrim;
clipModel.trimVeRange = trimVeRange;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
16)图片时长
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipTrim;
clipModel.trimVeRange = trimVeRange;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
17)图片动画
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipPhotoAnimation;
clipModel.clipPropertyData.isAnimationON = !clipModel.clipPropertyData.isAnimationON;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
18)背景
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipBackgroundBlur;
clipModel.clipPropertyData = clipPropertyData;
XYEffectPropertyData参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
fitType | 背景类型 | XYCommonEngineRatioFitType | 非必须 |
backgroundColorList | 颜色,最多可以支持三色渐变 | int[] 十六进制的颜色值 | 非必须 |
linearGradientAngle | 颜色渐变角度:默认0-水平方向。0~360 | NSInteger | 非必须 |
backgroundBlurValue | 模糊程度:0~100 | CGFloat | 非必须 |
backImagePath | 图片背景,自定义图片背景使用 | String | 非必须 |
taskID参数设置
/**
* 模糊背景
*/
taskID = XYCommonEngineTaskIDClipBackgroundBlur;
/**
* 图片背景
*/
taskID = XYCommonEngineTaskIDClipBackgroundImage;
/**
* 颜色背景
*
* @param backgroundColorList 最多支持三色。渐变色 0-1-2
* @param linearGradientAngle 渐变色方向。默认为水平方向,取值范围:0~360,对应的角度:0~360,单位为°
*/
taskID = XYCommonEngineTaskIDClipBackgroundColor;
19)位置修改
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipGesturePan;
XYEffectPropertyData * clipPropertyData = clipModel.clipPropertyData;
clipPropertyData.centerPosX = centerPosX;
clipPropertyData.centerPosY = centerPosY;
taskID参数设置
/**
* 移动
*/
taskID = XYCommonEngineTaskIDClipGesturePan;
/**
* 缩放
*/
taskID = XYCommonEngineTaskIDClipGesturePinch;
/**
* 旋转
*/
taskID = XYCommonEngineTaskIDClipGestureRotation;
20)镜头参数调节
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
// idx adjustItems数组中取一种参数调节对象
XYAdjustItem *adjustItem = clipModel.adjustItems[idx];
adjustItem.dwCurrentValue = 0-100;
[[XYEngineWorkspace clipMgr] runTaskToMore:clipModel];
adjustItem参数说明:
名称 | 解释 | 类型 |
---|---|---|
adjustType | 调节类型,共有类型为(亮度、对比度、饱和度、锐度、色温、暗角、色调、阴影、高光、褪色、噪点) | XYCommonEngineAdjustType |
dwID | 唯一id | NSInteger |
dwCurrentValue | 当前的值 0~100,默认50 | NSInteger |
21)滤镜
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.groupID = XYCommonEngineGroupIDColorFilter;
clipModel.taskID = XYCommonEngineTaskIDClipFilterAdd;
clipModel.clipEffectModel.colorFilterFilePath = filterPath;
clipModel.clipEffectModel.colorFilterAlpha = colorFilterAlpha;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
clipEffectModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
colorFilterFilePath | 滤镜路径 | NSString |
colorFilterAlpha | 滤镜程度, 0~1.0 | CGFloat |
taskID | XYCommonEngineTaskIDClipFilterAdd(添加滤镜), XYCommonEngineTaskIDClipFilterUpdateAlpha(修改滤镜程度 | XYCommonEngineTaskID |
22)特效滤镜
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.groupID = XYCommonEngineGroupIDFXFilter;
clipModel.taskID = XYCommonEngineTaskIDClipFilterAdd;
clipModel.clipEffectModel.fxFilterFilePath = fxFilterFilePath;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
clipEffectModel 参数说明:
名称 | 解释 | 类型 |
---|---|---|
fxFilterFilePath | 特效滤镜路径 | NSString |
23)转场
// clipIndex表示第几个片段,从0开始
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipTransition;
clipModel.clipEffectModel.effectTransFilePath = effectTransFilePath;
effectModel.transDuration = [XYCommonEngineRequest requestEffectTansDuration:effectModel.effectTransFilePath];
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
23)修改转场时长
// clipIndex表示第几个片段,从0开始
BOOL editable = [XYCommonEngineRequest requestTranEditable:clipModel.clipEffectModel.effectTransFilePath];//判断是否可以修改转场时长
if (editable) {
XYClipModel *clipModel = [[XYEngineWorkspace clipMgr] fetchClipModelObjectAtIndex:clipIndex];
clipModel.taskID = XYCommonEngineTaskIDClipTransition;
clipModel.clipEffectModel.effectTransFilePath = effectTransFilePath;
effectModel.transDuration = transDuration;
[[XYEngineWorkspace clipMgr] runTask:clipModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
}
clipEffectModel参数说明:
名称 | 解释 | 类型 |
---|---|---|
effectTransFilePath | 转场路径 | NSString |
transDestRange | //转场在视频中的range | XYVeRangeModel |
effectConfigIndex | 转场效果样式,有些素材包含多种效果,表示使用第几个效果,默认0 | NSInteger |
6. Effect剪辑功能接口
效果目前分为两大类: 1.声音类的 2.视觉类的
- 声音类 6.1.1 添加
// groupId为effect的类型
// effectAudioModel需要的effect {@see XYEffectAudioModel}
XYEffectAudioModel *effectAudioModel = [[XYEffectAudioModel alloc] init];
effectModel.taskID = XYCommonEngineTaskIDEffectAudioAdd;
effectModel.groupID = XYCommonEngineGroupIDBgmMusic;
effectModel.title = @"背景音乐1";
effectModel.filePath = filePath;
XYVeRangeModel *sourceVeRange = [XYVeRangeModel VeRangeModelWithPosition:0 length:5000];
effectModel.sourceVeRange = sourceVeRange;
XYVeRangeModel *trimVeRange = [XYVeRangeModel VeRangeModelWithPosition:0 length:5000];
effectModel.trimVeRange = trimVeRange;
NSInteger dwPos = 0;
NSInteger dwLen = 5000;
XYVeRangeModel *destVeRange = [XYVeRangeModel VeRangeModelWithPosition:dwPos length:dwLen];
effectModel.destVeRange = destVeRange;
[[XYEngineWorkspace effectMgr] runTask:effectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
XYEffectAudioModel参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
taskID | 执行的操作类型 | XYCommonEngineTaskID | 必须 |
groupID | effect的类型 | XYCommonEngineGroupID | 必须 |
filePath | 素材资源路径 | NSString | 必须 |
sourceVeRange | 效果选取的时长,可以选取某一部分,默认(0, -1) | VXYVeRangeModeleRange | 非必须 |
destVeRange | effect在storyboard上的 mVeRange(起始点,时长) | XYVeRangeModel | 非必须 |
trimVeRange | 对效果时长的裁剪 | destVeRange | 非必须 |
layerID | 效果的层级信息,是一个浮点数,数字越大 层级越高 | CGFloat | 非必须 |
isFadeOutON | 是否开启淡入 | BOOL | 非必须 |
isFadeOutON | 是否开启淡出 | BOOL | 非必须 |
fadeDuration | 渐变时长,0则无效果 | CGFloat | 必须 |
6.1.2 复制 |
// groupID为effect的类型
// effectIndex为同类型中第几个效果
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectAudioModel *duplicateEffectModel = [[XYEffectAudioModel alloc] init];
duplicateEffectModel.title = currentEffectModel.title;
XYVeRangeModel *destVeRange = [XYVeRangeModel VeRangeModelWithPosition:startPosition length:valideLength];
duplicateEffectModel.destVeRange = destVeRange;
currentEffectModel.duplicateEffectModel = duplicateEffectModel;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioDuplicate;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.3 删除
// groupID为effect的类型
// effectIndex为同类型中第几个效果
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioDelete;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.4 裁切区间
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// trimRange表示裁切区间
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.trimVeRange = currentEffectModel.trimVeRange;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioUpdateTrimRange;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.5 出入区间
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// destRange表示切入切出区间
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.destRange = destRange;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioUpdateDestRange;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.6 源文件区间
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// sourceVeRange表示切入切出区间
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.sourceVeRange = sourceVeRange;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioUpdateSourceVeRange;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.7 音量
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// volumeValue表示声音大小值
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.volumeValue = volumeValue;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectUpdateAudioVolume;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.8 音频渐入渐出
// groupID为effect的类型
// effectIndex为同类型中第几个效果
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.isFadeOutON = isFadeOutON;
currentEffectModel.fadeDuration = fadeDuration;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioFadeOut;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.9 音频循环
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// isRepeatON表示是否开启循环
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.isRepeatON = isRepeatON;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioUpdateRepeat;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.10 音频变声
// groupID为effect的类型
// effectIndex为同类型中第几个效果
// voiceChangeValue表示音调,从-60~60,
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.voiceChangeValue = voiceChangeValue;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioVoiceChange;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.1.11 替换音频
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// filePath表示音频路径
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.filePath = filePath;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioReplace;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
6.1.12 歌词文件生成字幕
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// lyric表示歌曲字幕lyric文件路径
// lyricTtid表示歌词模板的素材id
XYEffectAudioModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.lyric = lyric;
currentEffectModel.lyricTtid = lyricTtid;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectAudioLyic;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
- 视觉类的分为普通类型和字幕类型两种,字幕继承了普通类型的属性 普通类型的,修改字幕对应的普通属性,只需将taskID 改成对应的字幕的taskID即可
6.2.1 XYEffectVisionModel参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
defaultWidth | 默认宽度,素材中提取 | CGFloat | 非必须 |
defaultHeight | 默认高度,素材中提取 | CGFloat | 非必须 |
size.width | 宽 | CGFloat | 必须 |
size.height | 高 | CGFloat | 必须 |
degree | 旋转角度, 0~360 | XYVe3DDataF | 非必须 |
horizontalReversal | 水平反转 | BOOL | 非必须 |
verticalReversal | 垂直反转 | BOOL | 非必须 |
centerPoint | 相对于播放StreamSize的中心点坐标 | CGPoint | 必须 |
alpha | 透明度,默认1.0 | CGFloat | 非必须 |
volume | 透明度,默认1.0 | CGFloat | 非必须 |
isStaticPicture | 在YES的情况下,该效果将会静态展示 | BOOL | 非必须 |
layerID | /效果的层级信息,是一个浮点数,数字越大 层级越高 值范围 10000 - 9999998 | CGFloat | 必须 |
添加
// groupID为effect的类型
// taskID为操作类型
XYEffectVisionModel * visionModel = [XYEffectVisionModel new];
visionModel.taskID = XYCommonEngineTaskIDEffectVisionAdd;
visionModel.groupID = XYCommonEngineGroupIDSticker;
visionModel.filePath = pastePath;
visionModel.isStaticPicture = YES;
NSInteger beginTime = 0;
visionModel.destVeRange = [XYVeRangeModel VeRangeModelWithPosition:beginTime length:length];
[[XYEngineWorkspace effectMgr] runTask:visionModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
6.2.2 复制
// groupID为effect的类型
// effectIndex为同类型中第几个效果
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectVisionModel *duplicateEffectModel = [[XYEffectVisionModel alloc] init];
XYVeRangeModel *destVeRange = [XYVeRangeModel VeRangeModelWithPosition:startPosition length:valideLength];
duplicateEffectModel.destVeRange = destVeRange;
currentEffectModel.duplicateEffectModel = duplicateEffectModel;
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionDuplicate;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.3 删除
// groupID为effect的类型
// effectIndex为同类型中第几个效果
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionDelete;
[[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.4 修改图层
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// layerId表示图层,float类型,各类型的图层有区间限制 值范围 10000 - 9999998
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.layerID = layerID;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.5 裁切区间
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// trimRange表示裁切区间
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.trimVeRange = trimVeRange;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.6 出入区间
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// destRange表示切入切出区间
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.destVeRange = destVeRange;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.7 源文件区间
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// sourceVeRange表示源文件区间信息
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.sourceVeRange = sourceVeRange;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.8 透明度
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// alpha表示透明度,0~1
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.alpha = alpha;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.9 锁定播放器刷新效果,用于实时快速刷新修改的位置,大小,旋转角度等信息
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// isInstantRefresh表示是否锁定
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.centerPoint = centerPoint;
currentEffectModel.isInstantRefresh = isInstantRefresh;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
当需要快速刷新播放器某个效果位置时,需要先锁定该效果,当位置刷新结束后,需要对改效果解锁。
6.2.10 画中画混合模式设置
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// overlayInfo表示混合模式信息 {@see XYEffectPicInPicOverlayInfo}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectPicInPicOverlayInfo *overlayInfo = [[XYEffectPicInPicOverlayInfo alloc] init];
visionModel.overlayInfo = overlayInfo;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicOverlayUpdate;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.11 画中画蒙版设置
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// maskInfo表示混合模式信息 {@see XYEffectPicInPicMaskInfo}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectPicInPicMaskInfo *maskInfo = [[XYEffectPicInPicMaskInfo alloc] init];
visionModel.maskInfo = maskInfo;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicMaskUpdate;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.12 画中画抠色设置(绿幕)
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// visionModel.chromaInfo表示混合模式信息 {@see XYEffectPicInPicChromaInfo}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectPicInPicChromaInfo *chromaInfo = [[XYEffectPicInPicChromaInfo alloc] init];
visionModel.chromaInfo = chromaInfo;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicChromaUpdate;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.13 画中画滤镜设置
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// maskInfo表示混合模式信息 {@see XYEffectPicInPicFilterInfo}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
XYEffectPicInPicFilterInfo *filterInfo = [[XYEffectPicInPicFilterInfo alloc] init];
visionModel.filterInfo = filterInfo;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicFilterUpdate;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.14 画中画参数调节设置
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// adjustItems表示混合模式信息 {@see XYAdjustItem}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
NSArray <XYAdjustItem *> *adjustItems = list;
visionModel.adjustItems = adjustItems;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicSubAdjust;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.14 画中画添加子特效
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// fxInfoList表示混合模式信息 {@see XYEffectPicInPicSubFx}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
NSMutableArray <XYEffectPicInPicSubFx *> fxInfoList = list;
visionModel.fxInfoList = fxInfoList;
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicSubFX;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.15 画中画修改子特效出入点时间区间
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// fxInfoList表示混合模式信息 {@see XYEffectPicInPicSubFx}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
NSMutableArray <XYEffectPicInPicSubFx *> fxInfoList = visionModel.fxInfoList;
fxInfoList enumerateObjectsUsingBlock:^(XYEffectPicInPicSubFx * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.destRange = [XYVeRangeModel VeRangeModelWithPosition:start length:length];
}
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicSubFX;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.16 画中画删除子特效
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// fxInfoList表示混合模式信息 {@see XYEffectPicInPicSubFx}
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
NSMutableArray <XYEffectPicInPicSubFx *> fxInfoList = visionModel.fxInfoList;
fxInfoList enumerateObjectsUsingBlock:^(XYEffectPicInPicSubFx * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.subFxPath = nil;
}
visionModel.taskID = XYCommonEngineTaskIDEffectVisionPinInPicSubFX;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.17 锚点修改
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// anchor锚点,(0,0)为效果的左上角位置,(0.5,0.5)表示效果的中心,(1.0,1.0)表示效果的右下角。默认是(0.5,0.5) 。取值范围是0~1
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.anchor = anchor;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.18 显示静态图片
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// isStaticPicture表示是否显示静态图片
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
currentEffectModel.isStaticPicture = isStaticPicture;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
备注:由于一些动态贴纸/字幕,有效果变化,可以通过该操作,使效果关闭动画显示固定效果。
6.2.19 马赛克模糊程度
// groupId默认为XYCommonEngineGroupIDMosaic
// effectIndex为同类型中第几个效果
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionAdd;
visionModel.filePath = mediaItem.filePath;
visionModel.destVeRange = veRangeModel;
visionModel.propData = 0.5;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
程度调节
// groupId默认为XYCommonEngineGroupIDMosaic
// effectIndex为同类型中第几个效果
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
visionModel.propData = 0.5;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.20 关键帧设置
// groupId为effect的类型
// effectIndex为同类型中第几个效果
// sourceVeRange表示源文件区间信息
XYEffectVisionModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate;
XYEffectKeyFrameInfo *keyFrameInfo = [XYEffectKeyFrameInfo alloc] init];//@see{XYEffectKeyFrameInfo}
currentEffectModel.keyFrameInfo = keyFrameInfo;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6.2.21 设置位置 大小 旋转角度
effectVisionModel.taskID = XYCommonEngineTaskIDEffectVisionUpdate3dInfo;
effectVisionModel.size.x = x;
effectVisionModel.size.y = y;
effectVisionModel.degree.z = z
effectVisionModel.center.x = x;
effectVisionModel.center.y = y;
[[XYEngineWorkspace effectMgr] runTask:effectVisionModel completionBlock:^(BOOL success, NSError * _Nullable error, id _Nullable obj) {
}];
- 字幕
XYEffectVisionTextModel参数说明
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
isAnimatedText | 是否动画字幕 | BOOL | 非必须 |
textTransparency | 字幕不透明度,全透明0,不透明100 | NSInteger | 非必须 |
useCustomTextInfo | 第一次添加,如果这个值是YES,则文字大小、颜色、字体、位置、阴影、描边、描边大小、对齐方式,都用外面传进来的值,否则用模板里的信息 | BOOL | 非必须 |
multiTextList | 多行字幕标签信息列表,单行字幕数组里只有一个 | XYEffectVisionSubTitleLabelInfoModel | 非必须 |
XYEffectVisionSubTitleLabelInfoModel参数说明:
名称 | 解释 | 类型 | 是否必须 |
---|---|---|---|
text | 字幕当前文字 | NSString | 非必须 |
textFontName | 字幕字体名称 | NSString | 非必须 |
textColor | 字幕颜色 | UIColor | 非必须 |
textLine | 字幕行数 | NSInteger | 非必须 |
textAlignment | 对齐方式 | XYEffectVisionTextAlignment | 非必须 |
textStrokeColor | 描边颜色 | UIColor | 非必须 |
textShadowColor | 阴影颜色 | UIColor | 非必须 |
textStrokeWPercent | 描边粗细,引擎那边限制可以认为是0.0~1.0,但取值范围建议 0.0~0.5 | CGFloat | 非必须 |
textShadowBlurRadius | 阴影模糊程度:必须>=0 | CGFloat | 非必须 |
textShadowXShift | 阴影X轴偏移 | CGFloat | 非必须 |
textShadowXShift | 阴影Y轴偏移 | CGFloat | 非必须 |
1)字幕添加
XYEffectVisionTextModel * textModel = [XYEffectVisionTextModel new];
textModel.taskID = XYCommonEngineTaskIDEffectVisionTextAdd;
textModel.groupID = XYCommonEngineGroupIDText;
textModel.filePath = filePath;
textModel.templateID = templateID;
XYEffectVisionSubTitleLabelInfoModel *subTextModel = [XYEffectVisionSubTitleLabelInfoModel new];
subTextModel.text = text;
textModel.multiTextList = @[subTextModel];
NSInteger beginTime = 0;
textModel.destVeRange = [XYVeRangeModel VeRangeModelWithPosition:beginTime length:length];
[XYEngineWorkspace effectMgr] runTask:textModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
2)字幕文本
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
// text表示字幕文本
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.text = text;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
3)字幕字体
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
// textFontName表示字幕字体名称
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.textFontName = textFontName;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
4)字幕文本颜色
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
// textAlignment表示对齐方式
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.textAlignment = textAlignment;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
5)字幕文本阴影
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
currentEffectModel.isTextExtraEffectEnabled = YES;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.textShadowXShift = textShadowXShift;
labelInfoModel.textShadowYShift = textShadowYShift;
labelInfoModel.textShadowColor = textShadowColor;
labelInfoModel.textShadowBlurRadius = textShadowBlurRadius;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
6)字幕文本描边
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.textStrokeColor = textStrokeColor;
labelInfoModel.textStrokeWPercent = textStrokeWPercent;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
7)字幕对齐方式
// groupId默认为GROUP_ID_SUBTITLE
// effectIndex为同类型中第几个效果
// textIndex表示组合字幕中的第几个字幕
// textAlignment XYEffectVisionTextAlignment
XYEffectVisionTextModel *currentEffectModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
currentEffectModel.taskID = XYCommonEngineTaskIDEffectVisionTextUpdate;
XYEffectVisionSubTitleLabelInfoModel *labelInfoModel = currentEffectModel.multiTextList[textIndex];
labelInfoModel.textAlignment = textAlignment;
[XYEngineWorkspace effectMgr] runTask:currentEffectModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) { }];
8)获取字幕素材配置信息
NSArray <XYTemplateXtyInfo *>*list = [[XYTemplateDataMgr sharedInstance] requestTemplateTextInfoWithTemplateID:templateID];
7. 导出
/**
* 开始导出
*
*/
XYProjectExportConfiguration 参数说明:
名称 | 解释 | 类型 |
---|---|---|
projectType | 工程类型 | XYProjectType |
exportFilePath | 导出文件路径,需要带后缀,提取音频则只支持m4a | String |
width | 导出宽 | NSInteger |
height | 导出高 | NSInteger |
isGIF | 是否导出Gif图片 | BOOL |
bitrateRatio | 自定义比特率系数, [1, 10],默认1 | CGFloat |
fps | 自定义帧率, 默认30 | int |
isFullKeyFrame | 是否纯i帧,只支持转码时使用 | boolean |
trimRange | 导出时间区域 | XYVeRangeModel |
resolution | 导出分辨率类型 | XYEngineResolution |
XYProjectExportMgr 导出管理类说明:
@interface XYProjectExportMgr : NSObject
/// 导出视频
/// @param config 导出配置参数
/// @param start 导出开始 主线程
/// @param progress 导出进度 主线程
/// @param success 导出成功 主线程
/// @param failure 导出失败 主线程
- (void)exportWithConfig:(XYProjectExportConfiguration *)config
start:(export_start_block)start
progress:(export_progress_block)progress
success:(export_success_block)success
failure:(export_failure_block)failure;
//
XYProjectExportConfiguration *config = [[XYProjectExportConfiguration alloc] init];
config.resolution = XYEngineResolution480;
NSString *exportFolder = [NSString stringWithFormat:@"%@/public",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0]];
[NSFileManager qvmedi_createFolderWithPath:exportFolder];
NSString *exportFileName = @"video.mp4";
exportFileName = [NSString stringWithFormat:@"%@%@",[NSDate date],exportFileName];
NSString *exportFileFullPath = [NSString stringWithFormat:@"%@/%@",exportFolder, exportFileName];
config.exportFilePath = exportFileFullPath;
[[XYEngineWorkspace exportMgr] exportWithConfig:config start:^{
} progress:^(NSInteger currentTime, NSInteger totalTime) {
} success:^{
} failure:^(XYProjectExportResultType result, NSInteger errorCode, NSString *error) {
}];
/// 取消导出
- (void)cancel;
六、卡点视频工程功能开发接入
1. 卡点视频工程
创建和加载
/**
* 创建新的卡点视频工程
*/
__block NSMutableArray *medias = [NSMutableArray array];
XYSlideShowMedia *mediaModel = [[XYSlideShowMedia alloc] initWithMediaPath:[XYSlideShowMedia getMediaPathForEngine:phAsset] mediaTyp:(XYAssetMediaTypeImage == obj.mediaType ? XYSlideShowMediaTypeImage : XYSlideShowMediaTypeVideo)];
[medias addObject:mediaModel];
[[XYSlideShowEditor sharedInstance] createProjectWithThemeId:templateID medias:medias complete:^(BOOL success) {
}];
/**
* 加载卡点视频工程
*/
[[XYSlideShowEditor sharedInstance] loadProject:projectFilePath success:^{
} failure:^(NSError * _Nonnull error) {
}];
工程删除
【详情请参看剪辑工程工程删除相关。】
2. 播放器
【详情请参看剪辑工程播放器相关。】
3. 获取片段节点信息
NSArray XYSlideShowSourceNode *> *nodeList = [XYSlideShowEditor sharedInstance].clipMgr fetchSlideShowSourceNodes]
4. 卡点视频剪辑功能接口
1)排序
// 将from位置的片段移动到to位置
[[XYSlideShowEditor sharedInstance].clipMgr moveSource:from dstIndex:to];
2)替换
// clipIndex表示第几个片段,从0开始
PHAsset *phAsset;
XYSlideShowMedia *media = [[XYSlideShowMedia alloc] initWithMediaPath:[XYSlideShowMedia getMediaPathForEngine:phAsset] mediaTyp:XYSlideShowMediaTypeImage];
[[XYSlideShowEditor sharedInstance].clipMgr replaceSourceIdx:clipIndex media:media success:^{
} failure:^(NSError * _Nonnull error, NSInteger code) {
}];
5. 导出
【详情请参看剪辑工程导出相关。】
七、 缩略图获取
1. 工程相关缩略图获取
/**
* 获取工程封面
*/
[[XYVideoThumbnailManager manager] fetchVideoCoverThumbnailsWithThumbnailSize:CGSizeMake(320, 480) block:^(UIImage * _Nonnull image) {
}];
/**
* 获取视频的缩略图
*/
NSInteger seekPosition = 0;
[[XYVideoThumbnailManager manager] fetchThumbnailsWithThumbnailSize:CGSizeMake(60, 60) seekPosition:seekPosition block:^(UIImage * _Nonnull image) {
}
}];
/**
* 片段clip的缩略图
* clipIdentifier clip的identifier
*/
XYClipThumbnailManager *thumbnailManager = [XYClipThumbnailManager new];
[thumbnailManager thumbnailWithClipIdentifier:identifier inputBlock:^(XYVivaEditorThumbnailInputModel * _Nonnull inputModel) {
inputModel.seekPosition = beginTime;
} completeBlock:^(XYVivaEditorThumbnailCompleteModel * _Nonnull completeModel) {
}
} placeholderBlock:^(XYVivaEditorThumbnailCompleteModel * _Nonnull completeModel) {
}];
2.素材缩略图获取
XYEffectVisionModel *visionModel = [[[XYEngineWorkspace effectMgr] effectModels:(groupID)] objectAtIndex:effectIndex];
UIImage * decoratorImage = [XYCommonEngineRequest requestTemplateThumbnail:visionModel size:CGSizeMake(50, 50)];
/**
* 获取视频文件缩略图 如画中画
* identifier effect的identifier
*/
XYClipThumbnailManager *thumbnailManager = [XYClipThumbnailManager new];
[thumbnailManager thumbnailWithEffectIdentifier:identifier inputBlock:^(XYVivaEditorThumbnailInputModel * _Nonnull inputModel) {
inputModel.beginTime = beginTime;
inputModel.endTime = endTime;
inputModel.seekPosition = beginTime;
} completeBlock:^(XYVivaEditorThumbnailCompleteModel * _Nonnull completeModel) {
} placeholderBlock:^(XYVivaEditorThumbnailCompleteModel * _Nonnull completeModel) {
}];
八、Camera接入文档
- 初始化 1.1 初始化XYCameraDevice
#pragma mark - 初始化CameraDevice
- (void)initCameraDevice {
if (self.cameraDevice) {
return;
}
self.cameraDevice = [XYCameraDevice new];
[self.cameraDevice initCameraDeviceWithParamMaker:^(XYCameraDeviceParamMaker * _Nonnull paramMaker) {
paramMaker.captureSessionPreset(AVCaptureSessionPreset1280x720);//设置分辨率
paramMaker.devicePosition(AVCaptureDevicePositionBack);//设置初始镜头方向
}];
}
1.2 初始化XYCameraEngine
⚠️需要在能够拿到预览的view的frame size之后再初始化XYCameraEngine
#pragma mark - 初始化CameraEngine
- (void)initCameraEngine {
if (self.cameraEngine) {
return;
}
self.cameraEngine = [XYCameraEngine new];
NSString *licensePath = [[NSBundle mainBundle] pathForResource:@"license" ofType:@"txt"];
[self.cameraEngine initCameraEngineWithParamMaker:^(XYCameraEngineParamMaker * _Nonnull paramMaker) {
paramMaker.cXiaoYingEngine([[XYEngine sharedXYEngine] getCXiaoYingEngine]);//传入CXiaoYingEngine
paramMaker.enableMetal(YES);//是否启用Metal
paramMaker.enableDepth(YES);//是否启用深度信息
paramMaker.previewView(self.fullSceenPreviewView);//预览用的view
paramMaker.inputResolutionSize(CGSizeMake(1280, 720)).outputResolutionSize(CGSizeMake(1280, 720));//设置输入输入的分辨率
paramMaker.renderRegionRect(self.fullSceenPreviewView.bounds);//用于在预览view上渲染的区域
paramMaker.deviceOrientation(UIDeviceOrientationPortrait);//设备方向
paramMaker.templateAdapter([XYTemplateDataMgr sharedInstance]);//用于处理模版相关的回调
paramMaker.fbTemplateFilepath([[XYTemplateDataMgr sharedInstance] getByID:0x4400000000180001].strPath);//美颜模版的路径
paramMaker.fbTemplateID(0x4400000000180001);//美颜模版的ID
paramMaker.licensePath(licensePath);//License路径
}];
self.cameraDevice.cameraDeviceDelegate = self.cameraEngine;//SampleBuffer的delegate由CameraEngine来处理
self.cameraEngine.cameraEngineDelegate = self;//CameraEngine的回调处理
}
/// CameraEngine的状态回调
/// @param stateModel CameraEngine当前状态Model
- (void)onCameraEngineStateUpdate:(XYCameraEngineStateModel *)stateModel {
//stateModel中主要关心2个数据
//当前CameraEngine的状态信息: 预览中,录制中,暂停中
XYCameraEngineRecordState stateModel.recordState = stateModel.recordState;
//当前已录制视频总时长
NSInteger totalDuration = stateModel. totalDuration;
}
1.3 在viewWillAppear时启动CameraSession
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.cameraDevice startSession];//启动CameraSession,成功后可看到画面
}
1.4 销毁CameraEngine
- (void)dealloc {
NSLog(@"XYEngineCameraVC dealloc");
[_cameraEngine uninitCameraEngine];
}
- XYCameraDevice相关功能使用 2.1 切换前后摄像头
//切换前后摄像头
- (void)onSwapCameraBtnClick {
if (self.cameraDevice.firstCameraParam.devicePosition == AVCaptureDevicePositionFront) {
[self.cameraDevice swapCamera:AVCaptureDevicePositionBack];
} else {
[self.cameraDevice swapCamera:AVCaptureDevicePositionFront];
}
}
2.2 设置对焦点
/// 点击屏幕设置对焦点
/// @param touchPoint 点击位置相对于预览区域的坐标
/// @param previewAreaRect 预览区域rect
- (void)setFocusPointWithTouchPoint:(CGPoint)touchPoint previewAreaRect:(CGRect)previewAreaRect;
//示例代码
- (void)onTapGesture:(UITapGestureRecognizer *)gesture {
CGPoint touchPoint = [gesture locationInView:[gesture view]];
CGRect previewAreaRect = self.fullSceenPreviewView.frame;
BOOL isTouchInThePreviewArea = CGRectContainsPoint(previewAreaRect, touchPoint);
if (!isTouchInThePreviewArea) {//没有点在预览区域,忽略该点击
return;
}
[self.cameraDevice setFocusPointWithTouchPoint:touchPoint previewAreaRect:previewAreaRect];
}
2.3 开关闪光灯
//开关闪光灯
- (void)onFlashBtnClick {
if (self.cameraDevice.torchMode == AVCaptureTorchModeOff) {
self.cameraDevice.torchMode = AVCaptureTorchModeOn;
} else {
self.cameraDevice.torchMode = AVCaptureTorchModeOff;
}
}
2.4 调节曝光程度
#pragma mark - 调节曝光程度
- (void)onExposureBiasChanged:(float)level {
self.cameraDevice.exposureBias = level;//调节范围[-2.0, 2.0]
}
- XYCameraEngine相关功能使用 3.1 开始录制
[self.cameraEngine startRecordWithParamMaker:^(XYCameraRecordParamMaker * _Nonnull paramMaker) {
paramMaker.clipFilePath(self.videoClipFilePath);//录制文件保存路径
paramMaker.hasAudioTrack(YES);//录制文件是否包含音轨
paramMaker.PCMSampleRate(44100);//音频采样率
paramMaker.PCMChannels(2);//音频声道数
paramMaker.maxFrameRate(30);//最大帧率
}];
3.2 暂停录制
[self.cameraEngine pauseRecord];
3.3 继续录制
[self.cameraEngine resumeRecord];
3.4 停止录制
[self.cameraEngine stopRecord];
//完成录制后,可从self.cameraEngine.cameraClipModels获取数据,然后添加到工程中,可参考代码
- (void)insertClips:(NSArray<XYCameraClipModel *> *)cameraClipModels index:(NSInteger)index {
NSMutableArray<XYClipModel *> *clipModels = [NSMutableArray array];
[cameraClipModels enumerateObjectsUsingBlock:^(XYCameraClipModel * _Nonnull cameraClipModel, NSUInteger idx, BOOL * _Nonnull stop) {
XYClipModel *clipModel = [[XYClipModel alloc] init];
clipModel.sourceVeRange.dwPos = cameraClipModel.startPos;
clipModel.sourceVeRange.dwLen = cameraClipModel.endPos - cameraClipModel.startPos;
clipModel.clipFilePath = cameraClipModel.clipFilePath;
clipModel.rotation = cameraClipModel.rotation;
clipModel.clipIndex = index + idx;
[clipModels addObject:clipModel];
}];
XYClipModel *taskModel = [[XYClipModel alloc] init];
taskModel.taskID = XYCommonEngineTaskIDClipAddClip;
taskModel.clipModels = clipModels;
[[XYEngineWorkspace clipMgr] runTask:taskModel completionBlock:^(BOOL success, NSError * _Nonnull error, id _Nonnull obj) {
}];
__weak typeof(self) weakSelf = self;
[[XYEngineWorkspace clipMgr] addObserver:self observerID:XYCommonEngineTaskIDClipAddClip block:^(id _Nonnull obj) {
[weakSelf.navigationController popViewControllerAnimated:YES];
}];
}
3.5 拍照
/// 拍照(分辨率等于录制视频的分辨率,也就是outPutResolution)
/// @param filePath 拍照文件保存地址
/// @param isOriginal 是否原始图像,不包括效果(滤镜,美颜等效果)
- (void)captureWithFilePath:(NSString *)filePath isOriginal:(BOOL)isOriginal;
3.6 删除最后一个已拍摄镜头
/// 删除最后一个镜头
- (void)deleteCameraClip;
3.7 设置滤镜
/// 设置滤镜模版
/// @param templateFilePath 模版文件地址
- (void)setFilterTemplate:(NSString *)templateFilePath;
3.8 设置美颜 3.8.1 启用美颜
self.cameraEngine.enableFaceBeauty
3.8.2 调节制颜程度
self.cameraEngine.faceBeautyLevel = 0.5;//[0, 1]
4.9 缩放
self.cameraEngine.zoomLevel = 2.0;//[1.0, 4.0]
九、其它
/**
* 视频倒放
*
* @param filePath 原始文件全路径。
* exportFilePath 导出后的文件路径
*/
[[XYEngineWorkspace exportMgr] reverseWithFilePath:filePath exportFilePath:exportFilePath progress:^(NSInteger currentTime, NSInteger totalTime) {
} success:^{
} failure:^(XYProjectExportResultType result, NSInteger errorCode) {
}];
作者
Sunshine, [email protected]
许可证
QVEditorKit在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。