视频图片儿分析模型。
This commit is contained in:
@@ -4,13 +4,17 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.rj.entity.DetectVideoTemplate;
|
||||
import com.rj.mapper.DetectVideoTemplateMapper;
|
||||
import com.rj.service.IDetectVideoTemplateService;
|
||||
import com.rj.service.MinIOService;
|
||||
import com.rj.utils.MinIOUrlGenerator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
@@ -31,6 +35,12 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
@Value("${dashscope.api.key:}")
|
||||
private String apiKey;
|
||||
|
||||
@Autowired
|
||||
private MinIOService minioService;
|
||||
|
||||
@Autowired
|
||||
private MinIOUrlGenerator urlGenerator;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@@ -52,10 +62,11 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
/**
|
||||
* 执行视频模板检测并保存日志
|
||||
*/
|
||||
public DetectVideoTemplate detectVideoTemplateAndSave(String videoUrl, String ownerName, String ownerPhone, String avatarName, String model) {
|
||||
public DetectVideoTemplate detectVideoTemplateAndSave(String videoUrl, String ownerName, String ownerPhone, String templateName, String model) {
|
||||
|
||||
if (apiKey == null || apiKey.trim().isEmpty()) {
|
||||
log.error("DASHSCOPE_API_KEY未配置");
|
||||
return createErrorLog(videoUrl, "DASHSCOPE_API_KEY未配置", ownerName, ownerPhone, avatarName);
|
||||
return createErrorLog(videoUrl, "DASHSCOPE_API_KEY未配置", ownerName, ownerPhone, templateName);
|
||||
}
|
||||
|
||||
// 创建日志记录
|
||||
@@ -65,13 +76,13 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
|
||||
detectVideoTemplate.setRequestId(requestId);
|
||||
// 设置模型名称,如果未提供则使用默认值
|
||||
String modelName = (model != null && !model.trim().isEmpty()) ? model : "video-template-detect";
|
||||
String modelName = (model != null && !model.trim().isEmpty()) ? model : "animate-anyone-template-gen2";
|
||||
detectVideoTemplate.setModel(modelName);
|
||||
log.info("使用模型: {}", modelName);
|
||||
detectVideoTemplate.setVideoUrl(videoUrl);
|
||||
detectVideoTemplate.setOwnerName(ownerName);
|
||||
detectVideoTemplate.setOwnerPhone(ownerPhone);
|
||||
detectVideoTemplate.setAvatarName(avatarName);
|
||||
detectVideoTemplate.setTemplateName(templateName);
|
||||
detectVideoTemplate.setRequestTime(requestTime);
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
@@ -89,20 +100,19 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setBearerAuth(apiKey);
|
||||
// 添加异步调用请求头
|
||||
headers.set("X-DashScope-Async", "enable");
|
||||
log.info("发送视频模板检测请求,requestBody : {}, 请求参数headers: {}", requestBody , headers);
|
||||
|
||||
// 创建请求实体
|
||||
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
|
||||
|
||||
// 发送请求
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
API_URL,
|
||||
HttpMethod.POST,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
|
||||
log.info("发送视频模板检测请求,请求ID: {}, 视频URL: {}", requestId, videoUrl);
|
||||
// 发送请求
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(API_URL, requestEntity, String.class);
|
||||
|
||||
|
||||
|
||||
log.info("发送视频模板检测请求,response: {}, 视频URL: {}", response, videoUrl);
|
||||
|
||||
// 计算处理时间
|
||||
long endTime = System.currentTimeMillis();
|
||||
@@ -121,48 +131,35 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
if (response.getStatusCode() == HttpStatus.OK) {
|
||||
JsonNode jsonResponse = objectMapper.readTree(response.getBody());
|
||||
|
||||
// 根据success字段判断是否成功
|
||||
boolean isSuccess = false;
|
||||
if (jsonResponse.has("output") && jsonResponse.get("output").has("success")) {
|
||||
isSuccess = jsonResponse.get("output").get("success").asBoolean();
|
||||
detectVideoTemplate.setSuccess(isSuccess);
|
||||
|
||||
log.info("视频模板检测结果 - success: {}", isSuccess);
|
||||
} else {
|
||||
// 如果没有success字段,则根据HTTP状态码判断
|
||||
isSuccess = response.getStatusCode().is2xxSuccessful();
|
||||
detectVideoTemplate.setSuccess(isSuccess);
|
||||
}
|
||||
|
||||
// 检查是否有检测到模板
|
||||
// 解析响应数据
|
||||
if (jsonResponse.has("output")) {
|
||||
JsonNode output = jsonResponse.get("output");
|
||||
|
||||
// 解析模板ID
|
||||
if (output.has("template_id")) {
|
||||
String templateId = output.get("template_id").asText();
|
||||
detectVideoTemplate.setTemplateId(templateId);
|
||||
log.info("检测到的模板ID: {}", templateId);
|
||||
// 解析任务ID
|
||||
if (output.has("task_id")) {
|
||||
String taskId = output.get("task_id").asText();
|
||||
detectVideoTemplate.setTaskId(taskId);
|
||||
log.info("任务ID: {}", taskId);
|
||||
}
|
||||
|
||||
// 记录message信息
|
||||
if (output.has("message")) {
|
||||
String message = output.get("message").asText();
|
||||
log.info("检测消息: {}", message);
|
||||
// 解析任务状态
|
||||
if (output.has("task_status")) {
|
||||
String taskStatus = output.get("task_status").asText();
|
||||
detectVideoTemplate.setTaskStatus(taskStatus);
|
||||
log.info("任务状态: {}", taskStatus);
|
||||
|
||||
// 根据任务状态判断是否成功
|
||||
boolean isSuccess = "SUCCESS".equalsIgnoreCase(taskStatus) || "COMPLETED".equalsIgnoreCase(taskStatus);
|
||||
detectVideoTemplate.setSuccess(isSuccess);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 记录请求ID
|
||||
// 记录message信息
|
||||
if (jsonResponse.has("request_id")) {
|
||||
String apiRequestId = jsonResponse.get("request_id").asText();
|
||||
log.info("API请求ID: {}", apiRequestId);
|
||||
}
|
||||
|
||||
// 记录使用情况
|
||||
if (jsonResponse.has("usage")) {
|
||||
JsonNode usage = jsonResponse.get("usage");
|
||||
log.info("使用情况: {}", usage.toString());
|
||||
String request_id = jsonResponse.get("request_id").asText();
|
||||
detectVideoTemplate.setRequestId(request_id);
|
||||
}
|
||||
|
||||
} else {
|
||||
// HTTP状态码不是200,直接标记为失败
|
||||
detectVideoTemplate.setSuccess(false);
|
||||
@@ -224,14 +221,14 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
/**
|
||||
* 创建错误日志
|
||||
*/
|
||||
private DetectVideoTemplate createErrorLog(String videoUrl, String errorMessage, String ownerName, String ownerPhone, String avatarName) {
|
||||
private DetectVideoTemplate createErrorLog(String videoUrl, String errorMessage, String ownerName, String ownerPhone, String templateName) {
|
||||
DetectVideoTemplate detectVideoTemplate = new DetectVideoTemplate();
|
||||
detectVideoTemplate.setRequestId(UUID.randomUUID().toString());
|
||||
detectVideoTemplate.setModel("video-template-detect");
|
||||
detectVideoTemplate.setVideoUrl(videoUrl);
|
||||
detectVideoTemplate.setOwnerName(ownerName);
|
||||
detectVideoTemplate.setOwnerPhone(ownerPhone);
|
||||
detectVideoTemplate.setAvatarName(avatarName);
|
||||
detectVideoTemplate.setTemplateName(templateName);
|
||||
detectVideoTemplate.setRequestTime(LocalDateTime.now());
|
||||
detectVideoTemplate.setResponseTime(LocalDateTime.now());
|
||||
detectVideoTemplate.setSuccess(false);
|
||||
@@ -252,7 +249,7 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
@Override
|
||||
public com.baomidou.mybatisplus.extension.plugins.pagination.Page<DetectVideoTemplate> getPageList(
|
||||
Integer current, Integer size, Boolean success, String startTime, String endTime,
|
||||
String ownerName, String ownerPhone, String avatarName) {
|
||||
String ownerName, String ownerPhone, String templateName) {
|
||||
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<DetectVideoTemplate> page =
|
||||
new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(current, size);
|
||||
@@ -276,8 +273,8 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
if (ownerPhone != null && !ownerPhone.trim().isEmpty()) {
|
||||
queryWrapper.like(DetectVideoTemplate::getOwnerPhone, ownerPhone);
|
||||
}
|
||||
if (avatarName != null && !avatarName.trim().isEmpty()) {
|
||||
queryWrapper.like(DetectVideoTemplate::getAvatarName, avatarName);
|
||||
if (templateName != null && !templateName.trim().isEmpty()) {
|
||||
queryWrapper.like(DetectVideoTemplate::getTemplateName, templateName);
|
||||
}
|
||||
|
||||
// 按请求时间倒序排列
|
||||
@@ -348,4 +345,92 @@ public class DetectVideoTemplateServiceImpl extends ServiceImpl<DetectVideoTempl
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传视频模板文件并进行检测
|
||||
*/
|
||||
@Override
|
||||
public DetectVideoTemplate uploadAndDetectVideoTemplate(MultipartFile file, String userId, String ownerName,
|
||||
String ownerPhone, String templateName, String model, int expiresInSeconds) {
|
||||
try {
|
||||
log.info("开始处理视频模板上传,文件名: {}, 大小: {} bytes, 用户ID: {}",
|
||||
file.getOriginalFilename(), file.getSize(), userId);
|
||||
|
||||
// 1. 验证文件
|
||||
if (file.isEmpty()) {
|
||||
return createErrorLog("", "文件不能为空", ownerName, ownerPhone, templateName);
|
||||
}
|
||||
|
||||
// 验证文件类型
|
||||
String contentType = file.getContentType();
|
||||
if (contentType == null || (!contentType.startsWith("video/"))) {
|
||||
return createErrorLog("", "只支持视频文件格式", ownerName, ownerPhone, templateName);
|
||||
}
|
||||
|
||||
// 验证文件大小(限制为100MB)
|
||||
if (file.getSize() > 100 * 1024 * 1024) {
|
||||
return createErrorLog("", "文件大小不能超过100MB", ownerName, ownerPhone, templateName);
|
||||
}
|
||||
|
||||
// 2. 上传文件到MinIO
|
||||
log.info("开始上传视频文件到MinIO...");
|
||||
String fileUrl = minioService.uploadFile(file);
|
||||
log.info("视频文件上传成功,URL: {}", fileUrl);
|
||||
|
||||
// 3. 生成短链接(临时访问URL)
|
||||
log.info("开始生成短链接,有效期: {}秒", expiresInSeconds);
|
||||
String fileName = extractFileNameFromUrl(fileUrl);
|
||||
MinIOUrlGenerator.UrlInfo urlInfo = urlGenerator.generateTempUrl(fileName, expiresInSeconds);
|
||||
|
||||
if (!urlInfo.isSuccess()) {
|
||||
return createErrorLog(fileUrl, "生成短链接失败: " + urlInfo.getErrorMessage(), ownerName, ownerPhone, templateName);
|
||||
}
|
||||
|
||||
String shortUrl = urlInfo.getUrl();
|
||||
log.info("短链接生成成功: {}", shortUrl);
|
||||
|
||||
// 4. 进行视频模板检测
|
||||
log.info("开始进行视频模板检测,使用模型: {}", model != null ? model : "默认模型");
|
||||
DetectVideoTemplate detectLog = detectVideoTemplateAndSave(shortUrl, ownerName, ownerPhone, templateName, model);
|
||||
|
||||
// 5. 更新日志记录,添加文件信息和临时链接信息
|
||||
detectLog.setVideoUrl(fileUrl);
|
||||
detectLog.setRequestId(detectLog.getRequestId()); // 保持原有的requestId
|
||||
detectLog.setTempUrl(shortUrl);
|
||||
detectLog.setTempUrlExpiresAt(urlInfo.getExpiresAt());
|
||||
// 如果检测日志中有task_id,也保存到数据库
|
||||
if (detectLog.getTaskId() != null) {
|
||||
detectLog.setTaskId(detectLog.getTaskId());
|
||||
}
|
||||
|
||||
// 保存更新后的日志
|
||||
saveDetectVideoTemplateLog(detectLog);
|
||||
|
||||
log.info("视频模板上传和检测处理完成,文件URL: {}, 短链接: {}", fileUrl, shortUrl);
|
||||
return detectLog;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("视频模板上传和检测失败: {}", e.getMessage(), e);
|
||||
return createErrorLog("", "视频模板上传和检测失败: " + e.getMessage(), ownerName, ownerPhone, templateName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从URL中提取文件名
|
||||
*/
|
||||
private String extractFileNameFromUrl(String fileUrl) {
|
||||
if (fileUrl == null || fileUrl.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 从URL中提取文件名
|
||||
// 例如: http://101.35.52.237:19005/car/20251009_105616_48320fc2d8e24f7bb4be66cbb54a6512.jpg
|
||||
// 提取: 20251009_105616_48320fc2d8e24f7bb4be66cbb54a6512.jpg
|
||||
String[] parts = fileUrl.split("/");
|
||||
if (parts.length > 0) {
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user