| | |
| | | package cn.iocoder.yudao.module.digitalcourse.service.coursemedia; |
| | | |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpResponse; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; |
| | | import cn.iocoder.yudao.module.digitalcourse.controller.admin.coursemedia.vo.CourseMediaMegerVO; |
| | | import cn.iocoder.yudao.module.digitalcourse.controller.admin.coursescenecomponents.vo.AppCourseSceneComponentsMegerReqVO; |
| | | import cn.iocoder.yudao.module.digitalcourse.controller.admin.coursescenes.vo.AppCourseScenesMegerReqVO; |
| | | import cn.iocoder.yudao.module.digitalcourse.dal.dataobject.coursemedia.CourseMediaDO; |
| | | import cn.iocoder.yudao.module.digitalcourse.dal.dataobject.digitalhumans.DigitalHumansDO; |
| | | import cn.iocoder.yudao.module.digitalcourse.dal.dataobject.voices.AuditionVO; |
| | | import cn.iocoder.yudao.module.digitalcourse.dal.mysql.coursemedia.CourseMediaMapper; |
| | | import cn.iocoder.yudao.module.digitalcourse.dal.mysql.digitalhumans.DigitalHumansMapper; |
| | | import cn.iocoder.yudao.module.digitalcourse.service.voices.VoicesServiceImpl; |
| | | import cn.iocoder.yudao.module.digitalcourse.util.SrtToVttUtil; |
| | | import cn.iocoder.yudao.module.infra.api.config.ConfigApi; |
| | | import com.alibaba.fastjson.JSON; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.*; |
| | | import java.math.BigInteger; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.nio.file.StandardCopyOption; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | |
| | | @Resource |
| | | private SrtToVttUtil srtToVttUtil; |
| | | |
| | | @Resource |
| | | private DigitalHumansMapper digitalcourseDigitalHumansMapper; |
| | | |
| | | @Resource |
| | | private VoicesServiceImpl serviceImpl; |
| | | |
| | | /** |
| | | * è¿ç¨åå¹¶è§é¢ |
| | | * |
| | | * @param updateReqVO |
| | | * @return |
| | | */ |
| | | @Async |
| | | public void remoteMegerMedia(CourseMediaMegerVO updateReqVO) { |
| | | CourseMediaDO courseMediaDO = courseMediaMapper.selectById(updateReqVO.getCourseMediaId()); |
| | | List<AppCourseScenesMegerReqVO> scenes = updateReqVO.getScenes(); |
| | | //è·åæ°åäººç´ æï¼å£°é³ãè§é¢ï¼ |
| | | String entityId = null; |
| | | if (scenes != null) { |
| | | //è·åscenesä¸ç第ä¸ä¸ªå
ç´ çentityId |
| | | List<AppCourseSceneComponentsMegerReqVO> components = scenes.get(0).getComponents(); |
| | | if (components != null) { |
| | | entityId = components.get(0).getEntityId(); |
| | | } |
| | | } |
| | | DigitalHumansDO digitalHumansDO = digitalcourseDigitalHumansMapper.selectByCode(entityId); |
| | | //è·åæ°åäººç´ æï¼å£°é³ãè§é¢ï¼ |
| | | if (digitalHumansDO == null) { |
| | | // 妿æ¾ä¸å°å¯¹åºç课ç¨åªä½è®°å½ï¼ç´æ¥è¿åæè®°å½é误æ¥å¿ |
| | | return; |
| | | } |
| | | if (courseMediaDO == null) { |
| | | // 妿æ¾ä¸å°å¯¹åºç课ç¨åªä½è®°å½ï¼ç´æ¥è¿åæè®°å½é误æ¥å¿ |
| | | return; |
| | | } |
| | | boolean success; |
| | | List<String> videoUrls = new ArrayList<>(); |
| | | AuditionVO auditionVO = new AuditionVO(); |
| | | auditionVO.setHumanId(String.valueOf(digitalHumansDO.getId())); |
| | | for (AppCourseScenesMegerReqVO scene : scenes) { |
| | | |
| | | int maxRetries = 3; // æå¤§éè¯æ¬¡æ° |
| | | int retryCount = 0; // å½åéè¯æ¬¡æ° |
| | | boolean success = false; |
| | | auditionVO.setText(scene.getBackground().getPptRemark()); |
| | | String audition = serviceImpl.audition(auditionVO); |
| | | // æåé³é¢æä»¶åï¼è·¯å¾çæåä¸é¨åï¼ |
| | | String substring = configApi.getConfigValueByKey("easegen.url") + audition.substring(audition.lastIndexOf("/")); |
| | | String fileName = audition.substring(audition.lastIndexOf('/') + 1); |
| | | String newFileName = "D:/heygem_data/face2face/temp/" + fileName; |
| | | // æåè§é¢æä»¶åï¼è·¯å¾çæåä¸é¨åï¼ |
| | | String substring1 = configApi.getConfigValueByKey("easegen.url") + digitalHumansDO.getFixVideoUrl().substring(digitalHumansDO.getFixVideoUrl().lastIndexOf("/")); |
| | | String fileName1 = digitalHumansDO.getFixVideoUrl().substring(digitalHumansDO.getFixVideoUrl().lastIndexOf('/') + 1); |
| | | String newFileName1 = "D:/heygem_data/face2face/temp/" + fileName1; |
| | | //è·åPPTå
容 |
| | | String cover = scene.getComponents().get(1).getCover(); |
| | | //è·åèæ¯ |
| | | String cover1 = scene.getBackground().getCover(); |
| | | // åæpptèæ¯ï¼è§é¢ï¼æ¨¡æ¿ |
| | | //ffmpeg -i 2.png -i 1.mp4 -filter_complex "[0:v]scale=w=ceil(iw/2)*2:h=ceil(ih/2)*2[bg];[1:v]scale=iw/2:ih/2[v1];[bg][v1]overlay=x=0:y=H-h" output.mp4 |
| | | ProcessBuilder builder = new ProcessBuilder( |
| | | "ffmpeg", "-i", cover1,"-i",cover,"-i",substring1,"-filter_complex","[0:v]scale=",scene.getBackground().getWidth().toString(),":",scene.getBackground().getHeight().toString(),"[bg];[1:v]scale=",scene.getComponents().get(1).getWidth().toString(),":",scene.getComponents().get(1).getHeight().toString(),"[v1];[bg][v1]overlay=x=",scene.getComponents().get(1).getMarginLeft().toString(),":y=",scene.getComponents().get(1).getTop().toString(),"[img];[2:v]scale=",scene.getComponents().get(0).getWidth().toString(),":",scene.getComponents().get(0).getHeight().toString(),"[v2];[img][v2]overlay=x=",scene.getComponents().get(0).getMarginLeft().toString(),":y=",scene.getComponents().get(0).getTop().toString(),newFileName1 |
| | | ); |
| | | builder.redirectErrorStream(true); |
| | | Process process = null; |
| | | try { |
| | | process = builder.start(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | // 读å FFmpeg è¾åºï¼å¯éï¼ |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
| | | try { |
| | | Files.copy(Path.of(substring), Path.of(newFileName), StandardCopyOption.REPLACE_EXISTING); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | //æå¤§éè¯æ¬¡æ° |
| | | int maxRetries = 3; |
| | | // å½åéè¯æ¬¡æ° |
| | | int retryCount = 0; |
| | | success = false; |
| | | |
| | | while (retryCount < maxRetries && !success) { |
| | | try { |
| | | // åéPOSTè¯·æ± |
| | | HttpResponse execute = HttpRequest.post(configApi.getConfigValueByKey(EASEGEN_CORE_URL) + "/api/mergemedia") |
| | | .header("X-API-Key", configApi.getConfigValueByKey(EASEGEN_CORE_KEY)) |
| | | .body(JSON.toJSONString(updateReqVO)) |
| | | HashMap<String, Object> objectObjectHashMap = new HashMap<>(); |
| | | //é³é¢è·¯å¾ |
| | | objectObjectHashMap.put("audio_url", fileName); |
| | | //è§é¢è·¯å¾ï¼æ å£°ï¼ |
| | | objectObjectHashMap.put("video_url", fileName1); |
| | | //å¯ä¸keyï¼ç¨äºæ¥è¯¢ï¼ |
| | | String code = RandomUtil.randomString(32); |
| | | //åºå®å¼ |
| | | objectObjectHashMap.put("code", code); |
| | | objectObjectHashMap.put("chaofen", 0); |
| | | objectObjectHashMap.put("watermark_switch", 0); |
| | | objectObjectHashMap.put("pn", 1); |
| | | HttpResponse execute = HttpRequest.post("http://192.168.3.161:8383/easy/submit") |
| | | .body(JSON.toJSONString(objectObjectHashMap)) |
| | | .execute(); |
| | | String body = execute.body(); |
| | | |
| | |
| | | continue; // éæ°å°è¯ |
| | | } |
| | | |
| | | //è°ç¨æ¥è¯¢è§é¢ç»æ |
| | | String result = getResult(code); |
| | | result = "D:/heygem_data/face2face/temp" + result; |
| | | videoUrls.add(result); |
| | | // 妿æåï¼æ´æ°ç¶æä¸º1ï¼æåï¼ |
| | | courseMediaDO.setStatus(1); // 1 è¡¨ç¤ºåææå |
| | | courseMediaDO.setStatus(1); |
| | | courseMediaMapper.updateById(courseMediaDO); |
| | | success = true; |
| | | |
| | | } catch (Exception e) { |
| | | retryCount++; |
| | | if (retryCount >= maxRetries) { |
| | |
| | | } |
| | | } |
| | | } |
| | | String fileListPath = "D:/heygem_data/face2face/temp/filelist.txt"; |
| | | try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileListPath))) { |
| | | for (String path : videoUrls) { |
| | | writer.write("file '" + path + "'\n"); |
| | | } |
| | | System.out.println("æä»¶å表已çæï¼" + fileListPath); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | ProcessBuilder builder = new ProcessBuilder( |
| | | "ffmpeg", "-f", "concat", "-safe","0", "-i", "DD:/heygem_data/face2face/temp/filelist.txt", "-c", "copy", "D:/heygem_data/face2face/temp/çæè§é¢.mp4" |
| | | ); |
| | | builder.redirectErrorStream(true); |
| | | Process process = null; |
| | | try { |
| | | process = builder.start(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | public String getResult(String taskCode) { |
| | | // ä½¿ç¨ do-while 循ç¯è½®è¯¢ä»»å¡ç¶æ |
| | | // å®ä¹åéåå¨è¿åç»æ |
| | | String result = null; |
| | | // åå§åç¶æä¸ºæªå®æ |
| | | int status = -1; |
| | | do { |
| | | try { |
| | | // è°ç¨æ¥å£è·åä»»å¡ç¶æï¼åè®¾ä½¿ç¨ Hutool ç HttpRequestï¼ |
| | | String body = HttpRequest.get("http://192.168.3.161:8383/easy/query?code=" + taskCode) |
| | | .execute() |
| | | .body(); |
| | | |
| | | System.out.println("æ¥å£è¿åæ°æ®: " + body); |
| | | |
| | | // ä½¿ç¨ fastjson è§£æ JSON æ°æ® |
| | | JSONObject jsonObject = JSON.parseObject(body); |
| | | JSONObject data = jsonObject.getJSONObject("data"); |
| | | |
| | | // æåä»»å¡ç¶æåç»æ |
| | | status = data.getIntValue("status"); |
| | | // 妿任å¡å®æ |
| | | if (status == 2) { |
| | | result = data.getString("result"); |
| | | System.out.println("ä»»å¡å·²å®æï¼ç»ææä»¶è·¯å¾: " + result); |
| | | } else { |
| | | System.out.println("ä»»å¡å°æªå®æï¼å½åè¿åº¦: " + data.getIntValue("progress") + "%"); |
| | | } |
| | | |
| | | // çå¾
䏿®µæ¶é´åè¿è¡ä¸ä¸æ¬¡è½®è¯¢ï¼é¿å
é¢ç¹è¯·æ±ï¼ |
| | | // æ¯é 5 ç§è½®è¯¢ä¸æ¬¡ |
| | | Thread.sleep(5000); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | System.out.println("è°ç¨æ¥å£å¤±è´¥ï¼ç¨åéè¯..."); |
| | | try { |
| | | // åºç°å¼å¸¸æ¶ä¹çå¾
5 ç§ |
| | | Thread.sleep(5000); |
| | | } catch (InterruptedException interruptedException) { |
| | | interruptedException.printStackTrace(); |
| | | } |
| | | } |
| | | // å½ status ä¸çäº 2 æ¶ç»§ç»å¾ªç¯ |
| | | } while (status != 2); |
| | | return result; |
| | | } |
| | | |
| | | public Boolean reMegerMedia(CourseMediaDO courseMediaDO) { |
| | | if (courseMediaDO == null) { |