From 7b3b249a7f2320f97e21e94e26a65f4b4ead0b6e Mon Sep 17 00:00:00 2001
From: shikeying <shikeying@163.com>
Date: 星期六, 24 九月 2022 16:50:25 +0800
Subject: [PATCH] 视频相似度分析1

---
 recommend-video/src/main/java/com/iplatform/recvideo/util/TestUtils.java                   |   49 +++
 recommend-video/src/main/java/com/iplatform/recvideo/api/DemoDebug.java                    |   55 ++++
 deploy-jar-template/src/main/resources/application-dev.yml                                 |   13 
 recommend-video/src/main/java/com/iplatform/recvideo/support/DefaultSimilarExecutor.java   |  110 ++++++++
 recommend-video/src/main/java/com/iplatform/recvideo/util/SearchRequest.java               |   27 ++
 recommend-video/src/main/java/com/iplatform/recvideo/util/PythonInvokeUtils.java           |   81 ++++++
 recommend-video/src/main/java/com/iplatform/recvideo/util/VideoFileUtils.java              |   26 +
 recommend-video/src/main/java/com/iplatform/recvideo/VideoFolderInfo.java                  |    5 
 recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoInfo.java                 |   91 +++++++
 recommend-video/src/main/java/com/iplatform/recvideo/SimilarExecutor.java                  |  107 +++++++-
 recommend-video/doc/table.SQL                                                              |    9 
 recommend-video/src/main/java/com/iplatform/recvideo/Constants.java                        |    4 
 deploy-jar-template/pom.xml                                                                |    8 
 recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarProperties.java    |   22 +
 recommend-video/src/main/java/com/iplatform/recvideo/service/VideoExecutorServiceImpl.java |   55 ++++
 recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoOrder.java                |   94 +++++++
 recommend-video/src/test/java/com/iplatform/recvideo/VideoSimilarTest.java                 |   22 +
 17 files changed, 756 insertions(+), 22 deletions(-)

diff --git a/deploy-jar-template/pom.xml b/deploy-jar-template/pom.xml
index ed20e5d..ce657ad 100644
--- a/deploy-jar-template/pom.xml
+++ b/deploy-jar-template/pom.xml
@@ -18,10 +18,10 @@
 
     <dependencies>
 
-        <dependency>
-            <groupId>com.iplatform</groupId>
-            <artifactId>recommend-text</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.iplatform</groupId>-->
+<!--            <artifactId>recommend-text</artifactId>-->
+<!--        </dependency>-->
 
         <dependency>
             <groupId>com.iplatform</groupId>
diff --git a/deploy-jar-template/src/main/resources/application-dev.yml b/deploy-jar-template/src/main/resources/application-dev.yml
index 96d7b2c..a25556c 100644
--- a/deploy-jar-template/src/main/resources/application-dev.yml
+++ b/deploy-jar-template/src/main/resources/application-dev.yml
@@ -3,7 +3,7 @@
     name: train_recommend
   datasource:
     # 鏄惁鏄剧ずdao涓墦鍗扮殑SQL璇彞
-    show-sql: true
+    show-sql: false
     username: root
 #    password: Bjjmy_63661766
     password: Bjjmy_2020
@@ -39,6 +39,8 @@
       springframework: error
     com:
       walker: info
+      iplatform: debug
+
 #  file: # logging.file.path 鍜� logging.file.name锛屽彧浼氭湁涓�涓敓鏁堬紝閰嶄簡path涓嶈閰峮ame锛岄厤浜唍ame涓嶈閰峱ath锛屽彧閰峱ath鏃秐ame榛樿涓簊pring.log锛屾兂璺緞鍜屾枃浠跺悕鍚屾椂鐢熸晥鍙厤缃甽ogging.file.name=d:/logs/mylog.log
 #    name: ${spring.application.name}.log #鏃ュ織鏂囦欢鍚�
 #    path: logs  #鏃ュ織瀛樺偍璺緞
@@ -86,4 +88,11 @@
 
   video:
     # 瑙嗛閲囬泦瀛樺偍鏍硅矾寰�
-    data-folder: D:/dev_tools/ai/
\ No newline at end of file
+#    data-folder: D:/dev_tools/ai/
+    data-folder: /opt/ai/video/
+
+    # 瑙嗛鐩镐技搴I鏈嶅姟URL
+    ai-service: http://121.36.40.27:12345
+
+    # 鎺ㄨ崘鐩镐技瑙嗛(绠楁硶)鍓嶅灏戜釜
+    top-n: 40
\ No newline at end of file
diff --git a/recommend-video/doc/table.SQL b/recommend-video/doc/table.SQL
new file mode 100644
index 0000000..2283614
--- /dev/null
+++ b/recommend-video/doc/table.SQL
@@ -0,0 +1,9 @@
+
+ALTER TABLE rc_video_t1
+    ADD INDEX inx_src_img (src_img) USING BTREE ;
+
+ALTER TABLE rc_video_t1
+    ADD INDEX inx_src_vid (src_video_id) USING BTREE ;
+
+ALTER TABLE rc_video_t2
+    ADD INDEX inx_t2_src_vid (src_video_id) USING BTREE ;
\ No newline at end of file
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/Constants.java b/recommend-video/src/main/java/com/iplatform/recvideo/Constants.java
index b5f017f..2bc2330 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/Constants.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/Constants.java
@@ -3,4 +3,8 @@
 public class Constants {
 
     public static final String IMAGE_SUFFIX = ".jpg";
+    public static final String VIDEO_SUFFIX = ".mp4";
+
+    public static final String AI_SERVICE_VIDEO_SEARCH = "/ai/video/search_img";
+    public static final String AI_SERVICE_VIDEO_LOAD = "/ai/video/gather";
 }
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/SimilarExecutor.java b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarExecutor.java
index 90d4868..1318e53 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/SimilarExecutor.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarExecutor.java
@@ -1,12 +1,15 @@
 package com.iplatform.recvideo;
 
 import com.iplatform.model.po.Rc_video_t1;
