完成视频部分的前后端
This commit is contained in:
@@ -17,5 +17,5 @@ public class ImageVideoProperties {
|
||||
private String voiceCloneWorkflowId = "7652954356887961641";
|
||||
private String voiceSynthesisWorkflowId = "7652954297530105894";
|
||||
private int cozeConnectTimeoutMillis = 10000;
|
||||
private int cozeReadTimeoutMillis = 600000;
|
||||
private int cozeReadTimeoutMillis = 3600000;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public class OssProperties {
|
||||
private String endpoint;
|
||||
private String publicEndpoint;
|
||||
private String bucket;
|
||||
private String imageVideoBucket;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,11 @@ public class OssStorageService {
|
||||
|
||||
public UploadedResult uploadResultFileWithFreshDownloadUrl(File file, String moduleType) {
|
||||
String objectKey = String.format("result/%s/%s/%s", moduleType.toLowerCase(), UUID.randomUUID(), file.getName());
|
||||
String bucket = resolveBucket(moduleType);
|
||||
OSS ossClient = buildClient();
|
||||
try {
|
||||
ossClient.putObject(ossProperties.getBucket(), objectKey, file);
|
||||
return new UploadedResult(objectKey, getPublicUrl(objectKey));
|
||||
ossClient.putObject(bucket, objectKey, file);
|
||||
return new UploadedResult(objectKey, getPublicUrl(objectKey, bucket));
|
||||
} finally {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
@@ -56,10 +57,11 @@ public class OssStorageService {
|
||||
objectName = file.getName();
|
||||
}
|
||||
String objectKey = String.format("upload/%s/%s/%s", normalizedModuleType, UUID.randomUUID(), objectName);
|
||||
String bucket = resolveBucket(moduleType);
|
||||
OSS ossClient = buildClient();
|
||||
try {
|
||||
ossClient.putObject(ossProperties.getBucket(), objectKey, file);
|
||||
return new UploadedResult(objectKey, getPublicUrl(objectKey));
|
||||
ossClient.putObject(bucket, objectKey, file);
|
||||
return new UploadedResult(objectKey, getPublicUrl(objectKey, bucket));
|
||||
} finally {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
@@ -151,12 +153,16 @@ public class OssStorageService {
|
||||
* 获取公开(无签名)URL,格式:https://{bucket}.{endpoint}/{objectKey}
|
||||
*/
|
||||
public String getPublicUrl(String value) {
|
||||
return getPublicUrl(value, ossProperties.getBucket());
|
||||
}
|
||||
|
||||
private String getPublicUrl(String value, String bucket) {
|
||||
if (value == null || value.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
String objectKey = resolveObjectKey(value);
|
||||
String normalizedKey = objectKey.startsWith("/") ? objectKey.substring(1) : objectKey;
|
||||
String host = String.format("%s.%s", ossProperties.getBucket(), publicEndpoint());
|
||||
String host = String.format("%s.%s", bucket, publicEndpoint());
|
||||
try {
|
||||
return new URI("https", host, "/" + normalizedKey, null).toASCIIString();
|
||||
} catch (Exception ignored) {
|
||||
@@ -210,6 +216,16 @@ public class OssStorageService {
|
||||
);
|
||||
}
|
||||
|
||||
private String resolveBucket(String moduleType) {
|
||||
if (moduleType != null
|
||||
&& "IMAGE_VIDEO".equalsIgnoreCase(moduleType.trim())
|
||||
&& ossProperties.getImageVideoBucket() != null
|
||||
&& !ossProperties.getImageVideoBucket().isBlank()) {
|
||||
return ossProperties.getImageVideoBucket().trim();
|
||||
}
|
||||
return ossProperties.getBucket();
|
||||
}
|
||||
|
||||
private String publicEndpoint() {
|
||||
String endpoint = ossProperties.getPublicEndpoint();
|
||||
if (endpoint == null || endpoint.isBlank()) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ImageVideoController {
|
||||
@PostMapping("/douyin-copy")
|
||||
@Operation(summary = "抖音文案识别和仿写")
|
||||
public ApiResponse<DouyinCopyVo> douyinCopy(@Valid @RequestBody DouyinCopyRequest request) {
|
||||
return ApiResponse.success(imageVideoCozeService.runDouyinCopy(request.getUserId(), request.getUrl()));
|
||||
return ApiResponse.success(imageVideoCozeService.runDouyinCopy(request));
|
||||
}
|
||||
|
||||
@PostMapping("/workflow/run")
|
||||
@@ -77,7 +77,7 @@ public class ImageVideoController {
|
||||
@PostMapping("/voice/list")
|
||||
@Operation(summary = "查看音色")
|
||||
public ApiResponse<Map<String, Object>> listVoices(@Valid @RequestBody ImageVideoVoiceListRequest request) {
|
||||
return ApiResponse.success(imageVideoCozeService.runVoiceList(request.getUserId()));
|
||||
return ApiResponse.success(imageVideoCozeService.runVoiceList(request.getUserId(), request.getName()));
|
||||
}
|
||||
|
||||
@PostMapping("/voice/delete")
|
||||
@@ -89,7 +89,7 @@ public class ImageVideoController {
|
||||
@PostMapping("/voice/clone")
|
||||
@Operation(summary = "音色克隆")
|
||||
public ApiResponse<Map<String, Object>> cloneVoice(@Valid @RequestBody ImageVideoVoiceCloneRequest request) {
|
||||
return ApiResponse.success(imageVideoCozeService.runVoiceClone(request.getUserId(), request.getAudioUrl(), request.getVideoUrl()));
|
||||
return ApiResponse.success(imageVideoCozeService.runVoiceClone(request.getUserId(), request.getName(), request.getAudioUrl(), request.getVideoUrl()));
|
||||
}
|
||||
|
||||
@PostMapping("/voice/synthesis")
|
||||
|
||||
@@ -1,19 +1,58 @@
|
||||
package com.nanri.aiimage.modules.imagevideo.model.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Schema(description = "抖音文案解析和仿写请求")
|
||||
public class DouyinCopyRequest {
|
||||
|
||||
@NotNull(message = "userId 不能为空")
|
||||
@Schema(description = "用户ID", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "文案工作流业务 api_key")
|
||||
@JsonProperty("api_key")
|
||||
@JsonAlias("apiKey")
|
||||
private String apiKey = "";
|
||||
|
||||
@Schema(description = "T8 平台密钥")
|
||||
@JsonProperty("t8_key")
|
||||
@JsonAlias("t8Key")
|
||||
private String t8Key = "";
|
||||
|
||||
@NotBlank(message = "url 不能为空")
|
||||
@Schema(description = "抖音分享口令、短链或视频链接", example = "2.38 复制打开抖音,看看")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "目标视频时长,单位秒", example = "15")
|
||||
private Integer duration;
|
||||
|
||||
@Schema(description = "产品信息")
|
||||
@JsonProperty("proc_info")
|
||||
@JsonAlias("procInfo")
|
||||
private ProcInfo procInfo = new ProcInfo();
|
||||
|
||||
@Data
|
||||
@Schema(description = "抖音文案仿写产品信息")
|
||||
public static class ProcInfo {
|
||||
@Schema(description = "产品类目", example = "连衣裙")
|
||||
private String type = "";
|
||||
|
||||
@Schema(description = "产品名称", example = "亚麻连衣裙")
|
||||
private String name = "";
|
||||
|
||||
@Schema(description = "产品图片 URL 列表")
|
||||
@JsonProperty("proc_image")
|
||||
@JsonAlias("procImage")
|
||||
private List<String> procImage = new ArrayList<>();
|
||||
|
||||
@Schema(description = "核心卖点或产品属性", example = "优雅、亚麻、白色")
|
||||
private String properties = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import lombok.Data;
|
||||
public class ImageVideoVoiceCloneRequest {
|
||||
@NotNull(message = "userId 不能为空")
|
||||
private Long userId;
|
||||
private String name;
|
||||
private String audioUrl;
|
||||
private String videoUrl;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,6 @@ import lombok.Data;
|
||||
public class ImageVideoVoiceListRequest {
|
||||
@NotNull(message = "userId 不能为空")
|
||||
private Long userId;
|
||||
|
||||
private String name;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.config.ImageVideoProperties;
|
||||
import com.nanri.aiimage.modules.file.service.oss.OssStorageService;
|
||||
import com.nanri.aiimage.modules.imagevideo.model.dto.DouyinCopyRequest;
|
||||
import com.nanri.aiimage.modules.imagevideo.model.vo.ImageVideoMediaUploadVo;
|
||||
import com.nanri.aiimage.modules.imagevideo.model.vo.DouyinCopyVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -25,6 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -39,6 +41,9 @@ public class ImageVideoCozeService {
|
||||
"scriptDraft", "script_draft", "rewrittenContent", "rewritten_content",
|
||||
"fullContent", "full_content", "copywriting", "script", "output", "text", "result"
|
||||
);
|
||||
private static final Set<String> IMAGE_VIDEO_MODELS = Set.of(
|
||||
"sdols-2.0", "sdols-2.0-fast", "doubao-seedance-2.0-mini"
|
||||
);
|
||||
|
||||
private final ImageVideoProperties properties;
|
||||
private final ImageVideoSecretService secretService;
|
||||
@@ -47,20 +52,23 @@ public class ImageVideoCozeService {
|
||||
private final ObjectMapper objectMapper;
|
||||
private volatile HttpClient sharedHttpClient;
|
||||
|
||||
public DouyinCopyVo runDouyinCopy(Long userId, String url) {
|
||||
String normalizedUrl = url == null ? "" : url.trim();
|
||||
public DouyinCopyVo runDouyinCopy(DouyinCopyRequest request) {
|
||||
if (request == null) {
|
||||
throw new BusinessException("请求参数不能为空");
|
||||
}
|
||||
String normalizedUrl = request.getUrl() == null ? "" : request.getUrl().trim();
|
||||
if (normalizedUrl.isBlank()) {
|
||||
throw new BusinessException("抖音口令或链接不能为空");
|
||||
}
|
||||
if (looksLikeJsonObject(normalizedUrl)) {
|
||||
throw new BusinessException("请粘贴抖音分享口令或链接,不要粘贴接口返回内容");
|
||||
}
|
||||
if (!isLikelyDouyinSource(normalizedUrl)) {
|
||||
throw new BusinessException("请粘贴包含抖音链接的分享口令");
|
||||
throw new BusinessException("请粘贴视频链接或文案来源链接,不要粘贴接口返回内容");
|
||||
}
|
||||
|
||||
ImageVideoSecretService.ResolvedSecret secret = secretService.requireValid(userId);
|
||||
String responseText = postWorkflow(normalizedUrl, secret.copyApiKey(), secret.t8Key(), secret.cozeToken(),
|
||||
ImageVideoSecretService.ResolvedSecret secret = secretService.resolveForDouyinCopy(request.getUserId());
|
||||
String responseText = postWorkflow(request, normalizedUrl,
|
||||
firstNonBlank(request.getApiKey(), secret.copyApiKey()),
|
||||
firstNonBlank(request.getT8Key(), secret.t8Key()),
|
||||
secret.cozeToken(),
|
||||
workflowConfigService.douyinCopyWorkflowId());
|
||||
return parseDouyinCopyResponse(responseText);
|
||||
}
|
||||
@@ -119,6 +127,32 @@ public class ImageVideoCozeService {
|
||||
normalizedProcInfo.put("proc_image", normalizeStringList(normalizedProcInfo.get("proc_image")));
|
||||
parameters.put("proc_info", normalizedProcInfo);
|
||||
}
|
||||
|
||||
Object videoInfo = parameters.get("video_info");
|
||||
if (videoInfo instanceof Map<?, ?>) {
|
||||
Map<String, Object> normalizedVideoInfo = new LinkedHashMap<>();
|
||||
((Map<?, ?>) videoInfo).forEach((key, value) -> normalizedVideoInfo.put(String.valueOf(key), value));
|
||||
String model = firstNonBlank(asText(normalizedVideoInfo.get("model")), "sdols-2.0-fast");
|
||||
if (!IMAGE_VIDEO_MODELS.contains(model)) {
|
||||
throw new BusinessException("不支持的视频模型: " + model);
|
||||
}
|
||||
normalizedVideoInfo.put("model", model);
|
||||
normalizedVideoInfo.put("draft", !"false".equalsIgnoreCase(asText(normalizedVideoInfo.get("draft"))));
|
||||
parameters.put("video_info", normalizedVideoInfo);
|
||||
}
|
||||
|
||||
Object audioInfo = parameters.get("audio_info");
|
||||
Map<String, Object> normalizedAudioInfo = new LinkedHashMap<>();
|
||||
if (audioInfo instanceof Map<?, ?>) {
|
||||
((Map<?, ?>) audioInfo).forEach((key, value) -> normalizedAudioInfo.put(String.valueOf(key), value));
|
||||
}
|
||||
String audioType = firstNonBlank(asText(normalizedAudioInfo.get("type")), "1");
|
||||
if (!"1".equals(audioType) && !"2".equals(audioType)) {
|
||||
throw new BusinessException("不支持的音频类型: " + audioType);
|
||||
}
|
||||
normalizedAudioInfo.put("audio_url", firstNonBlank(asText(normalizedAudioInfo.get("audio_url"))));
|
||||
normalizedAudioInfo.put("type", Integer.valueOf(audioType));
|
||||
parameters.put("audio_info", normalizedAudioInfo);
|
||||
}
|
||||
|
||||
private List<String> normalizeStringList(Object value) {
|
||||
@@ -144,15 +178,6 @@ public class ImageVideoCozeService {
|
||||
return text.startsWith("{") && text.endsWith("}");
|
||||
}
|
||||
|
||||
private boolean isLikelyDouyinSource(String value) {
|
||||
String text = firstNonBlank(value).toLowerCase();
|
||||
return text.contains("douyin.com")
|
||||
|| text.contains("v.douyin")
|
||||
|| text.contains("iesdouyin")
|
||||
|| text.contains("dou音")
|
||||
|| text.contains("抖音");
|
||||
}
|
||||
|
||||
public Map<String, Object> getImageVideoWorkflowResult(Long userId, String executeId) {
|
||||
String resolvedExecuteId = firstNonBlank(executeId);
|
||||
if (!hasText(resolvedExecuteId)) {
|
||||
@@ -210,10 +235,12 @@ public class ImageVideoCozeService {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> runVoiceList(Long userId) {
|
||||
public Map<String, Object> runVoiceList(Long userId, String name) {
|
||||
ImageVideoSecretService.ResolvedSecret secret = secretService.requireValid(userId);
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("api_key", secret.voiceApiKey());
|
||||
parameters.put("name", firstNonBlank(name));
|
||||
parameters.put("user_id", userId);
|
||||
return postWorkflowParameters("voice list", workflowConfigService.voiceListWorkflowId(), parameters, secret.cozeToken(), false);
|
||||
}
|
||||
|
||||
@@ -222,19 +249,22 @@ public class ImageVideoCozeService {
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("api_key", secret.voiceApiKey());
|
||||
parameters.put("group_id", secret.voiceGroupId());
|
||||
parameters.put("user_id", userId);
|
||||
parameters.put("voice_id", firstNonBlank(voiceId));
|
||||
return postWorkflowParameters("voice delete", workflowConfigService.voiceDeleteWorkflowId(), parameters, secret.cozeToken(), false);
|
||||
}
|
||||
|
||||
public Map<String, Object> runVoiceClone(Long userId, String audioUrl, String videoUrl) {
|
||||
String resolvedAudioUrl = firstNonBlank(audioUrl);
|
||||
public Map<String, Object> runVoiceClone(Long userId, String name, String audioUrl, String videoUrl) {
|
||||
String resolvedVideoUrl = firstNonBlank(videoUrl);
|
||||
String resolvedAudioUrl = firstNonBlank(audioUrl, resolvedVideoUrl);
|
||||
if (!hasText(resolvedAudioUrl) && !hasText(resolvedVideoUrl)) {
|
||||
throw new BusinessException("请上传音频或填写视频链接");
|
||||
}
|
||||
ImageVideoSecretService.ResolvedSecret secret = secretService.requireValid(userId);
|
||||
Map<String, Object> parameters = new LinkedHashMap<>();
|
||||
parameters.put("api_key", secret.voiceApiKey());
|
||||
parameters.put("name", firstNonBlank(name));
|
||||
parameters.put("user_id", userId);
|
||||
parameters.put("audio_url", resolvedAudioUrl);
|
||||
parameters.put("video_url", resolvedVideoUrl);
|
||||
return postWorkflowParameters("voice clone", workflowConfigService.voiceCloneWorkflowId(), parameters, secret.cozeToken(), false);
|
||||
@@ -250,7 +280,7 @@ public class ImageVideoCozeService {
|
||||
return postWorkflowParameters("voice synthesis", workflowConfigService.voiceSynthesisWorkflowId(), parameters, secret.cozeToken(), false);
|
||||
}
|
||||
|
||||
private String postWorkflow(String url, String apiKey, String t8Key, String token, String workflowId) {
|
||||
private String postWorkflow(DouyinCopyRequest request, String url, String apiKey, String t8Key, String token, String workflowId) {
|
||||
String resolvedApiKey = firstNonBlank(apiKey);
|
||||
String resolvedT8Key = firstNonBlank(t8Key);
|
||||
String cozeToken = firstNonBlank(token);
|
||||
@@ -268,6 +298,8 @@ public class ImageVideoCozeService {
|
||||
parameters.put("api_key", resolvedApiKey);
|
||||
parameters.put("t8_key", resolvedT8Key);
|
||||
parameters.put("url", url);
|
||||
parameters.put("duration", normalizeDouyinCopyDuration(request.getDuration()));
|
||||
parameters.put("proc_info", normalizeDouyinCopyProcInfo(request.getProcInfo()));
|
||||
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
String resolvedWorkflowId = firstNonBlank(workflowId, properties.getDouyinCopyWorkflowId());
|
||||
@@ -282,6 +314,30 @@ public class ImageVideoCozeService {
|
||||
return postCozeJson("douyin copy", endpoint, body, cozeToken);
|
||||
}
|
||||
|
||||
private int normalizeDouyinCopyDuration(Integer duration) {
|
||||
if (duration == null || duration < 0) {
|
||||
return 0;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
private Map<String, Object> normalizeDouyinCopyProcInfo(DouyinCopyRequest.ProcInfo procInfo) {
|
||||
Map<String, Object> normalized = new LinkedHashMap<>();
|
||||
if (procInfo == null) {
|
||||
normalized.put("properties", "");
|
||||
normalized.put("type", "");
|
||||
normalized.put("name", "");
|
||||
normalized.put("proc_image", List.of());
|
||||
return normalized;
|
||||
}
|
||||
normalized.put("properties", firstNonBlank(procInfo.getProperties()));
|
||||
normalized.put("type", firstNonBlank(procInfo.getType()));
|
||||
normalized.put("name", firstNonBlank(procInfo.getName()));
|
||||
List<String> images = normalizeStringList(procInfo.getProcImage());
|
||||
normalized.put("proc_image", images);
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private Map<String, Object> postWorkflowParameters(String label, String workflowId, Map<String, Object> parameters,
|
||||
String token, boolean async) {
|
||||
String cozeToken = firstNonBlank(token);
|
||||
|
||||
@@ -103,6 +103,28 @@ public class ImageVideoSecretService {
|
||||
return new ResolvedSecret(cozeToken, copyApiKey, t8Key, voiceApiKey, voiceGroupId);
|
||||
}
|
||||
|
||||
public ResolvedSecret resolveForDouyinCopy(Long userId) {
|
||||
String cozeToken = normalize(properties.getCozeToken());
|
||||
if (!hasText(cozeToken)) {
|
||||
throw new BusinessException("图生视频 Coze 访问令牌未配置");
|
||||
}
|
||||
if (userId == null || userId <= 0) {
|
||||
return new ResolvedSecret(cozeToken, "", "", "", "");
|
||||
}
|
||||
|
||||
ImageVideoSecretEntity row = selectByUserId(userId);
|
||||
if (row == null || row.getExpiresAt() == null || !row.getExpiresAt().isAfter(LocalDateTime.now())) {
|
||||
return new ResolvedSecret(cozeToken, "", "", "", "");
|
||||
}
|
||||
return new ResolvedSecret(
|
||||
cozeToken,
|
||||
decrypt(row.getCopyApiKey()),
|
||||
decrypt(row.getT8Key()),
|
||||
decrypt(row.getVoiceApiKey()),
|
||||
decrypt(row.getVoiceGroupId())
|
||||
);
|
||||
}
|
||||
|
||||
private ImageVideoSecretEntity selectByUserId(Long userId) {
|
||||
return secretMapper.selectOne(new LambdaQueryWrapper<ImageVideoSecretEntity>()
|
||||
.eq(ImageVideoSecretEntity::getUserId, userId)
|
||||
|
||||
@@ -88,6 +88,7 @@ aiimage:
|
||||
endpoint: ${AIIMAGE_OSS_ENDPOINT:oss-cn-hangzhou.aliyuncs.com}
|
||||
public-endpoint: ${AIIMAGE_OSS_PUBLIC_ENDPOINT:oss-cn-hangzhou.aliyuncs.com}
|
||||
bucket: ${AIIMAGE_OSS_BUCKET:nanri-ai-images}
|
||||
image-video-bucket: ${AIIMAGE_IMAGE_VIDEO_OSS_BUCKET:shufu-video}
|
||||
access-key-id: ${AIIMAGE_OSS_ACCESS_KEY_ID:LTAI5tNpyvzMNz9f2dHarsm8}
|
||||
access-key-secret: ${AIIMAGE_OSS_ACCESS_KEY_SECRET:bQSZnFH455i8tzyOgeahJmUzwmhynz}
|
||||
transient-storage:
|
||||
@@ -232,10 +233,10 @@ aiimage:
|
||||
coze-result-buffer-enabled: ${AIIMAGE_SIMILAR_ASIN_COZE_RESULT_BUFFER_ENABLED:true}
|
||||
image-video:
|
||||
coze-base-url: ${AIIMAGE_IMAGE_VIDEO_COZE_BASE_URL:https://api.coze.cn}
|
||||
coze-token: ${AIIMAGE_IMAGE_VIDEO_COZE_TOKEN:}
|
||||
coze-token: ${AIIMAGE_IMAGE_VIDEO_COZE_TOKEN:sat_Ws4VB1caOPasDivpKIvtOySYx3lhKgQ95H3crIh0tBwiNYtPTyi6bqe0pBaRzpVu}
|
||||
coze-workflow-path: ${AIIMAGE_IMAGE_VIDEO_COZE_WORKFLOW_PATH:/v1/workflow/run}
|
||||
coze-connect-timeout-millis: ${AIIMAGE_IMAGE_VIDEO_COZE_CONNECT_TIMEOUT_MILLIS:10000}
|
||||
coze-read-timeout-millis: ${AIIMAGE_IMAGE_VIDEO_COZE_READ_TIMEOUT_MILLIS:600000}
|
||||
coze-read-timeout-millis: ${AIIMAGE_IMAGE_VIDEO_COZE_READ_TIMEOUT_MILLIS:3600000}
|
||||
security:
|
||||
shop-credential-key: ${AIIMAGE_SHOP_CREDENTIAL_KEY:change-me-shop-credential-key}
|
||||
internal-token: ${AIIMAGE_INTERNAL_TOKEN:}
|
||||
|
||||
Reference in New Issue
Block a user