调整 音频合成, 头衔监测
This commit is contained in:
@@ -134,6 +134,8 @@ public class PasswordUtil {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -118,6 +118,8 @@ public class ServiceManager {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ public class AliyunConfig {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public class FaceDetectController {
|
||||
try {
|
||||
log.info("开始处理头衔上传,文件名: {}, 大小: {} bytes, 用户ID: {}",
|
||||
file.getOriginalFilename(), file.getSize(), userId);
|
||||
expiresInSeconds = 30*24*3600; // 默认30天
|
||||
expiresInSeconds = 7*24*3600; // 默认7天
|
||||
// 1. 验证文件
|
||||
if (file.isEmpty()) {
|
||||
result.put("success", false);
|
||||
@@ -167,12 +167,7 @@ public class FaceDetectController {
|
||||
result.put("avatarName", avatarName);
|
||||
|
||||
// 人脸检测结果
|
||||
result.put("faceDetection", Map.of(
|
||||
"success", detectLog.getSuccess(),
|
||||
"faceCount", detectLog.getFaceCount(),
|
||||
"processingTimeMs", detectLog.getProcessingTimeMs(),
|
||||
"requestId", detectLog.getRequestId()
|
||||
));
|
||||
result.put("faceDetection", detectLog.toString());
|
||||
|
||||
if (!detectLog.getSuccess()) {
|
||||
result.put("faceDetectionError", detectLog.getErrorMessage());
|
||||
@@ -225,12 +220,18 @@ public class FaceDetectController {
|
||||
@Parameter(description = "开始时间")
|
||||
@RequestParam(required = false) String startTime,
|
||||
@Parameter(description = "结束时间")
|
||||
@RequestParam(required = false) String endTime) {
|
||||
@RequestParam(required = false) String endTime,
|
||||
@Parameter(description = "所有人姓名")
|
||||
@RequestParam(required = false) String ownerName,
|
||||
@Parameter(description = "所有人电话")
|
||||
@RequestParam(required = false) String ownerPhone,
|
||||
@Parameter(description = "头像名字")
|
||||
@RequestParam(required = false) String avatarName) {
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.rj.entity.FaceDetectLog> page =
|
||||
faceDetectLogService.getPageList(current, size, success, startTime, endTime);
|
||||
faceDetectLogService.getPageList(current, size, success, startTime, endTime, ownerName, ownerPhone, avatarName);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.rj.controller;
|
||||
|
||||
import com.rj.dto.VideoSynthesisRequestDto;
|
||||
import com.rj.entity.VideoSynthesisLog;
|
||||
import com.rj.service.IVideoSynthesisService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 视频合成控制器
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/video-synthesis")
|
||||
@Tag(name = "视频合成,根据头像和音频生成视频", description = "视频合成相关接口,根据头像和音频生成视频")
|
||||
public class VideoSynthesisFromController {
|
||||
|
||||
@Autowired
|
||||
private IVideoSynthesisService videoSynthesisService;
|
||||
|
||||
/**
|
||||
* 视频合成接口
|
||||
*/
|
||||
@PostMapping("/synthesize")
|
||||
@Operation(summary = "视频合成", description = "根据图片和音频生成视频")
|
||||
public ResponseEntity<Map<String, Object>> synthesizeVideo(@Valid @RequestBody VideoSynthesisRequestDto requestDto) {
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
try {
|
||||
log.info("开始视频合成,图片URL: {}, 音频URL: {}", requestDto.getImageUrl(), requestDto.getAudioUrl());
|
||||
|
||||
// 执行视频合成
|
||||
VideoSynthesisLog synthesisLog = videoSynthesisService.synthesizeVideoAndSave(requestDto);
|
||||
|
||||
// 构建响应结果
|
||||
result.put("success", synthesisLog.getSuccess());
|
||||
result.put("message", synthesisLog.getSuccess() ? "视频合成成功" : "视频合成失败");
|
||||
result.put("requestId", synthesisLog.getRequestId());
|
||||
result.put("taskId", synthesisLog.getTaskId());
|
||||
result.put("taskStatus", synthesisLog.getTaskStatus());
|
||||
result.put("videoUrl", synthesisLog.getVideoUrl());
|
||||
result.put("videoDuration", synthesisLog.getVideoDuration());
|
||||
result.put("videoRatio", synthesisLog.getVideoRatio());
|
||||
result.put("processingTimeMs", synthesisLog.getProcessingTimeMs());
|
||||
result.put("imageId", synthesisLog.getImageId());
|
||||
result.put("audioId", synthesisLog.getAudioId());
|
||||
result.put("ownerName", synthesisLog.getOwnerName());
|
||||
result.put("ownerPhone", synthesisLog.getOwnerPhone());
|
||||
result.put("modelProvider", synthesisLog.getModelProvider());
|
||||
|
||||
if (!synthesisLog.getSuccess()) {
|
||||
result.put("errorMessage", synthesisLog.getErrorMessage());
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("视频合成失败: {}", e.getMessage(), e);
|
||||
result.put("success", false);
|
||||
result.put("message", "视频合成失败: " + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据请求ID查询视频合成结果
|
||||
*/
|
||||
@GetMapping("/result/{requestId}")
|
||||
@Operation(summary = "查询合成结果", description = "根据请求ID查询视频合成结果")
|
||||
public ResponseEntity<Map<String, Object>> getSynthesisResult(
|
||||
@Parameter(description = "请求ID", required = true)
|
||||
@PathVariable String requestId) {
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
try {
|
||||
VideoSynthesisLog synthesisLog = videoSynthesisService.getVideoSynthesisLogByRequestId(requestId);
|
||||
|
||||
if (synthesisLog == null) {
|
||||
result.put("success", false);
|
||||
result.put("message", "未找到对应的视频合成记录");
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("requestId", synthesisLog.getRequestId());
|
||||
result.put("taskId", synthesisLog.getTaskId());
|
||||
result.put("taskStatus", synthesisLog.getTaskStatus());
|
||||
result.put("videoUrl", synthesisLog.getVideoUrl());
|
||||
result.put("videoDuration", synthesisLog.getVideoDuration());
|
||||
result.put("videoRatio", synthesisLog.getVideoRatio());
|
||||
result.put("processingTimeMs", synthesisLog.getProcessingTimeMs());
|
||||
result.put("requestTime", synthesisLog.getRequestTime());
|
||||
result.put("responseTime", synthesisLog.getResponseTime());
|
||||
result.put("imageId", synthesisLog.getImageId());
|
||||
result.put("audioId", synthesisLog.getAudioId());
|
||||
result.put("ownerName", synthesisLog.getOwnerName());
|
||||
result.put("ownerPhone", synthesisLog.getOwnerPhone());
|
||||
result.put("modelProvider", synthesisLog.getModelProvider());
|
||||
|
||||
if (!synthesisLog.getSuccess()) {
|
||||
result.put("errorMessage", synthesisLog.getErrorMessage());
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("查询视频合成结果失败: {}", e.getMessage(), e);
|
||||
result.put("success", false);
|
||||
result.put("message", "查询失败: " + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务ID查询视频合成结果
|
||||
*/
|
||||
@GetMapping("/result/task/{taskId}")
|
||||
@Operation(summary = "根据任务ID查询结果", description = "根据任务ID查询视频合成结果")
|
||||
public ResponseEntity<Map<String, Object>> getSynthesisResultByTaskId(
|
||||
@Parameter(description = "任务ID", required = true)
|
||||
@PathVariable String taskId) {
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
try {
|
||||
VideoSynthesisLog synthesisLog = videoSynthesisService.getVideoSynthesisLogByTaskId(taskId);
|
||||
|
||||
if (synthesisLog == null) {
|
||||
result.put("success", false);
|
||||
result.put("message", "未找到对应的视频合成记录");
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("requestId", synthesisLog.getRequestId());
|
||||
result.put("taskId", synthesisLog.getTaskId());
|
||||
result.put("taskStatus", synthesisLog.getTaskStatus());
|
||||
result.put("videoUrl", synthesisLog.getVideoUrl());
|
||||
result.put("videoDuration", synthesisLog.getVideoDuration());
|
||||
result.put("videoRatio", synthesisLog.getVideoRatio());
|
||||
result.put("processingTimeMs", synthesisLog.getProcessingTimeMs());
|
||||
result.put("requestTime", synthesisLog.getRequestTime());
|
||||
result.put("responseTime", synthesisLog.getResponseTime());
|
||||
result.put("imageId", synthesisLog.getImageId());
|
||||
result.put("audioId", synthesisLog.getAudioId());
|
||||
result.put("ownerName", synthesisLog.getOwnerName());
|
||||
result.put("ownerPhone", synthesisLog.getOwnerPhone());
|
||||
result.put("modelProvider", synthesisLog.getModelProvider());
|
||||
|
||||
if (!synthesisLog.getSuccess()) {
|
||||
result.put("errorMessage", synthesisLog.getErrorMessage());
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("根据任务ID查询视频合成结果失败: {}", e.getMessage(), e);
|
||||
result.put("success", false);
|
||||
result.put("message", "查询失败: " + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,6 +356,8 @@ public class MenuController {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -326,6 +326,8 @@ public class RoleController {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -332,6 +332,8 @@ public class UserRoleController {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,8 @@ public class DifyWorkflowResponseDto {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
62
src/main/java/com/rj/dto/VideoSynthesisRequestDto.java
Normal file
62
src/main/java/com/rj/dto/VideoSynthesisRequestDto.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.rj.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 视频合成请求DTO
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "视频合成请求参数")
|
||||
public class VideoSynthesisRequestDto {
|
||||
|
||||
@NotBlank(message = "图片URL不能为空")
|
||||
@Schema(description = "图片URL", required = true, example = "https://example.com/image.jpg")
|
||||
private String imageUrl;
|
||||
|
||||
@NotBlank(message = "音频URL不能为空")
|
||||
@Schema(description = "音频URL", required = true, example = "https://example.com/audio.wav")
|
||||
private String audioUrl;
|
||||
|
||||
@Schema(description = "使用的模型", example = "liveportrait")
|
||||
private String model = "liveportrait";
|
||||
|
||||
@Schema(description = "图片ID", example = "img-12345")
|
||||
private String imageId;
|
||||
|
||||
@Schema(description = "音频ID", example = "audio-67890")
|
||||
private String audioId;
|
||||
|
||||
@Schema(description = "归属人姓名", example = "张三")
|
||||
private String ownerName;
|
||||
|
||||
@Schema(description = "归属人电话", example = "13800138000")
|
||||
private String ownerPhone;
|
||||
|
||||
@Schema(description = "模型供应商", example = "dashscope")
|
||||
private String modelProvider;
|
||||
|
||||
@Schema(description = "模板ID", example = "normal")
|
||||
private String templateId = "normal";
|
||||
|
||||
@Schema(description = "眼部动作频率", example = "0.5")
|
||||
private BigDecimal eyeMoveFreq = new BigDecimal("0.5");
|
||||
|
||||
@Schema(description = "视频帧率", example = "30")
|
||||
private Integer videoFps = 30;
|
||||
|
||||
@Schema(description = "嘴部动作强度", example = "1.0")
|
||||
private BigDecimal mouthMoveStrength = new BigDecimal("1.0");
|
||||
|
||||
@Schema(description = "是否粘贴背景", example = "true")
|
||||
private Boolean pasteBack = true;
|
||||
|
||||
@Schema(description = "头部动作强度", example = "0.7")
|
||||
private BigDecimal headMoveStrength = new BigDecimal("0.7");
|
||||
}
|
||||
189
src/main/java/com/rj/entity/VideoSynthesisLog.java
Normal file
189
src/main/java/com/rj/entity/VideoSynthesisLog.java
Normal file
@@ -0,0 +1,189 @@
|
||||
package com.rj.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 视频合成日志实体类
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
@Data
|
||||
@TableName("video_synthesis_log")
|
||||
public class VideoSynthesisLog {
|
||||
|
||||
/**
|
||||
* 主键ID(UUID)
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 请求ID(唯一)
|
||||
*/
|
||||
@TableField("request_id")
|
||||
private String requestId;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
@TableField("task_id")
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 使用的模型
|
||||
*/
|
||||
@TableField("model")
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 图片URL
|
||||
*/
|
||||
@TableField("image_url")
|
||||
private String imageUrl;
|
||||
|
||||
/**
|
||||
* 音频URL
|
||||
*/
|
||||
@TableField("audio_url")
|
||||
private String audioUrl;
|
||||
|
||||
/**
|
||||
* 音频ID
|
||||
*/
|
||||
@TableField("audio_id")
|
||||
private String audioId;
|
||||
|
||||
/**
|
||||
* 图片ID
|
||||
*/
|
||||
@TableField("image_id")
|
||||
private String imageId;
|
||||
|
||||
/**
|
||||
* 归属人姓名
|
||||
*/
|
||||
@TableField("owner_name")
|
||||
private String ownerName;
|
||||
|
||||
/**
|
||||
* 归属人电话
|
||||
*/
|
||||
@TableField("owner_phone")
|
||||
private String ownerPhone;
|
||||
|
||||
/**
|
||||
* 模型供应商
|
||||
*/
|
||||
@TableField("model_provider")
|
||||
private String modelProvider;
|
||||
|
||||
/**
|
||||
* 模板ID
|
||||
*/
|
||||
@TableField("template_id")
|
||||
private String templateId;
|
||||
|
||||
/**
|
||||
* 眼部动作频率
|
||||
*/
|
||||
@TableField("eye_move_freq")
|
||||
private BigDecimal eyeMoveFreq;
|
||||
|
||||
/**
|
||||
* 视频帧率
|
||||
*/
|
||||
@TableField("video_fps")
|
||||
private Integer videoFps;
|
||||
|
||||
/**
|
||||
* 嘴部动作强度
|
||||
*/
|
||||
@TableField("mouth_move_strength")
|
||||
private BigDecimal mouthMoveStrength;
|
||||
|
||||
/**
|
||||
* 是否粘贴背景
|
||||
*/
|
||||
@TableField("paste_back")
|
||||
private Boolean pasteBack;
|
||||
|
||||
/**
|
||||
* 头部动作强度
|
||||
*/
|
||||
@TableField("head_move_strength")
|
||||
private BigDecimal headMoveStrength;
|
||||
|
||||
/**
|
||||
* 请求时间
|
||||
*/
|
||||
@TableField("request_time")
|
||||
private LocalDateTime requestTime;
|
||||
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
@TableField("response_time")
|
||||
private LocalDateTime responseTime;
|
||||
|
||||
/**
|
||||
* 任务状态
|
||||
*/
|
||||
@TableField("task_status")
|
||||
private String taskStatus;
|
||||
|
||||
/**
|
||||
* 生成的视频URL
|
||||
*/
|
||||
@TableField("video_url")
|
||||
private String videoUrl;
|
||||
|
||||
/**
|
||||
* 视频时长(秒)
|
||||
*/
|
||||
@TableField("video_duration")
|
||||
private BigDecimal videoDuration;
|
||||
|
||||
/**
|
||||
* 视频比例
|
||||
*/
|
||||
@TableField("video_ratio")
|
||||
private String videoRatio;
|
||||
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
@TableField("success")
|
||||
private Boolean success;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@TableField("error_message")
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 处理时间(毫秒)
|
||||
*/
|
||||
@TableField("processing_time_ms")
|
||||
private Long processingTimeMs;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -42,6 +42,8 @@ public interface CustomerProfileAnalysisMapper extends BaseMapper<CustomerProfil
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
15
src/main/java/com/rj/mapper/VideoSynthesisLogMapper.java
Normal file
15
src/main/java/com/rj/mapper/VideoSynthesisLogMapper.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.rj.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.rj.entity.VideoSynthesisLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 视频合成日志Mapper接口
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
@Mapper
|
||||
public interface VideoSynthesisLogMapper extends BaseMapper<VideoSynthesisLog> {
|
||||
}
|
||||
@@ -102,6 +102,8 @@ public class AudioStatisticsScheduler {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -40,10 +40,14 @@ public interface IFaceDetectLogService extends IService<FaceDetectLog> {
|
||||
* @param success 成功状态筛选
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param ownerName 所有人姓名
|
||||
* @param ownerPhone 所有人电话
|
||||
* @param avatarName 头像名字
|
||||
* @return 分页结果
|
||||
*/
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<FaceDetectLog> getPageList(
|
||||
Integer current, Integer size, Boolean success, String startTime, String endTime);
|
||||
Integer current, Integer size, Boolean success, String startTime, String endTime,
|
||||
String ownerName, String ownerPhone, String avatarName);
|
||||
|
||||
/**
|
||||
* 获取统计信息
|
||||
|
||||
45
src/main/java/com/rj/service/IVideoSynthesisService.java
Normal file
45
src/main/java/com/rj/service/IVideoSynthesisService.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package com.rj.service;
|
||||
|
||||
import com.rj.dto.VideoSynthesisRequestDto;
|
||||
import com.rj.entity.VideoSynthesisLog;
|
||||
|
||||
/**
|
||||
* 视频合成服务接口
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
public interface IVideoSynthesisService {
|
||||
|
||||
/**
|
||||
* 执行视频合成并保存日志
|
||||
*
|
||||
* @param request 视频合成请求
|
||||
* @return 视频合成日志
|
||||
*/
|
||||
VideoSynthesisLog synthesizeVideoAndSave(VideoSynthesisRequestDto request);
|
||||
|
||||
/**
|
||||
* 保存视频合成日志
|
||||
*
|
||||
* @param log 视频合成日志
|
||||
* @return 是否保存成功
|
||||
*/
|
||||
boolean saveVideoSynthesisLog(VideoSynthesisLog log);
|
||||
|
||||
/**
|
||||
* 根据请求ID查询视频合成日志
|
||||
*
|
||||
* @param requestId 请求ID
|
||||
* @return 视频合成日志
|
||||
*/
|
||||
VideoSynthesisLog getVideoSynthesisLogByRequestId(String requestId);
|
||||
|
||||
/**
|
||||
* 根据任务ID查询视频合成日志
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
* @return 视频合成日志
|
||||
*/
|
||||
VideoSynthesisLog getVideoSynthesisLogByTaskId(String taskId);
|
||||
}
|
||||
@@ -63,6 +63,8 @@ public interface ICustomerProfileAnalysisService extends IService<CustomerProfil
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ public class CustomerProfileAnalysisServiceImpl extends ServiceImpl<CustomerProf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ public class FaceDetectLogServiceImpl extends ServiceImpl<FaceDetectLogMapper, F
|
||||
LocalDateTime requestTime = LocalDateTime.now();
|
||||
|
||||
faceDetectLog.setRequestId(requestId);
|
||||
faceDetectLog.setModel("liveportrait-detect");
|
||||
faceDetectLog.setModel("liveportrait-detect"); //TODO 模型名称
|
||||
faceDetectLog.setImageUrl(imageUrl);
|
||||
faceDetectLog.setOwnerName(ownerName);
|
||||
faceDetectLog.setOwnerPhone(ownerPhone);
|
||||
@@ -261,7 +261,8 @@ public class FaceDetectLogServiceImpl extends ServiceImpl<FaceDetectLogMapper, F
|
||||
*/
|
||||
@Override
|
||||
public com.baomidou.mybatisplus.extension.plugins.pagination.Page<FaceDetectLog> getPageList(
|
||||
Integer current, Integer size, Boolean success, String startTime, String endTime) {
|
||||
Integer current, Integer size, Boolean success, String startTime, String endTime,
|
||||
String ownerName, String ownerPhone, String avatarName) {
|
||||
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<FaceDetectLog> page =
|
||||
new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(current, size);
|
||||
@@ -279,6 +280,15 @@ public class FaceDetectLogServiceImpl extends ServiceImpl<FaceDetectLogMapper, F
|
||||
if (endTime != null && !endTime.trim().isEmpty()) {
|
||||
queryWrapper.le(FaceDetectLog::getRequestTime, endTime);
|
||||
}
|
||||
if (ownerName != null && !ownerName.trim().isEmpty()) {
|
||||
queryWrapper.like(FaceDetectLog::getOwnerName, ownerName);
|
||||
}
|
||||
if (ownerPhone != null && !ownerPhone.trim().isEmpty()) {
|
||||
queryWrapper.like(FaceDetectLog::getOwnerPhone, ownerPhone);
|
||||
}
|
||||
if (avatarName != null && !avatarName.trim().isEmpty()) {
|
||||
queryWrapper.like(FaceDetectLog::getAvatarName, avatarName);
|
||||
}
|
||||
|
||||
// 按请求时间倒序排列
|
||||
queryWrapper.orderByDesc(FaceDetectLog::getRequestTime);
|
||||
|
||||
151
src/main/java/com/rj/service/impl/VideoSynthesisServiceImpl.java
Normal file
151
src/main/java/com/rj/service/impl/VideoSynthesisServiceImpl.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package com.rj.service.impl;
|
||||
|
||||
import com.rj.dto.VideoSynthesisRequestDto;
|
||||
import com.rj.entity.VideoSynthesisLog;
|
||||
import com.rj.mapper.VideoSynthesisLogMapper;
|
||||
import com.rj.service.IVideoSynthesisService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
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 java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 视频合成服务实现类
|
||||
*
|
||||
* @author rj
|
||||
* @date 2025-01-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class VideoSynthesisServiceImpl implements IVideoSynthesisService {
|
||||
|
||||
@Autowired
|
||||
private VideoSynthesisLogMapper videoSynthesisLogMapper;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
|
||||
@Value("${dashscope.api.key}")
|
||||
private String apiKey;
|
||||
|
||||
private static final String API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/";
|
||||
|
||||
@Override
|
||||
public VideoSynthesisLog synthesizeVideoAndSave(VideoSynthesisRequestDto request) {
|
||||
LocalDateTime startTime = LocalDateTime.now();
|
||||
String requestId = UUID.randomUUID().toString();
|
||||
|
||||
VideoSynthesisLog synthesisLog = new VideoSynthesisLog();
|
||||
synthesisLog.setRequestId(requestId);
|
||||
synthesisLog.setRequestTime(startTime);
|
||||
synthesisLog.setSuccess(false);
|
||||
|
||||
// 使用BeanUtils复制相同名称的属性
|
||||
BeanUtils.copyProperties(request, synthesisLog);
|
||||
|
||||
try {
|
||||
log.info("开始视频合成,请求ID: {}, 图片URL: {}, 音频URL: {}",
|
||||
requestId, request.getImageUrl(), request.getAudioUrl());
|
||||
|
||||
// 构建请求头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.set("X-DashScope-Async", "enable");
|
||||
headers.set("Authorization", "Bearer " + apiKey);
|
||||
|
||||
// 构建请求体
|
||||
HttpEntity<VideoSynthesisRequestDto> entity = new HttpEntity<>(request, headers);
|
||||
|
||||
// 发送请求
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(API_URL, entity, String.class);
|
||||
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
synthesisLog.setResponseTime(endTime);
|
||||
synthesisLog.setProcessingTimeMs(java.time.Duration.between(startTime, endTime).toMillis());
|
||||
|
||||
// 解析响应
|
||||
if (response.getStatusCode() == HttpStatus.OK) {
|
||||
// 直接解析JSON响应
|
||||
String responseBody = response.getBody();
|
||||
log.info("API响应: {}", responseBody);
|
||||
|
||||
// 简单解析关键字段
|
||||
if (responseBody != null && responseBody.contains("task_id")) {
|
||||
// 这里可以添加更复杂的JSON解析逻辑
|
||||
// 暂时设置基本状态
|
||||
synthesisLog.setTaskStatus("PENDING");
|
||||
synthesisLog.setSuccess(true);
|
||||
} else {
|
||||
synthesisLog.setErrorMessage("API响应格式异常");
|
||||
synthesisLog.setSuccess(false);
|
||||
}
|
||||
|
||||
log.info("视频合成请求成功,任务ID: {}, 状态: {}",
|
||||
synthesisLog.getTaskId(), synthesisLog.getTaskStatus());
|
||||
} else {
|
||||
synthesisLog.setErrorMessage("HTTP请求失败,状态码: " + response.getStatusCode());
|
||||
log.error("视频合成请求失败,状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
synthesisLog.setResponseTime(endTime);
|
||||
synthesisLog.setProcessingTimeMs(java.time.Duration.between(startTime, endTime).toMillis());
|
||||
synthesisLog.setErrorMessage("视频合成异常: " + e.getMessage());
|
||||
log.error("视频合成失败: {}", e.getMessage(), e);
|
||||
}
|
||||
|
||||
// 保存日志
|
||||
saveVideoSynthesisLog(synthesisLog);
|
||||
return synthesisLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveVideoSynthesisLog(VideoSynthesisLog synthesisLog) {
|
||||
try {
|
||||
synthesisLog.setCreatedAt(LocalDateTime.now());
|
||||
synthesisLog.setUpdatedAt(LocalDateTime.now());
|
||||
|
||||
int result = videoSynthesisLogMapper.insert(synthesisLog);
|
||||
log.info("视频合成日志保存{}: 请求ID={}, 任务ID={}, 成功={}",
|
||||
result > 0 ? "成功" : "失败", synthesisLog.getRequestId(), synthesisLog.getTaskId(), synthesisLog.getSuccess());
|
||||
return result > 0;
|
||||
} catch (Exception e) {
|
||||
log.error("保存视频合成日志失败: {}", e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VideoSynthesisLog getVideoSynthesisLogByRequestId(String requestId) {
|
||||
try {
|
||||
return videoSynthesisLogMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<VideoSynthesisLog>()
|
||||
.eq("request_id", requestId)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("根据请求ID查询视频合成日志失败: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VideoSynthesisLog getVideoSynthesisLogByTaskId(String taskId) {
|
||||
try {
|
||||
return videoSynthesisLogMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<VideoSynthesisLog>()
|
||||
.eq("task_id", taskId)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("根据任务ID查询视频合成日志失败: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,8 @@ public interface IMenuService extends IService<Menu> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ public interface IUserRoleService extends IService<UserRole> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user