vlog/book-api/src/main/java/com/imooc/controller/VlogController.java
2025-05-02 14:05:58 +08:00

362 lines
16 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.imooc.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.base.BaseInfoProperties;
import com.imooc.bo.VlogBO;
import com.imooc.config.MinIOConfig;
import com.imooc.enums.YesOrNo;
import com.imooc.grace.result.GraceJSONResult;
import com.imooc.service.VlogService;
import com.imooc.utils.MinIOUtils;
import com.imooc.utils.PagedGridResult;
import com.qcloud.vod.model.VodUploadResponse;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import com.imooc.utils.QcCloud;
import java.util.List;
import java.util.Map;
@Slf4j
@Api(tags = "VlogController 短视频相关业务功能的接口")
@RequestMapping("vlog")
@RestController
@RefreshScope
public class VlogController extends BaseInfoProperties {
@Autowired
private VlogService vlogService;
@Autowired
private QcCloud qcCloud;
@Autowired
private MinIOConfig minIOConfig;
@PostMapping("vodCallBack")
public GraceJSONResult vodCallBack(@RequestBody Map<String, Object> callbackData) {
try {
// 解析回调事件类型
String eventType = (String) callbackData.get("EventType");
log.info("收到腾讯云 VOD 回调, 事件类型: {}", eventType);
log.info(callbackData.toString());
if ("ProcedureStateChanged".equals(eventType)) {
// 获取 ProcedureStateChangeEvent
Object eventObject = callbackData.get("ProcedureStateChangeEvent");
if (eventObject instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> procedureStateChangeEvent = (Map<String, Object>) eventObject;
String fileId = (String) procedureStateChangeEvent.get("FileId");
String fileUrl = (String) procedureStateChangeEvent.get("FileUrl"); // 原视频地址
String status = (String) procedureStateChangeEvent.get("Status"); // FINISH
// 只处理完成状态
if ("FINISH".equals(status)) {
// 获取 MediaProcessResultSet可能包含任务流信息
List<Map<String, Object>> mediaProcessResultSet =
(List<Map<String, Object>>) procedureStateChangeEvent.get("MediaProcessResultSet");
if (mediaProcessResultSet != null) {
String coverUrl=null; // 首帧图
String transVdUrl=null; // 转码后的视频地址
for (Map<String, Object> processResult : mediaProcessResultSet) {
String type = (String) processResult.get("Type");
if ("CoverBySnapshot".equals(type)) {
// 任务流:首帧截图
Map<String, Object> coverBySnapshotTask =
(Map<String, Object>) processResult.get("CoverBySnapshotTask");
Map<String, Object> output = (Map<String, Object>) coverBySnapshotTask.get("Output");
coverUrl = (String) output.get("CoverUrl"); // 正确获取 CoverUrl
}
if("Transcode".equals(type)){
// 拿到output中的url
Map<String, Object> TranscodeTask =
(Map<String, Object>) processResult.get("TranscodeTask");
Map<String, Object> output = (Map<String, Object>) TranscodeTask.get("Output");
transVdUrl = (String) output.get("Url");
}
}
log.info("任务流 [截取首帧,视频转码] 完成, FileId: {}, 封面图 URL: {},视频地址: {}", fileId, coverUrl,transVdUrl);
// TODO: 更新数据库,存储首帧图,设置云端地址删除minio视频文件
vlogService.updateVlogFirstImg(fileId,coverUrl,transVdUrl);
} else {
log.warn("MediaProcessResultSet 为空,回调数据: {}", callbackData);
}
}
log.info("任务流完成, FileId: {}, Status: {}", fileId, status);
} else {
log.warn("ProcedureStateChangeEvent 为空或格式错误,回调数据: {}", callbackData);
}
}
if("ReviewAudioVideoComplete".equals(eventType)){
//处理审核结果
Map<String, Object> reviewEvent = (Map<String, Object>) callbackData.get("ReviewAudioVideoCompleteEvent");
if (reviewEvent != null) {
String status = (String) reviewEvent.get("Status"); // FINISH
if ("FINISH".equals(status)) {
Map<String, Object> input = (Map<String, Object>) reviewEvent.get("Input");
String fileId = (String) input.get("FileId"); // 查询的唯一标识
// 获取审核结果
Map<String, Object> output = (Map<String, Object>) reviewEvent.get("Output");
String suggestion = (String) output.get("Suggestion");
if ("block".equals(suggestion)) {
// 审核不通过修改视频状态为2写入reason发送站内消息告知审核结果
// label
//Porn色情
//Terror暴力
//Polity不适宜的信息
//Ad广告
//Illegal违法
//Abuse谩骂
//Moan娇喘。
String label = (String) output.get("Label"); // 违规内容
String subLabel = (String) output.get("SubLabel"); // 违规子标签
log.info("视频文件 {} 审核驳回, 原因: {} - {}", fileId, label, subLabel);
// TODO: 更新数据库,发送站内信
vlogService.updateVlogStatus(fileId,2,label);
} else if ("pass".equals(suggestion)) {
// 审核通过,处理通过逻辑,修改视频状态为1发送站内消息告知审核结果
log.info("视频文件 {} 审核通过", fileId);
// TODO: 更新数据库,发送站内信
vlogService.updateVlogStatus(fileId,1,"通过");
} else if ("review".equals(suggestion)){
// 建议复审修改状态为3发送站内消息告知审核结果
String label = (String) output.get("Label"); // 违规内容
String subLabel = (String) output.get("SubLabel"); // 违规子标签
log.info("视频文件 {} 建议复审, 原因: {} - {}", fileId, label, subLabel);
// TODO: 更新数据库,发送站内信
vlogService.updateVlogStatus(fileId,3,"等待复审");
}
}
}
}
// 处理完成,返回成功,防止腾讯云重复发送回调
return GraceJSONResult.ok();
} catch (Exception e) {
log.error("处理腾讯云 VOD 回调异常: ", e);
return GraceJSONResult.error();
}
}
@PostMapping("publish")
public GraceJSONResult publish(@RequestBody VlogBO vlogBO) throws Exception {
String url = vlogBO.getUrl();
log.info("未审核视频地址:"+url);
String fileName = url.substring(url.lastIndexOf("/") + 1);
log.info("视频文件名称:"+fileName);
String fileId = qcCloud.uploadViaTempFile(fileName);
log.info("视频发布ID:"+fileId);
vlogBO.setFileId(fileId);
// 删除minio文件
// MinIOUtils.removeFile(minIOConfig.getBucketName(),fileName);
// log.info("删除minio文件"+fileName);
// FIXME 校验VlogBO
vlogService.createVlog(vlogBO);
return GraceJSONResult.ok();
}
@GetMapping("indexList")
public GraceJSONResult indexList(@RequestParam(defaultValue = "") String userId,
@RequestParam(defaultValue = "") String search,
@RequestParam(defaultValue = "") String cityCode,
@RequestParam(defaultValue = "") String status,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getIndexVlogList(userId, search, cityCode,status, page, pageSize);
return GraceJSONResult.ok(gridResult);
}
@GetMapping("detail")
public GraceJSONResult detail(@RequestParam(defaultValue = "") String userId,
@RequestParam String vlogId) {
return GraceJSONResult.ok(vlogService.getVlogDetailById(userId, vlogId));
}
@PostMapping("changeToPrivate")
public GraceJSONResult changeToPrivate(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.YES.type);
return GraceJSONResult.ok();
}
@PostMapping("changeToPublic")
public GraceJSONResult changeToPublic(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.NO.type);
return GraceJSONResult.ok();
}
@GetMapping("myPublicList")
public GraceJSONResult myPublicList(@RequestParam String userId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.queryMyVlogList(userId,
page,
pageSize,
YesOrNo.NO.type);
return GraceJSONResult.ok(gridResult);
}
@GetMapping("myPrivateList")
public GraceJSONResult myPrivateList(@RequestParam String userId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.queryMyVlogList(userId,
page,
pageSize,
YesOrNo.YES.type);
return GraceJSONResult.ok(gridResult);
}
@GetMapping("myLikedList")
public GraceJSONResult myLikedList(@RequestParam String userId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getMyLikedVlogList(userId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
}
@Value(("${nacos.counts}"))
private Integer nacosConuts;
@PostMapping("like")
public GraceJSONResult like(@RequestParam String userId,
@RequestParam String vlogerId,
@RequestParam String vlogId) {
// 我点赞的视频,关联关系保存到数据库
vlogService.userLikeVlog(userId, vlogId);
// 点赞后,视频和视频发布者的获赞都会 +1
redis.increment(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + vlogerId, 1);
redis.increment(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId, 1);
// 我点赞的视频需要在redis中保存关联关系
redis.set(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId, "1");
log.info("nacosConuts="+nacosConuts);
String countsStr = redis.get(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId);
Integer counts=0;
if (StringUtils.isNotBlank(countsStr)){
counts=Integer.valueOf(countsStr);
if (counts>=nacosConuts){
vlogService.flushCounts(vlogId, counts);
}
}
return GraceJSONResult.ok();
}
@PostMapping("unlike")
public GraceJSONResult unlike(@RequestParam String userId,
@RequestParam String vlogerId,
@RequestParam String vlogId) {
// 我取消点赞的视频,关联关系删除
vlogService.userUnLikeVlog(userId, vlogId);
redis.decrement(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + vlogerId, 1);
redis.decrement(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId, 1);
redis.del(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId);
return GraceJSONResult.ok();
}
@PostMapping("totalLikedCounts")
public GraceJSONResult totalLikedCounts(@RequestParam String vlogId) {
return GraceJSONResult.ok(vlogService.getVlogBeLikedCounts(vlogId));
}
@GetMapping("followList")
public GraceJSONResult followList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getMyFollowVlogList(myId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
}
@GetMapping("friendList")
public GraceJSONResult friendList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
if (page == null) {
page = COMMON_START_PAGE;
}
if (pageSize == null) {
pageSize = COMMON_PAGE_SIZE;
}
PagedGridResult gridResult = vlogService.getMyFriendVlogList(myId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
}
}