diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmImage2Video.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmImage2Video.java index 935ccd0f..9c66b4fa 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmImage2Video.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmImage2Video.java @@ -3,9 +3,16 @@ package com.dsideal.aiSupport.Util.JiMeng; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmCommon; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmErrorCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.*; public class JmImage2Video extends JmCommon { @@ -18,8 +25,9 @@ public class JmImage2Video extends JmCommon { * 提交图生视频任务(使用图片URL) * * @param imageUrls 图片URL数组 - * @return 任务ID - * @throws Exception + * @param prompt 提示词 + * @return 任务结果 + * @throws Exception 异常信息 */ public static JSONObject submitImageToVideoTaskWithUrls(List imageUrls, String prompt) throws Exception { // 创建请求体 @@ -36,11 +44,136 @@ public class JmImage2Video extends JmCommon { return JSON.parseObject(responseBody); } + /** + * 从URL下载文件到指定路径 + * + * @param fileUrl 文件URL + * @param saveFilePath 保存路径 + * @throws Exception 下载过程中的异常 + */ + public static void downloadFile(String fileUrl, String saveFilePath) throws Exception { + URL url = new URL(fileUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(60000); + + // 确保目录存在 + File file = new File(saveFilePath); + File parentDir = file.getParentFile(); + if (parentDir != null && !parentDir.exists()) { + parentDir.mkdirs(); + log.info("创建目录: {}", parentDir.getAbsolutePath()); + } + + // 获取输入流 + try (InputStream in = connection.getInputStream(); + FileOutputStream out = new FileOutputStream(saveFilePath)) { + + byte[] buffer = new byte[4096]; + int bytesRead; + + // 读取数据并写入文件 + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + + log.info("文件下载成功,保存路径: {}", saveFilePath); + } catch (Exception e) { + log.error("文件下载失败: {}", e.getMessage(), e); + throw e; + } finally { + connection.disconnect(); + } + } + public static void main(String[] args) throws Exception { List imageUrls = new ArrayList<>(); imageUrls.add("https://dsideal.obs.myhuaweicloud.com/HuangHai/%E5%A4%87%E4%BB%BD/%E5%B0%8F%E4%B9%94%E5%A4%B4%E5%83%8F.jpg"); - String prompt = "眨眨眼"; - JSONObject submitResult = submitImageToVideoTaskWithUrls(imageUrls, prompt); - System.out.println("提交结果: " + submitResult); + String prompt = ""; + + String mp4FileName = "image2video.mp4"; + + // 添加重试逻辑,处理API并发限制错误 + JSONObject submitResult = null; + int submitRetryCount = 0; + int maxSubmitRetries = 1000; // 最大重试次数 + int submitRetryInterval = 3000; // 重试间隔(毫秒) + + while (submitRetryCount < maxSubmitRetries) { + try { + submitResult = submitImageToVideoTaskWithUrls(imageUrls, prompt); + log.info("提交结果: {}", submitResult); + + int code = submitResult.getInteger("code"); + if (code == JmErrorCode.API_CONCURRENT_LIMIT.getCode()) { + log.warn("API并发限制,等待{}毫秒后重试...", submitRetryInterval); + Thread.sleep(submitRetryInterval); + submitRetryCount++; + continue; + } else if (!JmErrorCode.isSuccess(code)) { + log.error("提交任务失败: 错误码={}, 错误信息={}", code, JmErrorCode.getMessageByCode(code)); + return; + } + + // 成功获取结果,跳出循环 + break; + } catch (Exception e) { + log.error("提交任务异常: {}", e.getMessage(), e); + submitRetryCount++; + if (submitRetryCount < maxSubmitRetries) { + log.warn("等待{}毫秒后重试...", submitRetryInterval); + Thread.sleep(submitRetryInterval); + } else { + throw e; // 达到最大重试次数,抛出异常 + } + } + } + + if (submitRetryCount >= maxSubmitRetries) { + log.error("提交任务失败,已达到最大重试次数: {}", maxSubmitRetries); + return; + } + + // 获取任务ID + String taskId = submitResult.getJSONObject("data").getString("task_id"); + log.info("任务ID: {}", taskId); + + // 检查任务是不是已经结束 + int queryRetryCount = 0; + int maxQueryRetries = 10000; // 最大查询次数 + int queryRetryInterval = 3000; // 查询间隔(毫秒) + + while (queryRetryCount < maxQueryRetries) { + JSONObject result = queryTaskResult(taskId); + log.info("查询结果: {}", result); + + int code = result.getInteger("code"); + if (!JmErrorCode.isSuccess(code)) { + log.error("查询失败: 错误码={}, 错误信息={}", code, JmErrorCode.getMessageByCode(code)); + break; + } + + JSONObject data = result.getJSONObject("data"); + if (data != null && data.getString("video_url") != null && !data.getString("video_url").isEmpty()) { + String videoUrl = data.getString("video_url"); + log.info("视频地址: {}", videoUrl); + + // 下载视频 + String saveVideoPath = basePath + mp4FileName; + log.info("开始下载视频..."); + downloadFile(videoUrl, saveVideoPath); + log.info("视频已下载到: {}", saveVideoPath); + break; + } else { + log.info("任务处理中,等待{}毫秒后重试...", queryRetryInterval); + Thread.sleep(queryRetryInterval); + queryRetryCount++; + } + } + + if (queryRetryCount >= maxQueryRetries) { + log.error("任务查询超时,已达到最大查询次数: {}", maxQueryRetries); + } } } \ No newline at end of file diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Image.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Image.java index 81c4fe29..fface938 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Image.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Image.java @@ -2,6 +2,8 @@ package com.dsideal.aiSupport.Util.JiMeng; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmCommon; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmErrorCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Video.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Video.java index d170075c..9fbee42f 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Video.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmText2Video.java @@ -2,6 +2,8 @@ package com.dsideal.aiSupport.Util.JiMeng; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmCommon; +import com.dsideal.aiSupport.Util.JiMeng.Kit.JmErrorCode; import com.jfinal.kit.StrKit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,7 +90,7 @@ public class JmText2Video extends JmCommon { // 添加重试逻辑,处理API并发限制错误 JSONObject jo = null; int generateRetryCount = 0; - int maxGenerateRetries = 5; // 最大重试次数 + int maxGenerateRetries = 1000; // 最大重试次数 int generateRetryInterval = 5000; // 重试间隔(毫秒) while (generateRetryCount < maxGenerateRetries) { @@ -121,7 +123,7 @@ public class JmText2Video extends JmCommon { } } - if (jo == null || generateRetryCount >= maxGenerateRetries) { + if (generateRetryCount >= maxGenerateRetries) { log.error("生成视频失败,已达到最大重试次数: {}", maxGenerateRetries); return; } diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmCommon.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmCommon.java similarity index 96% rename from dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmCommon.java rename to dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmCommon.java index 58856cb6..144a3358 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmCommon.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmCommon.java @@ -1,4 +1,4 @@ -package com.dsideal.aiSupport.Util.JiMeng; +package com.dsideal.aiSupport.Util.JiMeng.Kit; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -12,7 +12,6 @@ import javax.crypto.spec.SecretKeySpec; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; -import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; import java.nio.charset.Charset; diff --git a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmErrorCode.java b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmErrorCode.java similarity index 93% rename from dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmErrorCode.java rename to dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmErrorCode.java index 4313cb23..6e036d76 100644 --- a/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/JmErrorCode.java +++ b/dsAiSupport/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Kit/JmErrorCode.java @@ -1,4 +1,4 @@ -package com.dsideal.aiSupport.Util.JiMeng; +package com.dsideal.aiSupport.Util.JiMeng.Kit; /** * 火山引擎API错误码枚举 diff --git a/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Example/1.mp4 b/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Example/1.mp4 new file mode 100644 index 00000000..b0e03842 Binary files /dev/null and b/src/main/java/com/dsideal/aiSupport/Util/JiMeng/Example/1.mp4 differ