package com.iplatform.recvideo.support;
|
|
import com.iplatform.model.po.Rc_video_t1;
|
import com.iplatform.model.po.Rc_video_t2;
|
import com.iplatform.model.po.Rc_video_user;
|
import com.iplatform.recvideo.Constants;
|
import com.iplatform.recvideo.SimilarExecutor;
|
import com.iplatform.recvideo.SimilarVideoInfo;
|
import com.iplatform.recvideo.SimilarVideoOrder;
|
import com.iplatform.recvideo.SimilarVideoUser;
|
import com.iplatform.recvideo.SimilarVideoUserOrder;
|
import com.iplatform.recvideo.VideoFolderInfo;
|
import com.iplatform.recvideo.service.VideoExecutorServiceImpl;
|
import com.iplatform.recvideo.util.PythonInvokeUtils;
|
import com.walker.infrastructure.utils.DateUtils;
|
import com.walker.infrastructure.utils.NumberGenerator;
|
import com.walker.infrastructure.utils.StringUtils;
|
import org.springframework.web.client.RestTemplate;
|
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.Iterator;
|
import java.util.List;
|
import java.util.Map;
|
|
public class DefaultSimilarExecutor extends SimilarExecutor {
|
|
private RestTemplate restTemplate;
|
|
// python AI 服务地址前缀
|
private String remoteUrl;
|
|
private VideoExecutorServiceImpl videoExecutorService = null;
|
|
public void setVideoExecutorService(VideoExecutorServiceImpl videoExecutorService) {
|
this.videoExecutorService = videoExecutorService;
|
}
|
|
public void setRemoteUrl(String remoteUrl) {
|
this.remoteUrl = remoteUrl;
|
}
|
|
public void setRestTemplate(RestTemplate restTemplate) {
|
this.restTemplate = restTemplate;
|
}
|
|
@Override
|
protected boolean pythonLoadVideoDone(String batchId, String batchFolder) {
|
return this.videoExecutorService.queryLoadVideoDone(batchFolder);
|
}
|
|
@Override
|
protected String requestStartPythonLoadVideo(String batchId) throws Exception {
|
logger.info("开始请求python服务:" + Constants.AI_SERVICE_VIDEO_LOAD);
|
String url = this.remoteUrl + Constants.AI_SERVICE_VIDEO_LOAD;
|
boolean success = PythonInvokeUtils.postLoadVideoGather(batchId, url, this.restTemplate);
|
return success? null : "python 加载视频调用失败";
|
}
|
|
@Override
|
protected List<Rc_video_t1> acquirePythonSearchSimilarOnce(String srcVideoId, String imagePath, String topN) throws Exception {
|
String url = this.remoteUrl + Constants.AI_SERVICE_VIDEO_SEARCH;
|
return PythonInvokeUtils.acquireImageSearchResult(srcVideoId, imagePath, topN, url, this.restTemplate);
|
}
|
|
@Override
|
protected void writeRcVideoT1(List<Rc_video_t1> list, String srcImageId) {
|
// 删除 distance == 0 的,这个是自身视频信息(推荐的要排除自己)
|
Rc_video_t1 e = null;
|
for(Iterator<Rc_video_t1> it = list.iterator(); it.hasNext();){
|
e = it.next();
|
if(e.getDistance().doubleValue() == 0){
|
it.remove();
|
}
|
}
|
this.videoExecutorService.execBatchInsertVideoT1(list, srcImageId);
|
logger.debug("成功写入集合'Rc_video_t1':" + list.size());
|
}
|
|
@Override
|
protected void writeRcVideoT2(VideoFolderInfo videoFolderInfo, String batchId) {
|
logger.debug("正在写入'Rc_video_t2',原始视频:" + videoFolderInfo.getVideoId());
|
List<Rc_video_t1> list = this.videoExecutorService.queryVideoT_1List(videoFolderInfo.getVideoId());
|
if(StringUtils.isEmptyList(list)){
|
logger.warn("writeRcVideoT2: Rc_video_t1检索结果为空,无法继续写入'Rc_video_t2'");
|
return;
|
}
|
SimilarVideoOrder similarVideoOrder = new SimilarVideoOrder(list);
|
List<SimilarVideoInfo> similarVideoInfoList = similarVideoOrder.calculateOrder();
|
List<Rc_video_t2> video2List = this.toRcVideoT2List(videoFolderInfo.getVideoId(), similarVideoInfoList, batchId);
|
if(video2List == null){
|
logger.warn("writeRcVideoT2(): similarVideoInfoList为空,不能执行, srcVideoId = " + videoFolderInfo.getVideoId());
|
return;
|
}
|
this.videoExecutorService.execBatchInsertVideoT2(video2List, videoFolderInfo.getVideoId());
|
}
|
|
@Override
|
protected void writeRcVideoUser(String batchId, List<String> recVideoIdList) {
|
logger.info("正在写入一次用户推荐视频数据, batchId = " + batchId);
|
List<Map<String, Object>> batchUserVideoList = this.videoExecutorService.queryBatchUserVideoList(batchId);
|
if(StringUtils.isEmptyList(batchUserVideoList)){
|
logger.error("未找到批次用户视频记录,无法更新用户推荐视频数据,batchId = " + batchId);
|
return;
|
}
|
List<Rc_video_t2> video2List = this.videoExecutorService.queryVideoT_2List(batchId);
|
if(StringUtils.isEmptyList(video2List)){
|
logger.warn("从表'rc_video_t2'未加载到批次视频结果记录,无法继续写入用户推荐视频'rc_video_user'");
|
return;
|
}
|
|
// 原始视频ID与用户关系
|
Map<String, Long> srcVideoIdUserCache = new HashMap<>();
|
for(Map<String, Object> m : batchUserVideoList){
|
srcVideoIdUserCache.put(m.get("src_video_id").toString(), Long.parseLong(m.get("user_id").toString()));
|
}
|
|
// 推荐视频ID与用户关系
|
Map<String, Long> videoIdUserCache = new HashMap<>();
|
Long userId = null;
|
for(Rc_video_t2 e : video2List){
|
userId = srcVideoIdUserCache.get(e.getSrc_video_id());
|
if(userId == null){
|
throw new IllegalArgumentException("推荐视频的原始视频未找到对应用户,src_video = " + e.getSrc_video_id() + ", rec_video = " + e.getSim_video_id());
|
}
|
videoIdUserCache.put(e.getSim_video_id(), userId);
|
}
|
|
SimilarVideoUserOrder similarVideoUserOrder = new SimilarVideoUserOrder(videoIdUserCache, video2List);
|
List<SimilarVideoUser> similarVideoUserList = similarVideoUserOrder.calculateOrder();
|
List<Rc_video_user> videoUserList = this.toRcVideoUserList(similarVideoUserList);
|
if(videoUserList == null){
|
logger.warn("writeRcVideoUser(): similarVideoUserList,不能执行, batchId = " + batchId);
|
return;
|
}
|
|
// 用户推荐视频记录,需要更新,如果不存在才写入。
|
// 注意:这里暂时不更新,全部写入,这样用户推荐表中会存在较多重复数据,后续要添加定时任务清除重复数据即可。
|
this.videoExecutorService.execBatchInsertVideoUser(videoUserList, batchId);
|
logger.debug("批次任务状态已更新成功! " + batchId);
|
}
|
|
@Override
|
protected void ignoreTaskStatus(String batchId) {
|
this.videoExecutorService.execIgnoreTaskStatus(batchId);
|
}
|
|
private List<Rc_video_user> toRcVideoUserList(List<SimilarVideoUser> similarVideoUserList){
|
if(StringUtils.isEmptyList(similarVideoUserList)){
|
return null;
|
}
|
List<Rc_video_user> resultList = new ArrayList<>(similarVideoUserList.size());
|
Rc_video_user rc_video_t2 = null;
|
for(SimilarVideoUser e : similarVideoUserList){
|
rc_video_t2 = new Rc_video_user(NumberGenerator.getLongSequenceNumber());
|
rc_video_t2.setCreate_time(Long.parseLong(DateUtils.getDateTimeSecondForShow()));
|
rc_video_t2.setUser_id(e.getUserId());
|
rc_video_t2.setVideo_id(e.getRecommendVideoId());
|
rc_video_t2.setScore(e.getScore());
|
resultList.add(rc_video_t2);
|
}
|
return resultList;
|
}
|
|
private List<Rc_video_t2> toRcVideoT2List(String srcVideoId
|
, List<SimilarVideoInfo> similarVideoInfoList, String batchId){
|
if(StringUtils.isEmptyList(similarVideoInfoList)){
|
return null;
|
}
|
List<Rc_video_t2> resultList = new ArrayList<>(similarVideoInfoList.size());
|
Rc_video_t2 rc_video_t2 = null;
|
for(SimilarVideoInfo e : similarVideoInfoList){
|
rc_video_t2 = new Rc_video_t2(NumberGenerator.getLongSequenceId());
|
rc_video_t2.setSrc_video_id(srcVideoId);
|
rc_video_t2.setSim_video_id(e.getId());
|
rc_video_t2.setScore(e.getScore());
|
rc_video_t2.setBatch_id(batchId);
|
resultList.add(rc_video_t2);
|
}
|
return resultList;
|
}
|
}
|