瀏覽代碼

修改视频创建逻辑、新增图片检查接口、新增百度API接口、修改上传阿里云检查、新增回调接口

private_deployment
lrh 1 年之前
父節點
當前提交
82eeafccc6
共有 16 個檔案被更改,包括 315 行新增23 行删除
  1. +21
    -4
      suimangCApi/src/main/java/com/iformall/controller/PersonPhotoController.java
  2. +46
    -1
      suimangCApi/src/main/java/com/iformall/controller/VideoCallbackController.java
  3. +115
    -0
      suimangCApi/src/main/java/com/iformall/utils/BaiduImageCheckUtil.java
  4. +77
    -0
      suimangCApi/src/main/java/com/iformall/utils/HttpUtil.java
  5. +2
    -1
      suimangCApi/src/main/java/com/iformall/utils/UrlCheck.java
  6. +4
    -1
      suimangCApi/src/main/resources/application-dev.yml
  7. +4
    -1
      suimangCApi/src/main/resources/application-prod.yml
  8. +1
    -0
      suimangService/src/main/java/com/iformall/common/ErrorCode.java
  9. +0
    -2
      suimangService/src/main/java/com/iformall/enums/EnumVideoStatus.java
  10. +31
    -2
      suimangService/src/main/java/com/iformall/service/sm/impl/PhotoSpeakVideoServiceImpl.java
  11. +2
    -2
      suimangService/src/main/java/com/iformall/sm/AiCheckPhotoResult.java
  12. +5
    -1
      suimangService/src/main/java/com/iformall/sm/AiPhotoSpeakParam.java
  13. +2
    -2
      suimangService/src/main/java/com/iformall/sm/AiPhotoSpeakResult.java
  14. +2
    -2
      suimangService/src/main/java/com/iformall/sm/AiPreviewResult.java
  15. +3
    -2
      suimangService/src/main/java/com/iformall/sm/AiVideoHqResult.java
  16. +0
    -2
      suimangVideo/src/main/java/com/iformall/video/VideoExcutor.java

+ 21
- 4
suimangCApi/src/main/java/com/iformall/controller/PersonPhotoController.java 查看文件

@@ -5,14 +5,12 @@ import com.iformall.annotation.AuthIgnore;
import com.iformall.common.ErrorCode;
import com.iformall.common.ResultData;
import com.iformall.domain.po.base.BaseEntity;
import com.iformall.domain.po.sm.MaterialMould;
import com.iformall.domain.po.sm.PersonPhoto;
import com.iformall.enums.EnumMouldPatchType;
import com.iformall.enums.EnumMouldSendType;
import com.iformall.enums.EnumaMouldPatchStatus;
import com.iformall.service.sm.MaterialMouldService;
import com.iformall.service.sm.MouldPatchSignService;
import com.iformall.service.sm.PersonPhotoService;
import com.iformall.utils.BaiduImageCheckUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -23,6 +21,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


@RestController
@@ -97,7 +96,25 @@ public class PersonPhotoController extends BaseController {
if (data.code == 2000) {
return new ResultData();
}
return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), data.message);
return new ResultData(data.message);
}

@AuthIgnore
@ApiOperation("百度图片审核接口")
@PostMapping(value = "baiduPhoto", consumes = "multipart/*", headers = "content-type=multipart/form-data")
@ApiImplicitParam(name = "material", value = "material", dataType = "String", paramType = "query", required = true)
public ResultData baiduCheckPhoto(@RequestPart("file") MultipartFile file) {
logger.debug("[" + getIpAddr() + "] PersonPhotoController::baiduCheckPhoto");
if (ObjectUtils.isEmpty(file) || file.getSize() <= 0) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "素材为空");
}
long size = file.getSize();
final long length = 4 * 1024 * 1024;
if (size > length) {
return new ResultData(ErrorCode.PICTURE_FOUR_SIZE_EXCEED);
}
String result = BaiduImageCheckUtil.photoCheck(file);
return new ResultData(result);
}




+ 46
- 1
suimangCApi/src/main/java/com/iformall/controller/VideoCallbackController.java 查看文件

