高光成片是指从视频中提取出来的精彩瞬间,这些瞬间通常是视频中最引人注目的部分。通过将高光成片接入到app中,通过提取高光,并且对视频进行打分与打标签,模板匹配,然后进行模板合成,很容易就能获得一个高质量的视频。
高光成片往往需要结合剪同款模版一同使用,参考 EffectOne 标品接入文档完成 SDK 接入,以 cocoapods 为例
# 版本号可替换为需要接入的版本,这里以 1.8.1 为例 pod 'EffectOneKit', '1.8.1', :source => 'https://github.com/volcengine/volcengine-spces'
EffectOne 客户接入文档--iOS 1.8.1
EffectOne-iOS 高光成片 V1.8.1
参考 EffectOne iOS 剪同款SDK无UI接入文档 先完成剪同款鉴权与初始化。
判断高光鉴权是否通过:
BOOL isAuth = [[EOAuthorization sharedInstance] isCheckAuthForHighLight];
通过 ILAManager 可以对素材(视频/图片)进行识别,得到素材的分类标签和打分,接口定义如下
- (NSString *)scanWithAssetList:(NSArray <ILAAsset *> *)assetList taskConfig:(ILATaskConfig *)taskConfig progress:(void(^)(int32_t cur, int32_t total, int32_t code, ILAAsset *asset, ILAScanResult *result, BOOL hasScan, bool asset_cv_finish))progress finish:(void(^)(int32_t code, NSArray *result, NSDictionary *mapping))finish;
使用样例:
// 传入鉴权 buffer 和模型路径初始化 ILAManager 识别配置 ILAConfig *ilaConfig = [[ILAConfig alloc] initWithLicenceBuffer:[[EOAuthorization sharedInstance] cvLicenseBuffer] modelDir:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"EOLocalResources.bundle/EffectResource/ILAModels.bundle"] ofType:nil]]; ilaConfig.targetCVSize = CGSizeMake(256, 256); [ILAManager setConfig:ilaConfig]; [ILAManager setLogProtocol:self]; [[ILAManager sharedInstance] initialization]; // 批量识别 NSString *taskID = [[ILAManager sharedInstance] scanWithAssetList:assetList taskConfig:taskConfig progress:^(int32_t cur, int32_t total, int32_t code, ILAAsset * _Nonnull asset, ILAScanResult * _Nonnull result, BOOL hasScan, bool asset_cv_finish) { } finish:^(int32_t code, NSArray * _Nonnull result, NSDictionary * _Nonnull mapping) { // 识别完成,数据转化 NSMutableArray *hlResults = @[].mutableCopy; for (ILAAsset *ilaAsset in splitedILAAssetList) { EOHLResultByMedia *hlRes = [EOHLResultByMedia new]; EORecognizeMedia *media = [EORecognizeMedia new]; media.mediaID = ilaAsset.assetId; media.type = (int)ilaAsset.mediaType; media.width = ilaAsset.width; media.height = ilaAsset.height; media.durationMs = ilaAsset.duration; media.createTimeMs = ilaAsset.createTime; hlRes.media = media; // 根据assetId查询结果 NSArray <ILAScanResult *> *scanResults = [[ILAManager sharedInstance] queryResultsWithLocalId:ilaAsset.assetId]; NSMutableArray <EORecognizeResult *>*arr = @[].mutableCopy; for (ILAScanResult *r in scanResults) { EORecognizeResult *info = [EORecognizeResult new]; info.timeStamp = r.scoreInfo.timeStamp; info.score = r.scoreInfo.qualityScore; NSMutableArray *probs = @[].mutableCopy; NSMutableArray *tags = @[].mutableCopy; for (ILAScanTag *tag in r.tagsInfo) { [probs addObject:@(tag.tagProb)]; [tags addObject:tag.tagName ?: @""]; } info.categoryProbs = probs.copy; info.categoryList = tags.copy; [arr addObject:info]; EOSDKLogInfo(@"ILA score, id=%@ , qualityScore=%f, frame=%lld, tag=%@", r.assetId, r.scoreInfo.qualityScore, r.frame, [tags componentsJoinedByString:@","]); } hlRes.hlResults = arr.copy; [hlResults addObject:hlRes]; } }];
通过 EOHighLightWrapper 可以匹配推荐出来的最优topN模板,接口定义如下
+ (NSArray <EOHLTemplateMatchedInfo *>*)matchTemplate:(NSArray <EOMomentTemplate *> *)templateList scanResultList:(NSArray <EOHLResultByMedia *> *)scanResultList topN:(int)topN;
使用样例:
NSArray *matchedInfos = [EOHighLightWrapper matchTemplate:momentTemplates.copy scanResultList:hlResults topN:3];
匹配结果数据结构如下
@interface EOHLTemplateMatchedInfo : NSObject //匹配出的模板信息 @property (nonatomic, strong) EOMomentTemplate *momentTemplate; @property (nonatomic, assign) float score; //模板槽位对应匹配到的最佳素材信息,顺序就是模板槽位的顺序 @property (nonatomic, copy) NSArray <EOHLTemplateMatchedItem *>*mediaList; @end //模板信息 @interface EOMomentTemplate : NSObject @property (nonatomic, copy) NSString *templateID; @property (nonatomic, copy) NSString *cover; @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *orderId; @property (nonatomic, copy) NSArray <NSNumber *>*segmentDurations; //每个槽位的时长 @property (nonatomic, copy) NSArray <NSString *>*category; //模板的分类信息 @property (nonatomic, copy) NSString *extra; @property (nonatomic, copy) NSString *template_url; @property (nonatomic, copy) NSString *zip_path; @property (nonatomic, copy) NSString *unzip_path; @end @interface EOHLTemplateMatchedItem : NSObject //识别到的素材,路径,时长,宽高的那些信息 @property (nonatomic, strong) EORecognizeMedia *media; //素材对应槽位长度,提取到的高光片段信息,模板合成时,填充槽位会用到 @property (nonatomic, strong) EOHighLightResult *extractorResult; @end @interface EOHighLightResult : NSObject @property (nonatomic, assign) float startTime; //高光片段的开始时间,模板合成时传给槽位,sdk内部会自动裁剪 @property (nonatomic, assign) float endTime; //高光的结束时间,模板合成时传给槽位,sdk内部会自动裁剪 @property (nonatomic, assign) float averageScore; // 高光时刻内每一帧的平均分 @property (nonatomic, assign) BOOL categoryMatched; @property (nonatomic, copy) NSString *path; @end
根据匹配结果的extractorResult设置CSIFAssetModel的highlightTimeRange,然后设置给剪同款SDK就可以预览效果了,详细源码参考 Sample Code 中 EOHighLightManager 类的实现。