Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

root před 2 roky
rodič
revize
56b43f8e69

+ 0 - 105
.gitignore

@@ -1,105 +0,0 @@
-# ---> Java
-# Compiled class file
-*.class
-
-# Log file
-*.log
-
-# BlueJ files
-*.ctxt
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.nar
-*.ear
-*.zip
-*.tar.gz
-*.rar
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-replay_pid*
-
-# ---> JetBrains
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
-# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
-
-# User-specific stuff
-.idea/**/workspace.xml
-.idea/**/tasks.xml
-.idea/**/usage.statistics.xml
-.idea/**/dictionaries
-.idea/**/shelf
-
-# AWS User-specific
-.idea/**/aws.xml
-
-# Generated files
-.idea/**/contentModel.xml
-
-# Sensitive or high-churn files
-.idea/**/dataSources/
-.idea/**/dataSources.ids
-.idea/**/dataSources.local.xml
-.idea/**/sqlDataSources.xml
-.idea/**/dynamic.xml
-.idea/**/uiDesigner.xml
-.idea/**/dbnavigator.xml
-
-# Gradle
-.idea/**/gradle.xml
-.idea/**/libraries
-
-# Gradle and Maven with auto-import
-# When using Gradle or Maven with auto-import, you should exclude module files,
-# since they will be recreated, and may cause churn.  Uncomment if using
-# auto-import.
-# .idea/artifacts
-# .idea/compiler.xml
-# .idea/jarRepositories.xml
-# .idea/modules.xml
-# .idea/*.iml
-# .idea/modules
-# *.iml
-# *.ipr
-
-# CMake
-cmake-build-*/
-
-# Mongo Explorer plugin
-.idea/**/mongoSettings.xml
-
-# File-based project format
-*.iws
-
-# IntelliJ
-out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Cursive Clojure plugin
-.idea/replstate.xml
-
-# SonarLint plugin
-.idea/sonarlint/
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
-fabric.properties
-
-# Editor-based Rest Client
-.idea/httpRequests
-
-# Android studio 3.1+ serialized cache file
-.idea/caches/build_file_checksums.ser
-

+ 6 - 0
api-common/pom.xml

@@ -79,6 +79,12 @@
             <groupId>io.minio</groupId>
             <artifactId>minio</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.11.0</version>
+            <scope>compile</scope>
+        </dependency>
 
 
     </dependencies>

+ 89 - 0
api-common/src/main/java/api/common/util/FfmpegUtil.java

@@ -0,0 +1,89 @@
+package api.common.util;
+
+import lombok.SneakyThrows;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+public class FfmpegUtil {
+
+    /**
+     * @param sourcePath 原始图片路径
+     * @param videoPath  视频生成路径
+     * @param filename   视频文件名称
+     * @param ffmpeg  视频软件路径
+     */
+    @SneakyThrows
+    public static void imgToMp4(String sourcePath, String videoPath, String filename, double inputFrameRate, String ffmpeg) {
+        int nameLength = copyImgToTemp(sourcePath);
+        String execute = LinuxUtil.execute(ffmpeg
+                + " -r " + inputFrameRate
+                + " -i " + FileUtil.addSeparator(sourcePath) + "tmp/image%0" + nameLength + "d.tga"
+                + " -y "
+                + videoPath + "/" + filename + ".mp4"
+        );
+    }
+
+    /**
+     * 计算帧率
+     *
+     * @param imageNumber   图片数量
+     * @param second        视频长度
+     * @param decimalPlaces 帧率保留几位小数
+     * @return 帧率
+     */
+    public static double computeFramerate(int imageNumber, int second, int decimalPlaces) {
+        return Math.round(imageNumber * Math.pow(10.0, decimalPlaces) / second) / Math.pow(10.0, decimalPlaces);
+    }
+
+    private static int copyImgToTemp(String sourcePath) throws IOException {
+        File file = new File(sourcePath);
+        File[] files = file.listFiles();
+        assert files != null;
+        Arrays.sort(files);
+        String[] names = file.list();
+        assert names != null;
+        Arrays.sort(names);
+        int nameLength = getLen(names.length);//获取图片总张数的位数大小,用于补齐图片名称,例如image000.jpg,image001.jpg ....image999.jpg
+        int makeUpMaxNum = getMakeUpMaxNum(nameLength);//图片名字需要补齐的最大数
+        if (names.length > 0) {
+            String tmpPath = sourcePath + "/tmp";
+            new File(tmpPath).mkdir();
+            for (int i = 0; i < names.length; i++) {
+                String name = names[i];
+                if (name.lastIndexOf(".") > 0) {
+                    int lo = name.lastIndexOf(".");
+                    String lastName = name.substring(lo);
+                    String forNeName = String.valueOf(i);
+                    if (i <= makeUpMaxNum) {
+                        StringBuilder zeString = new StringBuilder();
+                        for (int j = 0; j < nameLength - forNeName.length(); j++) {
+                            zeString.append("0");
+                        }
+                        forNeName = "image" + zeString + forNeName + lastName;
+                    } else {
+                        forNeName = "image" + forNeName + lastName;
+                    }
+                    FileUtils.copyFile(files[i], new File(tmpPath + "/" + forNeName));
+                }
+            }
+        }
+        return nameLength;
+    }
+
+    public static int getLen(int x) {
+        if (x < 10) return 1;
+        return getLen(x / 10) + 1;
+    }
+
+    public static int getMakeUpMaxNum(int len) {
+        int num = 1;
+        for (int i = 1; i < len; i++) {
+            num = num * 10;
+        }
+        return num - 1;
+    }
+
+}

+ 13 - 5
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/service/VideoService.java

@@ -73,16 +73,24 @@ public class VideoService {
         String xoscPath = generateXosc(csvDirectoryPath, xodrPath, osgbPath, projectId, projectType);
         //4 生成图片
         String pictureDirectoryPath = csvDirectoryPath + "picture";
-        String esminiCommand = "" + pictureDirectoryPath;
+        FileUtil.createDirectory(pictureDirectoryPath);
+        String esminiCommand =  "/root/disk1/simulation-cloud/esmini/build/EnvironmentSimulator/code-examples/image-capture/image-capture "
+                + xoscPath + " " + pictureDirectoryPath + "/screenshot";
         String esminiResult = LinuxUtil.execute(esminiCommand);
         //5 生成视频
-        String videoName = "";
+        String videoName = "simulation_output.mp4";
         String videoTargetPathOfLinux = csvDirectoryPath + "video";
+        FileUtil.createDirectory(videoTargetPathOfLinux);
         String videoTargetPathOfMinio = projectResultPathOfMinio + projectId + "/" + taskId + "/" + videoName;
-        String ffmpegCommand = " " + pictureDirectoryPath + " " + videoTargetPathOfLinux;
-        String ffmpegResult = LinuxUtil.execute(ffmpegCommand);
+
+        String execute = LinuxUtil.execute("ffmpeg"
+                + " -f image2 -framerate 30 "
+                + " -i " + pictureDirectoryPath + "/screenshot_%05d.tga"
+                + " -c:v libx264 -vf format=yuv420p -crf 20 "
+                + videoTargetPathOfLinux + "/" + videoName
+        );
         //6 将视频上传到 minio
-        MinioUtil.uploadFromFile(minioClient, videoTargetPathOfLinux, bucketName, videoTargetPathOfMinio);
+        MinioUtil.uploadFromFile(minioClient, videoTargetPathOfLinux + videoName, bucketName, videoTargetPathOfMinio);
     }
 
     /**