@@ -1,6 +1,7 @@
package com.iformall.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.api.R;
import com.github.pagehelper.PageInfo;
import com.iformall.annotation.AuthIgnore;
import com.iformall.common.ErrorCode;
@@ -16,12 +17,14 @@ import com.iformall.service.sm.MusicInfoService;
import com.iformall.service.sm.PhotoSpeakVideoService;
import com.iformall.service.sm.VoiceInfoService;
import com.iformall.video.VideoFactory;
import com.iformall.video.aliyun.sdk.server.UploadCacheHelper;
import com.iformall.video.entity.VideUploadResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -58,14 +61,56 @@ public class VideoCallbackController extends BaseController {
logger.debug("[" + getIpAddr() + "] VideoCallbackController::photoSpeak");
logger.info("照片生成视频结果通知{}"+JSONObject.toJSONString(paranMap));
String task_id = (String) paranMap.get("task_id");//任务ID
Integer code = (Integer) paranMap.get("code");//任务ID
Integer code = (Integer) paranMap.get("code");//code
String msg = (String) paranMap.get("msg");

Map<String, Object> data = (HashMap) paranMap.get("data");
String url = (String) data.get("url");
String save_dir = (String) data.get("save_dir");
Boolean sr = (Boolean) data.get("sr");//判断 sr=True 就是超分的, False 是没超分的

PhotoSpeakVideo photoSpeakVideo = photoSpeakVideoService.getById(Long.valueOf(task_id));
if (photoSpeakVideo == null){
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"未找到任务数据");
}

if (code != 4000){
String returnMsg;
if (sr){
photoSpeakVideo.setVideoHyStatus(EnumVideoStatus.fail.getCode());
returnMsg = "超分视频生成失败";
}else {
photoSpeakVideo.setVideoStatus(EnumVideoStatus.fail.getCode());
returnMsg = "视频生成失败";
}
photoSpeakVideo.setVideoMsg(msg);
photoSpeakVideo.setUpdateDate(new Date());
photoSpeakVideoService.updateById(photoSpeakVideo);
return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),returnMsg);
}

if (StringUtils.isEmpty(task_id)){
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"任务ID不能为空");
}

if (StringUtils.isEmpty(url)){
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"视频URL不能为空");
}

if (!save_dir.equals(photoSpeakVideo.getSaveDir())){
return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"save_dir参数不一致");
}

if (sr){
photoSpeakVideo.setVideoHyStatus(EnumVideoStatus.success.getCode());
}else {
photoSpeakVideo.setVideoStatus(EnumVideoStatus.success.getCode());
}
photoSpeakVideo.setVideoMsg("success");
photoSpeakVideo.setUpdateDate(new Date());
photoSpeakVideoService.updateById(photoSpeakVideo);
//TODO 用户相关操作
photoSpeakVideoService.uploadVideo(photoSpeakVideo);
return new ResultData();
}



+ 115
- 0
suimangCApi/src/main/java/com/iformall/utils/BaiduImageCheckUtil.java 查看文件

@@ -0,0 +1,115 @@
package com.iformall.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Base64;