+import com.iplatform.recvideo.util.PythonInvokeUtils;
+import com.iplatform.recvideo.util.TestUtils;
 import com.iplatform.recvideo.util.VideoFileUtils;
 import com.walker.infrastructure.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -25,7 +28,9 @@
 
     private String batchId = null;
 
+    // 褰撳墠鎵规瑕佸鐞嗙殑鍘熷瑙嗛闆嗗悎
     private List<VideoFolderInfo> videoFolderInfoList = null;
+    private List<String> videoIdList = new ArrayList<>();
 
     // 璁板綍褰撳墠鎵ц鍒�(璇ユ壒娆�)鍝釜瑙嗛鏂囦欢瀵瑰簲鐨勭鍑犱釜鍥剧墖
     private int currentVideoFolderIndex = -1;
@@ -33,15 +38,24 @@
 //    private VideoFolderInfo currentVideoFolderInfo = null;
 //    private ImageInfo currentImageInfo = null;
 
-    //
+    // 鏄惁宸插畬鎴愯棰戝姞杞借皟鐢紝瀹屾垚鍚庢墠鑳芥绱㈢浉浼艰棰�
     private boolean pythonLoadVideoDone = false;
+
+    private int topN = 40;
+
+    // 濡傛灉娴嬭瘯妯″紡锛屾暟鎹槸鍋囩殑!
+    private boolean testMode = false;
+
+    public int getTopN() {
+        return topN;
+    }
 
     /**
      * 鍒濆鍖栧璞¤皟鐢ㄤ竴娆�
      * @param videoDataFolder
      * @param batchId
      */
-    public void startup(String videoDataFolder, String batchId){
+    public void startup(String videoDataFolder, String batchId, int topN, boolean testMode){
         if(StringUtils.isEmpty(videoDataFolder)){
             throw new IllegalArgumentException("瑙嗛鏂囦欢澶规牴鐩綍蹇呴』璁剧疆!");
         }
@@ -50,17 +64,28 @@
         }
         this.videoDataFolder = videoDataFolder;
         this.batchId = batchId;
+        this.topN = topN;
+        this.testMode = testMode;
 //        this.videoFolderInfoList = VideoFileUtils.getBatchVideoFolderInfo(this.videoDataFolder, batchId);
+    }
+
+    public void destroy(){
+        if(this.videoFolderInfoList != null){
+            this.videoFolderInfoList.clear();
+        }
+        if(this.videoIdList != null){
+            this.videoIdList.clear();
+        }
     }
 
     /**
      * 鍦ㄦ瘡娆¤皟搴︽椂閽熷懆鏈熸墽琛屼竴娆°�備緥濡�: 10绉掍竴娆°��<p></p>
      * 娉ㄦ剰锛氳鏂规硶鑻辩‘淇濇瘡娆¤皟鐢ㄤ笉浼氶噸澶嶆暟鎹��
      */
-    public void execute(){
+    public int execute() throws Exception{
         if(!this.pythonLoadVideoDone){
             logger.debug("褰撳墠 pythonLoadVideoDone = false, 闇�瑕佹煡璇㈡暟鎹簱鏄惁宸插姞杞借棰�");
-            this.pythonLoadVideoDone = this.pythonLoadVideoDone(this.batchId, videoDataFolder + File.separator + batchId);
+            this.pythonLoadVideoDone = this.pythonLoadVideoDone(this.batchId, VideoFileUtils.combineBatchPath(videoDataFolder, batchId));
         }
 
         // 1: 濡傛灉瑙嗛杩樻湭鍔犺浇锛屽垯鍏堝姞杞借棰�
@@ -70,29 +95,42 @@
                 if(StringUtils.isNotEmpty(error)){
                     // 缁堟璋冪敤锛岀瓑寰呬笅娆¤皟搴︾户缁皾璇曟墽琛�
                     logger.error("python璋冪敤鍔犺浇瑙嗛杩斿洖閿欒:" + error);
-                    return;
+                    return -1;
                 }
                 this.pythonLoadVideoDone = true;
 
             } catch (Exception ex){
                 logger.error("python璋冪敤鍔犺浇瑙嗛寮傚父:" + this.batchId, ex);
-                return;
+                return -1;
             }
         }
 
         // 2: 鍔犺浇瀹岃棰戯紝闇�瑕佹煡璇㈡瘡涓浘鐗囩浉浼煎害缁撴灉锛屽苟瀛樺偍鍒版暟鎹簱
         //    杩欓噷娉ㄦ剰锛岀▼搴忓繀椤诲拰AI鏈嶅姟鍣ㄩ儴缃插湪涓�璧凤紝鏂逛究妫�绱㈣棰戝垎鏋愭枃浠跺す(鏈湴)
         if(this.videoFolderInfoList == null){
-            this.videoFolderInfoList = VideoFileUtils.getBatchVideoFolderInfo(this.videoDataFolder, batchId);
+            if(testMode){
+                this.videoFolderInfoList = TestUtils.getBatchVideoFolderInfo(this.videoDataFolder, batchId);
+            } else {
+                this.videoFolderInfoList = VideoFileUtils.getBatchVideoFolderInfo(this.videoDataFolder, batchId);
+            }
         }
         if(StringUtils.isEmptyList(this.videoFolderInfoList)){
             logger.warn("瑙嗛鍒嗘瀽鏂囦欢澶瑰唴瀹逛负绌猴紝鏃犳硶缁х画鏌ヨ鐩镐技搴︾粨鏋�! videoFolderInfoList = null");
-            return;
+            return -1;
+        }
+        for(VideoFolderInfo v : this.videoFolderInfoList){
+            this.videoIdList.add(v.getVideoId());
         }
 
         if(this.isSearchWriteDone()){
-            logger.info("宸茬粡瀹屾垚鎵规鐩镐技缁撴灉鍐欏叆鏁版嵁搴擄紝涓嶅啀寰�涓嬪鐞嗐�俠atch = " + this.batchId);
-            return;
+            logger.info("宸茬粡瀹屾垚鎵规鐩镐技缁撴灉鍐欏叆鏁版嵁搴擄紝澶勭悊鏈�鍚庝竴姝�:鍐欏叆鐢ㄦ埛鎺ㄨ崘琛ㄦ暟鎹�俠atch = " + this.batchId);
+            try {
+                this.writeRcVideoUser(this.batchId, this.videoIdList);
+                // 杩斿洖1琛ㄧず鏁翠釜娴佺▼鎵ц瀹屾瘯銆�
+                return 1;
+            } catch (Exception ex){
+                throw new Exception("writeRcVideoUser():" + ex.getMessage(), ex);
+            }
         }
 
         // 寮�濮嬫绱㈢浉浼煎害
@@ -100,6 +138,12 @@
             this.currentVideoFolderIndex ++;
         }
 
+        try {
+            this.processOneSearchAndWrite();
+            return 0;
+        } catch (Exception e) {
+            throw new Exception("processOneSearchAndWrite(): " + e.getMessage(), e);
+        }
     }
 
     private void processOneSearchAndWrite() throws Exception{
@@ -113,20 +157,34 @@
         }
         ImageInfo imageInfo = currentVideoFolderInfo.getImageInfoList().get(this.currentImageIndex);
 
-        this.acquirePythonSearchSimilarOnce(imageInfo.getImagePath(), "30");
+        List<Rc_video_t1> videoT1_list = this.acquirePythonSearchSimilarOnce(imageInfo.getVideoId()
+                , imageInfo.getImagePath(), String.valueOf(this.topN));
+        if(!StringUtils.isEmptyList(videoT1_list)){
+            try {
+                this.writeRcVideoT1(videoT1_list, PythonInvokeUtils.getFileNameWithoutSuffix(imageInfo.getImagePath(), Constants.IMAGE_SUFFIX));
+            } catch (Exception ex){
+                throw new Exception("writeRcVideoT1()鎵ц閿欒:" + ex.getMessage(), ex);
+            }
+        }
 
+        // 姣忎釜瑙嗛鐨勬渶鍚庝竴寮犲浘鐗�
         if((this.currentImageIndex + 1) >= currentVideoFolderInfo.getImageInfoSize()){
+            try {
+                this.writeRcVideoT2(currentVideoFolderInfo);
+            } catch (Exception ex){
+                throw new Exception("writeRcVideoT2()鎵ц閿欒:" + ex.getMessage(), ex);
+            }
             if((this.currentVideoFolderIndex + 1) < this.videoFolderInfoList.size()){
                 logger.debug("涓�涓棰戝浘鍍忛泦鍚堟绱㈠鐞嗗畬姣曪紝鍒囨崲鍒颁笅涓�涓紝currentImageIndex = " + this.currentImageIndex);
                 this.currentVideoFolderIndex ++;
                 this.currentImageIndex = -1;
             } else {
-                //
+                // 璁╂渶鍚庝竴涓浘鍍忛泦鍚堢储寮曞�艰秴杩囩晫闄愶紝琛ㄧず鏈�鍚庝竴涓棰戝凡澶勭悊瀹屾瘯銆�
+                this.currentImageIndex ++;
                 logger.debug("鎵�鏈夎棰戝寘鍚殑鎵�鏈夊浘鍍忓鐞嗗畬姣曪紝currentVideoFolderIndex = " + this.currentVideoFolderIndex);
             }
             return;
         }
-
         this.currentImageIndex ++;
     }
 
@@ -167,5 +225,26 @@
      * 璇锋眰AI鏈嶅姟锛屾绱㈢粰瀹氬浘鐗囩殑鐩镐技搴︾粨鏋滈泦鍚堛��
      * @return
      */