/**
* 图片质量检查方法
*/
public class BaiduImageCheckUtil {
// 百度图片审核接口地址
private final static String photo_check_url = "https://aip.baidubce.com/rest/2.0/solution/v1/img_censor/v2/user_defined";
// 获取token
private final static String auth_url = "https://aip.baidubce.com/oauth/2.0/token?";
// 百度API Key
private final static String apiKey = "Your API Key";
// 百度Secret Key
private final static String secretKey = "Your Secret Key";
//写死的 access_token
private final static String access_token = "24.c1c7992795301773c60c8cf01abfe759.2592000.1689236723.282335-33618414";

public static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

public static String photoCheck(MultipartFile file) {
try {
byte[] fileBytes = file.getBytes();
String imgStr = Base64Util.encode(fileBytes);
String imageUrl = URLEncoder.encode(imgStr, "UTF-8");
String param = "image=" + imageUrl;
// 注意这里access_token有过期时间, 客户端可自行缓存,过期后重新获取。
// Access Token的有效期(秒为单位,有效期30天)
// String accessToken = getAuth();
//这里暂时写死
String result = HttpUtil.post(photo_check_url, access_token, param);
System.out.println(result);
JSONObject jsonObject = JSON.parseObject(result);
//1:合规,2:不合规,3:疑似,4:审核失败
Integer type = jsonObject.getInteger("conclusionType");
String msg;
if (type == 1) {
msg = "图片合规";
} else if (type == 2 || type == 3) {
msg = "图片不合规";
} else if (type == 4) {
msg = "图片审核失败";
} else {
msg = "图片审核失败";
}
return msg;
} catch (Exception e) {
e.printStackTrace();
}
return "图片审核接口请求失败";
}

/**
* 将阿里云图片地址转为字节码
*/
public static String aliyunImageToByteArray(String imageUrl) throws IOException {
InputStream inputStream = null;
try {
// 创建URL对象
URL url = new URL(imageUrl);
// 打开连接
URLConnection conn = url.openConnection();
// 获取输入流
inputStream = conn.getInputStream();
// 将输入流转换为字节数组
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteStream.write(buffer, 0, bytesRead);
}
inputStream.close();
byte[] byteArray = byteStream.toByteArray();
String imgStr = Base64Util.encode(byteArray);
return URLEncoder.encode(imgStr, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
if (inputStream != null) {
inputStream.close();
}
}
return null;
}

/**
* 获取API访问权限token,该token有一定的有效期,需要自行管理,当失效时需重新获取。
* Access Token的有效期(秒为单位,有效期30天)
*/
public static String getAuth() throws IOException {
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
.url(auth_url + "client_id=" + apiKey + "&client_secret= " + secretKey + "&grant_type=client_credentials")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
Response response = HTTP_CLIENT.newCall(request).execute();
System.out.println(response.body().string());
return response.body().string();
}
}

+ 77
- 0
suimangCApi/src/main/java/com/iformall/utils/HttpUtil.java 查看文件

@@ -0,0 +1,77 @@
package com.iformall.utils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
* http 工具类
*/
public class HttpUtil {

public static String post(String requestUrl, String accessToken, String params)
throws Exception {
String contentType = "application/x-www-form-urlencoded";
return HttpUtil.post(requestUrl, accessToken, contentType, params);
}

public static String post(String requestUrl, String accessToken, String contentType, String params)
throws Exception {
String encoding = "UTF-8";
if (requestUrl.contains("nlp")) {
encoding = "GBK";
}
return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
}

public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
throws Exception {
String url = requestUrl + "?access_token=" + accessToken;
return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
}

public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
throws Exception {
URL url = new URL(generalUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
// 设置通用的请求属性
connection.setRequestProperty("Content-Type", contentType);
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);

// 得到请求的输出流对象
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(params.getBytes(encoding));
out.flush();
out.close();

// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> headers = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : headers.keySet()) {
System.err.println(key + "--->" + headers.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = null;
in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), encoding));
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
System.err.println("result:" + result);
return result;
}
}

+ 2
- 1
suimangCApi/src/main/java/com/iformall/utils/UrlCheck.java 查看文件

@@ -10,7 +10,8 @@ public class UrlCheck {
|| url.contains("awsFilesUpload")
|| url.contains("awsImgUpload")
|| url.contains("getCarStopFee")
|| url.contains("/video/upload");
|| url.contains("/video/upload")
|| url.contains("/personPhoto/baiduPhoto");
}

}

+ 4
- 1
suimangCApi/src/main/resources/application-dev.yml 查看文件

@@ -186,4 +186,7 @@ fm:
logging:
level:
com.iformall: debug
path: ./logs/c
path: ./logs/c

photo:
callbackUrl: https://phototest.metavatar.cc/C

+ 4
- 1
suimangCApi/src/main/resources/application-prod.yml 查看文件

@@ -141,4 +141,7 @@ fm:
logging:
level:
com.iformall: debug
path: ./logs/c
path: ./logs/c

photo:
callbackUrl: https://photo.metavatar.cc/C

+ 1
- 0
suimangService/src/main/java/com/iformall/common/ErrorCode.java 查看文件