-    protected abstract List<Rc_video_t1> acquirePythonSearchSimilarOnce(String imagePath, String topN);
+    protected abstract List<Rc_video_t1> acquirePythonSearchSimilarOnce(String videoId
+            , String imagePath, String topN) throws Exception;
+
+    /**
+     * 绗竴涓复鏃惰〃'rc_video_t1'锛屾瘡寮犲浘鍍忓寘鍚涓浉浼艰棰戣褰曘��
+     * @param list
+     * @param srcImageId 鍘熷瑙嗛ID
+     */
+    protected abstract void writeRcVideoT1(List<Rc_video_t1> list, String srcImageId);
+
+    /**
+     * 鍒嗘瀽琛�'rc_video_t1'锛屽苟鎶婄粰瀹氳棰戠浉浼艰褰曞啓鍏ョ浜屼釜涓存椂琛�'rc_video_t2'
+     * @param videoFolderInfo
+     */
+    protected abstract void writeRcVideoT2(VideoFolderInfo videoFolderInfo);
+
+    /**
+     * 鍒嗘瀽缁欏畾鎵规鎵�鏈夎棰戠敤鎴锋帹鑽愮殑瑙嗛淇℃伅锛屽苟鍐欏叆琛�:'rc_video_user'
+     * @param batchId
+     * @param recVideoIdList 鎺ㄨ崘瑙嗛id闆嗗悎
+     */
+    protected abstract void writeRcVideoUser(String batchId, List<String> recVideoIdList);
 }
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoInfo.java b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoInfo.java
new file mode 100644
index 0000000..f98a3c3
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoInfo.java
@@ -0,0 +1,91 @@
+package com.iplatform.recvideo;
+
+import java.text.DecimalFormat;
+
+/**
+ * 鐩镐技瑙嗛瀵硅薄瀹氫箟銆�
+ * @author 鏃跺厠鑻�
+ * @date 2022-09-24
+ */
+public class SimilarVideoInfo implements Comparable<SimilarVideoInfo> {
+
+    private String id;
+
+    private double distance = 0;
+
+    // 杩欎釜鐩镐技瑙嗛锛屽搴旂殑婧愯棰戝浘鍍忓紶鏁�
+    private int count = 0;
+
+    private double score = 0;
+
+    private DecimalFormat df = new DecimalFormat("#.00");
+
+    public String getId() {
+        return id;
+    }
+
+    public double getDistance() {
+        return distance;
+    }
+
+    public SimilarVideoInfo(String id, double distance){
+        this.id = id;
+        this.distance = distance;
+    }
+
+    /**
+     * 杩斿洖鐩镐技瑙嗛鐨勬帓鍚嶅垎鍊硷紝鐩墠绠�鍗曟牴鎹暟閲忕櫨鍒嗘瘮璁$畻銆�
+     * @return
+     */
+    public double getScore(){
+        if(this.score > 0){
+            return this.score;
+        }
+        if(count == 0){
+            return 0;
+        }
+        double s = (this.count)/100.0;
+        String score = df.format(s);
+        this.score = Double.parseDouble(score);
+        return this.score;
+    }
+
+    public void increase(){
+        this.count ++;
+    }
+
+    public void setDistance(double distance){
+        this.distance = distance;
+    }
+
+    @Override
+    public String toString(){
+        return new StringBuilder("[id=").append(id)
+                .append(", dis=").append(this.distance)
+                .append("]").toString();
+    }
+
+    @Override
+    public int hashCode(){
+        return this.id.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj){
+        if(obj == null){
+            return false;
+        }
+        if(obj instanceof SimilarVideoInfo){
+            SimilarVideoInfo e = (SimilarVideoInfo)obj;
+            if(e.id.equals(this.id)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int compareTo(SimilarVideoInfo o) {
+        return o.count - this.count;
+    }
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoOrder.java b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoOrder.java
new file mode 100644
index 0000000..338cd43
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/SimilarVideoOrder.java
@@ -0,0 +1,94 @@
+package com.iplatform.recvideo;
+
+import com.iplatform.model.po.Rc_video_t1;
+import com.walker.infrastructure.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鎶婁竴涓師瑙嗛瀵瑰簲鐨勫涓浉浼艰棰戦泦鍚堬紝鏍规嵁鍥惧儚鐩镐技搴︽暟閲忓綊骞舵帓搴忋��<p></p>
+ * 鏈�缁堣繑鍥炴帓搴忓悗鐨勭浉浼艰棰戝垪琛紝鐢ㄤ簬鍐欏叆鍒版暟鎹簱涓��
+ * @author 鏃跺厠鑻�
+ * @date 2022-09-24
+ */
+public class SimilarVideoOrder {
+
+    // 鍙備笌杩愮畻鐨勬渶澶ц窛绂伙紝瓒呰繃璇ヨ窛绂昏鏄庣浉浼煎害寰堜綆锛屼笉鍐嶅弬涓庤繍绠椼��
+    private double maxDistance = 1.0;
+
+    // 璁$畻澶氫釜鐩镐技瑙嗛id锛岀患鍚堣窛绂诲钩鍧囧��, key = 鐩镐技瑙嗛ID
+    private Map<String, List<Double>> simiVideoDistanceMap = new HashMap<>();
+    // 鏈�缁堟帓搴忕敤鐨勭浉浼艰棰戦泦鍚堢粨鏋�, key = 鐩镐技瑙嗛ID
+    private Map<String, SimilarVideoInfo> orderVideoList = new HashMap<>();
+
+    public SimilarVideoOrder(List<Rc_video_t1> list){
+        for(Rc_video_t1 e : list){
+            this.addSimiVideoDistance(e.getSim_video_id(), e.getDistance());
+            this.addOrderVideo(e.getSim_video_id());
+        }
+    }
+
+    public List<SimilarVideoInfo> calculateOrder(){
+        SimilarVideoInfo similarVideoInfo = null;
+        double averageDistance = 0;
+        for(Map.Entry<String, List<Double>> entry : this.simiVideoDistanceMap.entrySet()){
+            similarVideoInfo = this.orderVideoList.get(entry.getKey());
+            if(similarVideoInfo == null){
+                throw new IllegalArgumentException("similarVideoInfo涓嶅瓨鍦紝杩欎笉绉戝:(" + entry.getKey());
+            }
+            averageDistance = this.getAverageDistance(entry.getValue(), entry.getKey());
+            similarVideoInfo.setDistance(averageDistance);
+        }
+
+        //
+        List<SimilarVideoInfo> resultList = new ArrayList<>(32);
+
+        for(SimilarVideoInfo e : this.orderVideoList.values()){
+            e.getScore();
+            resultList.add(e);
+        }
+        Collections.sort(resultList);
+        return resultList;
+    }
+
+    private double getAverageDistance(List<Double> list, String simiVideoId){
+        if(StringUtils.isEmptyList(list)){
+            return 0;
+        }
+        double total = 0;
+        for(double d : list){
+            if(d > this.maxDistance){
+//                logger.debug("distance杩囧ぇ锛屼笉鍙備笌鎺掑簭杩愮畻:" + d + ", simiVideoId = " + simiVideoId);
+                continue;
+            }
+            total += d;
+        }
+        return total/list.size();
+    }
+
+    private void addOrderVideo(String simiVideoId){
+        SimilarVideoInfo v = this.orderVideoList.get(simiVideoId);
+        if(v == null){
+            v = new SimilarVideoInfo(simiVideoId, 0);
+            this.orderVideoList.put(simiVideoId, v);
+        }
+        v.increase();
+    }
+
+    private void addSimiVideoDistance(String videoId, double distance){
+        List<Double> v = this.simiVideoDistanceMap.get(videoId);
+        if(v == null){
+            v = new ArrayList<>(16);
+            this.simiVideoDistanceMap.put(videoId, v);
+        }
+        v.add(distance);
+    }
+
+    protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/VideoFolderInfo.java b/recommend-video/src/main/java/com/iplatform/recvideo/VideoFolderInfo.java
index ffd5722..4ee67f6 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/VideoFolderInfo.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/VideoFolderInfo.java
@@ -18,6 +18,11 @@
         this.videoId = videoId;
     }
 
+    /**
+     * 娣诲姞鍥惧儚淇℃伅銆�
+     * @param imagePath 鍥剧墖缁濆璺緞
+     * @param imageName 鍥剧墖鐨勫悕瀛�(濡�: landscape_01_1.jpg)
+     */
     public void addImageInfo(String imagePath, String imageName){
         ImageInfo imageInfo = new ImageInfo();
         imageInfo.setImagePath(imagePath);
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/api/DemoDebug.java b/recommend-video/src/main/java/com/iplatform/recvideo/api/DemoDebug.java
new file mode 100644
index 0000000..4c36014
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/api/DemoDebug.java
@@ -0,0 +1,55 @@
+package com.iplatform.recvideo.api;
+
+import com.iplatform.recvideo.config.VideoSimilarProperties;
+import com.iplatform.recvideo.service.VideoExecutorServiceImpl;
+import com.iplatform.recvideo.support.DefaultSimilarExecutor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+@RestController
+@RequestMapping("/debug/video")
+public class DemoDebug {
+
+    private RestTemplate restTemplate;
+    private VideoSimilarProperties videoSimilarProperties;
+    private VideoExecutorServiceImpl videoExecutorService;
+
+    private DefaultSimilarExecutor similarExecutor = null;
+
+    @Autowired
+    public DemoDebug(RestTemplate restTemplate
+            , VideoSimilarProperties videoSimilarProperties
+            , VideoExecutorServiceImpl videoExecutorService){
+        this.restTemplate = restTemplate;
+        this.videoSimilarProperties = videoSimilarProperties;
+        this.videoExecutorService = videoExecutorService;
+    }
+
+    /**
+     * 璇ユ祴璇曠敤浜庢ā鎷熻皟搴︿换鍔★紝姣忔璋冪敤涓�娆℃墽琛屽櫒鏂规硶锛屾壒閲忓鐞嗕竴寮犲浘鐗囨暟鎹��<p></p>
+     * 鏈�缁堝畬鎴愪竴鎵瑰涓棰戠殑鐩镐技搴︽绱㈠苟鍐欏叆鏁版嵁搴撲腑銆�
+     * @return
+     * @date 2022-09-24
+     */
+    @RequestMapping("/test1")
+    public String testSimilarExecutor(){
+//        String
+        if(similarExecutor == null){
+            this.similarExecutor = new DefaultSimilarExecutor();
+            this.similarExecutor.setVideoExecutorService(this.videoExecutorService);
+            this.similarExecutor.setRestTemplate(this.restTemplate);
+            this.similarExecutor.setRemoteUrl(this.videoSimilarProperties.getAiService());
+            this.similarExecutor.startup(this.videoSimilarProperties.getDataFolder()
+                    , "20220921", this.videoSimilarProperties.getTopN(), true); // 娉ㄦ剰锛氳繖閲屾祴璇曟ā寮�
+        }
+        try {
+            this.similarExecutor.execute();
+            return "鎴愬姛鎵ц涓�娆�";
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarProperties.java b/recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarProperties.java
index 5659418..71c79db 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarProperties.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/config/VideoSimilarProperties.java
@@ -7,6 +7,28 @@
 
     private String dataFolder;
 
+    private int topN;
+
+    private String aiService;
+
+    public String getAiService() {
+        return aiService;
+    }
+
+    public void setAiService(String aiService) {
+        this.aiService = aiService;
+    }
+
+
+    public int getTopN() {
+        return topN;
+    }
+
+    public void setTopN(int topN) {
+        this.topN = topN;
+    }
+
+
     public String getDataFolder() {
         return dataFolder;
     }
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/service/VideoExecutorServiceImpl.java b/recommend-video/src/main/java/com/iplatform/recvideo/service/VideoExecutorServiceImpl.java
index bd4408f..9802597 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/service/VideoExecutorServiceImpl.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/service/VideoExecutorServiceImpl.java
@@ -1,9 +1,64 @@
 package com.iplatform.recvideo.service;
 
+import com.iplatform.model.po.Rc_video_t1;
+import com.iplatform.model.po.Rc_video_t2;
 import com.walker.jdbc.service.BaseServiceImpl;
 import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
 
 @Service
 public class VideoExecutorServiceImpl extends BaseServiceImpl {
 
+    private static final String SQL_CHECK_VIDEO_STATUS = "select * from milvus_video_status where id=?";
+    private static final String SQL_CLEAR_VIDEO_T1 = "delete from rc_video_t1 where src_img=?";
+    private static final String SQL_CLEAR_VIDEO_T2 = "delete from rc_video_t2 where src_video_id=?";
+
+    /**
+     * 鍐欏叆瑙嗛鐩镐技搴︾涓�绾т复鏃舵暟鎹紝姣忎釜鍥惧儚鍖呭惈澶氫釜鐩镐技瑙嗛璁板綍銆�
+     * @param list
+     * @param srcImageId 鍘熷鍥惧儚ID
+     */
+    public void execBatchInsertVideoT1(List<Rc_video_t1> list, String srcImageId){
+        // 鍐欏叆鏂版暟鎹箣鍓嶏紝鍏堟竻闄よ�佽棰戞暟鎹紝鍚庣画鍒嗘瀽閬垮厤鏁版嵁閲嶅(姣忎釜瑙嗛)
+        this.execute(SQL_CLEAR_VIDEO_T1, new Object[]{srcImageId});
+        this.insert(list);
+    }
+
+    /**
+     * 鍐欏叆瑙嗛鐩镐技搴︾浜屼复鏃舵暟鎹紝姣忎釜鍘熷瑙嗛瀵瑰簲澶氫釜鐩镐技瑙嗛锛屽凡鎺掑簭瀛樺偍銆�
+     * @param list
+     * @param srcVideoId
+     */
+    public void execBatchInsertVideoT2(List<Rc_video_t2> list, String srcVideoId){
+        this.execute(SQL_CLEAR_VIDEO_T2, new Object[]{srcVideoId});
+        this.insert(list);
+    }
+
+    /**
+     * 鏍规嵁鍘熷瑙嗛ID杩斿洖鐩镐技璁板綍闆嗗悎銆�
+     * @param srcVideoId
+     * @return
+     */
+    public List<Rc_video_t1> queryVideoT_1List(String srcVideoId){
+        return this.select(new Rc_video_t1(), "where src_video_id=?", new Object[]{srcVideoId});
+    }
+
+    /**
+     * 鏌ヨ瑙嗛鍔犺浇鐘舵�佽〃锛屾槸鍚﹀凡缁忓畬鎴愬姞杞�(绗竴姝�)锛屽鏋滆褰曚笉瀛樺湪璇存槑杩樻病鏈夊紑濮嬪姞杞姐��
+     * @param videoStatusId
+     * @return
+     */
+    public boolean queryLoadVideoDone(String videoStatusId){
+        Map<String, Object> map = this.get(SQL_CHECK_VIDEO_STATUS, new Object[]{videoStatusId});
+        if(map == null){
+            return false;
+        }
+        int status = Integer.parseInt(map.get("status").toString());
+        if(status == 1){
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/support/DefaultSimilarExecutor.java b/recommend-video/src/main/java/com/iplatform/recvideo/support/DefaultSimilarExecutor.java
new file mode 100644
index 0000000..ea9327b
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/support/DefaultSimilarExecutor.java
@@ -0,0 +1,110 @@
+package com.iplatform.recvideo.support;
+
+import com.iplatform.model.po.Rc_video_t1;
+import com.iplatform.model.po.Rc_video_t2;
+import com.iplatform.recvideo.Constants;
+import com.iplatform.recvideo.SimilarExecutor;
+import com.iplatform.recvideo.SimilarVideoInfo;
+import com.iplatform.recvideo.SimilarVideoOrder;
+import com.iplatform.recvideo.VideoFolderInfo;
+import com.iplatform.recvideo.service.VideoExecutorServiceImpl;
+import com.iplatform.recvideo.util.PythonInvokeUtils;
+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.Iterator;
+import java.util.List;
+
+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("寮�濮嬭姹俻ython鏈嶅姟:" + Constants.AI_SERVICE_VIDEO_LOAD);
+        return null;
+    }
+
+    @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) {
+        logger.debug("姝e湪鍐欏叆'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);
+        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("姝e湪鍐欏叆涓�娆$敤鎴锋帹鑽愯棰戞暟鎹�, batchId = " + batchId);
+    }
+
+    private List<Rc_video_t2> toRcVideoT2List(String srcVideoId, List<SimilarVideoInfo> similarVideoInfoList){
+        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());
+            resultList.add(rc_video_t2);
+        }
+        return resultList;
+    }
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/util/PythonInvokeUtils.java b/recommend-video/src/main/java/com/iplatform/recvideo/util/PythonInvokeUtils.java
new file mode 100644
index 0000000..a315bb2
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/util/PythonInvokeUtils.java
@@ -0,0 +1,81 @@
+package com.iplatform.recvideo.util;
+
+import com.iplatform.model.po.Rc_video_t1;
+import com.iplatform.recvideo.Constants;
+import com.walker.infrastructure.utils.JsonUtils;
+import com.walker.infrastructure.utils.NumberGenerator;
+import com.walker.infrastructure.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class PythonInvokeUtils {
+
+    private static final transient Logger logger = LoggerFactory.getLogger(PythonInvokeUtils.class);
+
+    public static List<Rc_video_t1> acquireImageSearchResult(String videoId, String imgPath
+            , String topN, String url, RestTemplate restTemplate) throws Exception{
+        SearchRequest request = new SearchRequest();
+        request.setImg_path(imgPath);
+        request.setTop_n(topN);
+
+        ResponseEntity<String> entity = restTemplate.postForEntity(url, request, String.class);
+        if(entity != null){
+            String jsonData = entity.getBody();
+            if(StringUtils.isEmpty(jsonData)){
+                return null;
+            }
+
+            List<Rc_video_t1> data = new ArrayList<>();
+
+            try {
+                List<Map<String, Object>> list = JsonUtils.jsonStringToObject(jsonData, List.class);
+                for(Map<String, Object> obj : list){
+                    data.add(transferToVideoT1(obj, videoId, imgPath));
+                }
+                logger.debug("++++++ 璇锋眰杩斿洖 Rc_video_t1: " + data.size());
+                return data;
+
+            } catch (Exception e) {
+                logger.error("瑙f瀽json缁撴灉閿欒:" + jsonData, e);
+                throw e;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 浠庢枃浠惰矾寰勪腑锛屾埅鍙栨枃浠禝D锛屾枃浠剁敤id鍛藉悕銆�
+     * @param videoPath
+     * @return
+     */
+    public static final String getFileNameWithoutSuffix(String videoPath, String suffix){
+        String[] array = videoPath.split("/");
+        if(array == null || array.length == 0){
+            logger.error("瑙嗛鍚嶇О鎴彇id閿欒:" + videoPath);
+            return null;
+        }
+        String fileName = array[array.length-1];
+//        String[] idValue = fileName.split(".");
+        return fileName.replaceAll(suffix, StringUtils.EMPTY_STRING);
+    }
+
+    private static Rc_video_t1 transferToVideoT1(Map<String, Object> map, String videoId, String imgPath){
+        String videoPath = map.get("video").toString();
+        String distance = map.get("dis").toString();
+        String srcImageId = getFileNameWithoutSuffix(imgPath, Constants.IMAGE_SUFFIX);
+
+        Rc_video_t1 textBlock = new Rc_video_t1();
+        textBlock.setSim_video_id(getFileNameWithoutSuffix(videoPath, Constants.VIDEO_SUFFIX));
+        textBlock.setDistance(Double.parseDouble(distance));
+        textBlock.setSrc_video_id(videoId);
+        textBlock.setSrc_img(srcImageId);
+        textBlock.setId(NumberGenerator.getLongSequenceId());
+        return textBlock;
+    }
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/util/SearchRequest.java b/recommend-video/src/main/java/com/iplatform/recvideo/util/SearchRequest.java
new file mode 100644
index 0000000..fea99ad
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/util/SearchRequest.java
@@ -0,0 +1,27 @@
+package com.iplatform.recvideo.util;
+
+import java.io.Serializable;
+
+public class SearchRequest implements Serializable {
+
+    private String img_path;
+
+    private String top_n;
+
+    public String getImg_path() {
+        return img_path;
+    }
+
+    public void setImg_path(String img_path) {
+        this.img_path = img_path;
+    }
+
+    public String getTop_n() {
+        return top_n;
+    }
+
+    public void setTop_n(String top_n) {
+        this.top_n = top_n;
+    }
+
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/util/TestUtils.java b/recommend-video/src/main/java/com/iplatform/recvideo/util/TestUtils.java
new file mode 100644
index 0000000..7261c02
--- /dev/null
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/util/TestUtils.java
@@ -0,0 +1,49 @@
+package com.iplatform.recvideo.util;
+
+import com.iplatform.recvideo.VideoFolderInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestUtils {
+
+    public static final List<VideoFolderInfo> getBatchVideoFolderInfo(String videoDataFolder, String batchId){
+        List<VideoFolderInfo> resultList = new ArrayList<>();
+
+        VideoFolderInfo videoFolderInfo = new VideoFolderInfo("landscape_01");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_0.jpg", "landscape_01_0.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_1.jpg", "landscape_01_1.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_2.jpg", "landscape_01_2.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_3.jpg", "landscape_01_3.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_4.jpg", "landscape_01_4.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_5.jpg", "landscape_01_5.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_6.jpg", "landscape_01_6.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_7.jpg", "landscape_01_7.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_8.jpg", "landscape_01_8.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_9.jpg", "landscape_01_9.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_10.jpg", "landscape_01_10.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_11.jpg", "landscape_01_11.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_01/landscape_01_12.jpg", "landscape_01_12.jpg");
+        resultList.add(videoFolderInfo);
+
+        videoFolderInfo = new VideoFolderInfo("landscape_02");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_0.jpg", "landscape_02_0.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_1.jpg", "landscape_02_1.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_2.jpg", "landscape_02_2.jpg");
+        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_3.jpg", "landscape_02_3.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_4.jpg", "landscape_02_4.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_5.jpg", "landscape_02_5.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_6.jpg", "landscape_02_6.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_7.jpg", "landscape_02_7.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_8.jpg", "landscape_02_8.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_9.jpg", "landscape_02_9.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_10.jpg", "landscape_02_10.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_11.jpg", "landscape_02_11.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_12.jpg", "landscape_02_12.jpg");
+//        videoFolderInfo.addImageInfo("/opt/ai/video/20220921/landscape_02/landscape_02_13.jpg", "landscape_02_13.jpg");
+        resultList.add(videoFolderInfo);
+
+        return resultList;
+    }
+
+}
diff --git a/recommend-video/src/main/java/com/iplatform/recvideo/util/VideoFileUtils.java b/recommend-video/src/main/java/com/iplatform/recvideo/util/VideoFileUtils.java
index 61b3707..21812ca 100644
--- a/recommend-video/src/main/java/com/iplatform/recvideo/util/VideoFileUtils.java
+++ b/recommend-video/src/main/java/com/iplatform/recvideo/util/VideoFileUtils.java
@@ -1,8 +1,8 @@
 package com.iplatform.recvideo.util;
 
 import com.iplatform.recvideo.Constants;
-import com.iplatform.recvideo.ImageInfo;
 import com.iplatform.recvideo.VideoFolderInfo;
+import com.walker.infrastructure.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -14,8 +14,30 @@
 
     protected static final transient Logger logger = LoggerFactory.getLogger(VideoFileUtils.class);
 
+    /**
+     * 鎷兼帴瑙嗛鎵归噺(瀛樺偍)鏂囦欢澶硅矾寰勶紝濡�: /opt/ai/video/20220921锛屽叾涓�'20220921'涓烘壒閲忓彿
+     * @param videoDataFolder
+     * @param batchId
+     * @return
+     */
+    public static final String combineBatchPath(String videoDataFolder, String batchId){
+        String batchFolderPath = null;
+        if(videoDataFolder.endsWith(StringUtils.FOLDER_SEPARATOR)){
+            batchFolderPath = videoDataFolder + batchId;
+        } else {
+            batchFolderPath = videoDataFolder + StringUtils.FOLDER_SEPARATOR + batchId;
+        }
+        return batchFolderPath;
+    }
+
     public static final List<VideoFolderInfo> getBatchVideoFolderInfo(String videoDataFolder, String batchId){
-        String batchFolderPath = videoDataFolder + File.separator + batchId;
+//        String batchFolderPath = videoDataFolder + File.separator + batchId;
+        String batchFolderPath = combineBatchPath(videoDataFolder, batchId);
+//        if(videoDataFolder.endsWith(StringUtils.FOLDER_SEPARATOR)){
+//            batchFolderPath = videoDataFolder + batchId;
+//        } else {
+//            batchFolderPath = videoDataFolder + StringUtils.FOLDER_SEPARATOR + batchId;
+//        }
         File batchFolder = new File(batchFolderPath);
         if(!batchFolder.exists()){
             logger.error("瑙嗛鏂囦欢澶逛笉瀛樺湪锛屾棤娉曡幏鍙栧浘鐗囬泦鍚堜俊鎭�俠atchFolderPath = " + batchFolderPath);
diff --git a/recommend-video/src/test/java/com/iplatform/recvideo/VideoSimilarTest.java b/recommend-video/src/test/java/com/iplatform/recvideo/VideoSimilarTest.java
index ef88d0e..d1e3849 100644
--- a/recommend-video/src/test/java/com/iplatform/recvideo/VideoSimilarTest.java
+++ b/recommend-video/src/test/java/com/iplatform/recvideo/VideoSimilarTest.java
@@ -1,13 +1,35 @@
 package com.iplatform.recvideo;
 
+import com.iplatform.model.po.Rc_video_t1;
+import com.iplatform.recvideo.util.PythonInvokeUtils;
 import com.iplatform.recvideo.util.VideoFileUtils;
 import org.junit.Test;
+import org.springframework.web.client.RestTemplate;
 
 import java.util.List;
 
 public class VideoSimilarTest {
 
     @Test
+    public void testPythonSearch() throws Exception{
+        String url = "http://121.36.40.27:12345/ai/video/search_img";
+        RestTemplate restTemplate = new RestTemplate();
+        List<Rc_video_t1> data = PythonInvokeUtils.acquireImageSearchResult("landscape_01"
+                , "/opt/ai/video/20220921/landscape_01/landscape_01_1.jpg", "30", url, restTemplate);
+        if(data != null){
+            for(Rc_video_t1 e : data){
+                System.out.println(e);
+            }
+        }
+    }
+
+//    @Test
+    public void testGetVideoId(){
+        String id = PythonInvokeUtils.getFileNameWithoutSuffix("/opt/ai/video/20220921/landscape_01.mp4", Constants.VIDEO_SUFFIX);
+        System.out.println(id);
+    }
+
+//    @Test
     public void testVideoFolderInfo(){
         List<VideoFolderInfo> list = VideoFileUtils.getBatchVideoFolderInfo("D:/dev_tools/ai", "video");
         if(list != null){

--
Gitblit v1.9.1