@@ -609,6 +609,7 @@ public enum ErrorCode{
PICTURE_SIZE_CUSTOMIZE(40003, "图片超过大小限制"),
PICTURE_W_H_CUSTOMIZE(40004, "图片不符合宽高限制"),
PICTURE_ENDWIDTH_ERROR(40005, "格式只支持.mp3,.mp4"),
PICTURE_FOUR_SIZE_EXCEED(40006, "图片超过4M限制"),

/**
* 电费生成配置


+ 0
- 2
suimangService/src/main/java/com/iformall/enums/EnumVideoStatus.java 查看文件

@@ -16,8 +16,6 @@ public enum EnumVideoStatus {
upload_ing(4,"上传视频中"),
upload_success(5,"上传视频成功"),
upload_fail(6,"上传视频失败")
//TODO 接口调用成功、失败状态

;

public static EnumVideoStatus getEnum(Integer code) {


+ 31
- 2
suimangService/src/main/java/com/iformall/service/sm/impl/PhotoSpeakVideoServiceImpl.java 查看文件

@@ -17,11 +17,15 @@ import com.iformall.sm.*;
import com.iformall.utils.Base64Util;
import com.iformall.utils.DateUtils;
import com.iformall.video.VideoFactory;
import com.iformall.video.aliyun.sdk.server.UploadCacheHelper;
import com.iformall.video.entity.VideUploadResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
@@ -33,6 +37,7 @@ import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;


@Service
@@ -75,8 +80,15 @@ public class PhotoSpeakVideoServiceImpl implements PhotoSpeakVideoService {
@Autowired
private UserCreditLogService userCreditLogService;

@Autowired
@Qualifier("objectCommonRedisTemplate")
RedisTemplate<String, Object> redisTemplate;

private final static String str = "\uD83D\uDD57";

@Value("photo.callbackUrl")
private String callbackUrl;

@Override
public PageInfo<PhotoSpeakVideo> listAsPage(PhotoSpeakVideo record, Integer pageIndex, Integer pageSize) {
return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> photoSpeakVideoMapper.findList(record));
@@ -181,6 +193,8 @@ public class PhotoSpeakVideoServiceImpl implements PhotoSpeakVideoService {
public ResultData createVideo(PhotoSpeakVideo photoSpeakVideo) {
try {
AiPhotoSpeakParam param = new AiPhotoSpeakParam();
param.setTask_id(photoSpeakVideo.getId());
param.setCallback_url(callbackUrl + "/callback/photo/speak");
param.setImg(Base64Util.imageUrlToBase64(photoSpeakVideo.getPersonPhotoUrl()));
param.setVoice_id(photoSpeakVideo.getVoiceMouldSm() == null ? "default" : photoSpeakVideo.getVoiceMouldSm());
String voiceMouldSm = photoSpeakVideo.getVoiceMouldSm();
@@ -226,12 +240,14 @@ public class PhotoSpeakVideoServiceImpl implements PhotoSpeakVideoService {
} catch (Exception e) {
e.printStackTrace();
photoSpeakVideo.setVideoStatus(EnumVideoStatus.draft.getCode());
photoSpeakVideo.setVideoMsg("第三方接口请求异常");
photoSpeakVideo.setVideoMsg("口请求异常");
this.saveOrUpdate(photoSpeakVideo);
return new ResultData(ErrorCode.SYS_PARAMETER_ERROR.getCode(),"接口请求异常");
}
}


@Async
@Override
public void uploadVideo(PhotoSpeakVideo mouldVideo){
if(EnumVideoStatus.success.getCode().equals(mouldVideo.getVideoStatus())
@@ -244,6 +260,19 @@ public class PhotoSpeakVideoServiceImpl implements PhotoSpeakVideoService {
videoUpd.setVideoId(result.getVideoId());
videoUpd.setVideoStatus(EnumVideoStatus.upload_ing.getCode());
this.saveOrUpdate(videoUpd);

AtomicInteger integer = new AtomicInteger(30);
while (true){
String progress = videoFactory.getExcutor(videoType).getVedioUploadProgress(result.getVideoId());
if (progress.equals("complete")) {
mouldVideo.setVideoStatus(EnumVideoStatus.upload_success.getCode());
this.updateById(mouldVideo);
break;
}
if (integer.getAndDecrement() <= 0){
break;
}
}
}
}
}
@@ -297,7 +326,7 @@ public class PhotoSpeakVideoServiceImpl implements PhotoSpeakVideoService {
}

speakVideo.setVideoHyStatus(EnumVideoStatus.fail.getCode());
speakVideo.setVideoMsg("超分视频失败");
speakVideo.setVideoMsg("视频超分失败");
this.updateById(speakVideo);
}



+ 2
- 2
suimangService/src/main/java/com/iformall/sm/AiCheckPhotoResult.java 查看文件

@@ -12,7 +12,7 @@ public class AiCheckPhotoResult {

public String getMsgInfo(Integer code,String msg){
if (code == 10 && msg.equals("unknown error")) {
return "系统服务异常";
return "服务被Avatar攻击... 点击“编辑”重试";
}else if (code == 2000 && msg.equals("success")){
return "成功";
}else if (code == 2001 && msg.equals("no face")){
@@ -26,7 +26,7 @@ public class AiCheckPhotoResult {
}else if (code == 2005 && msg.equals("Sensitive people")){
return "图片中人物可能是敏感人物,比如是政要或者明星";
}else {
return msg;
return "系统繁忙,请稍后重试";
}
}
}

+ 5
- 1
suimangService/src/main/java/com/iformall/sm/AiPhotoSpeakParam.java 查看文件

@@ -23,6 +23,8 @@ public class AiPhotoSpeakParam {
private String gender;
private String url;
private String img;
private Long task_id;
private String callback_url;

public String neglectImgString() {
StringBuffer str = new StringBuffer();
@@ -32,7 +34,9 @@ public class AiPhotoSpeakParam {
str.append("\"voice_style\":").append("\"").append(voice_style).append("\",");
str.append("\"gender\":").append("\"").append(gender).append("\",");
str.append("\"url\":").append("\"").append(url).append("\",");
str.append("\"img\":").append("\"").append(img).append("\"}");
str.append("\"img\":").append("\"").append(img);
str.append("\"task_id\":").append("\"").append(task_id);
str.append("\"callback_url\":").append("\"").append(callback_url).append("\"}");
return str.toString();
}
}

+ 2
- 2
suimangService/src/main/java/com/iformall/sm/AiPhotoSpeakResult.java 查看文件

@@ -20,9 +20,9 @@ public class AiPhotoSpeakResult {
} else if (code == 3008 && msg.equals("check languages")) {
return "文字和语种不对应";
} else if (msg.equals("unknown error")) {
return "系统服务异常";
return "服务被Avatar攻击... 点击“编辑”重试";
} else {
return msg;
return "系统繁忙,请稍后重试";
}
}
}

+ 2
- 2
suimangService/src/main/java/com/iformall/sm/AiPreviewResult.java 查看文件

@@ -22,9 +22,9 @@ public class AiPreviewResult {
} else if (code == 3008 && msg.equals("check languages")) {
return "文字和语种不对应";
} else if (msg.equals("unknown error")) {
return "系统服务异常";
return "服务被Avatar攻击... 点击“编辑”重试";
} else {
return msg;
return "系统繁忙,请稍后重试";
}
}
}

+ 3
- 2
suimangService/src/main/java/com/iformall/sm/AiVideoHqResult.java 查看文件

@@ -13,9 +13,10 @@ public class AiVideoHqResult {
if (code == 5000 && msg.equals("success")) {
return "成功";
} else if (msg.equals("unknown error")) {
return "系统服务异常";
return "服务被Avatar攻击... 点击“编辑”重试";
}else {
return "系统繁忙,请稍后重试";
}
return msg;
}

}

+ 0
- 2
suimangVideo/src/main/java/com/iformall/video/VideoExcutor.java 查看文件

@@ -1,11 +1,9 @@
package com.iformall.video;

import java.io.File;
import java.io.InputStream;

import com.iformall.video.entity.VideTransResult;
import com.iformall.video.entity.VideUploadResult;
import org.apache.commons.lang3.StringUtils;

public interface VideoExcutor {



Loading…
取消
儲存