From 6034ffa8c557cfad869f64309fa0719aa47e66c3 Mon Sep 17 00:00:00 2001 From: Y1NanPing <735289578@qq.com> Date: Mon, 21 Jul 2025 20:23:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=AC=A1=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=20=20=E5=A3=B0=E9=9F=B3=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=9A=84=E7=AE=A1=E7=90=86=E5=92=8C=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/SystemConstant.java | 2 + service/service-album/pom.xml | 10 + .../tingshu/ServiceAlbumApplication.java | 2 + .../album/api/AlbumInfoApiController.java | 15 ++ .../album/api/TrackInfoApiController.java | 104 +++++++++- .../album/config/VodConstantProperties.java | 17 ++ .../tingshu/album/mapper/TrackInfoMapper.java | 4 + .../album/service/AlbumInfoService.java | 4 + .../tingshu/album/service/AuditService.java | 38 ++++ .../album/service/TrackInfoService.java | 27 +++ .../tingshu/album/service/VodService.java | 14 ++ .../service/impl/AlbumInfoServiceImpl.java | 21 +- .../album/service/impl/AuditServiceImpl.java | 153 ++++++++++++++ .../service/impl/TrackInfoServiceImpl.java | 191 ++++++++++++++++++ .../album/service/impl/VodServiceImpl.java | 91 +++++++++ .../tingshu/album/task/ReviewTask.java | 63 ++++++ .../main/resources/mapper/TrackInfoMapper.xml | 29 ++- .../album/api/AlbumInfoApiController.class | Bin 3310 -> 5175 bytes .../album/api/TrackInfoApiController.class | Bin 768 -> 2028 bytes .../album/config/VodConstantProperties.class | Bin 4786 -> 5061 bytes .../album/service/AlbumInfoService.class | Bin 1066 -> 1502 bytes .../tingshu/album/service/VodService.class | Bin 135 -> 390 bytes .../service/impl/AlbumInfoServiceImpl.class | Bin 6093 -> 11935 bytes .../service/impl/TrackInfoServiceImpl.class | Bin 1122 -> 1122 bytes .../album/service/impl/VodServiceImpl.class | Bin 642 -> 2778 bytes 25 files changed, 781 insertions(+), 4 deletions(-) create mode 100644 service/service-album/src/main/java/com/atguigu/tingshu/album/service/AuditService.java create mode 100644 service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AuditServiceImpl.java create mode 100644 service/service-album/src/main/java/com/atguigu/tingshu/album/task/ReviewTask.java diff --git a/common/service-util/src/main/java/com/atguigu/tingshu/common/constant/SystemConstant.java b/common/service-util/src/main/java/com/atguigu/tingshu/common/constant/SystemConstant.java index 32f5b29..978430d 100644 --- a/common/service-util/src/main/java/com/atguigu/tingshu/common/constant/SystemConstant.java +++ b/common/service-util/src/main/java/com/atguigu/tingshu/common/constant/SystemConstant.java @@ -24,6 +24,8 @@ public class SystemConstant { //声音状态 0501-审核通过 0502"-审核不通过 public static final String TRACK_STATUS_PASS="0501"; // 审核通过 public static final String TRACK_STATUS_NO_PASS="0502"; // 审核不通过 + public static final String TRACK_STATUS_REVIEWING = "0503";// 审核中 + public static final String TRACK_STATUS_ARTIFICIAL = "0504";// 人工复审 //声音来源 0601-用户原创 0602-上传 public static final String TRACK_SOURCE_USER="0601"; // 用户原创 diff --git a/service/service-album/pom.xml b/service/service-album/pom.xml index 5dff7c5..4ba473d 100644 --- a/service/service-album/pom.xml +++ b/service/service-album/pom.xml @@ -46,6 +46,16 @@ rabbit-util 1.0 + + com.tencentcloudapi + tencentcloud-sdk-java + 3.1.1014 + + + com.tencentcloudapi + tencentcloud-sdk-java-tms + 3.1.1010 + diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java b/service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java index eb01876..56d3f89 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java @@ -4,10 +4,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients +@EnableScheduling //开启定时任务功能 public class ServiceAlbumApplication { public static void main(String[] args) { diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/api/AlbumInfoApiController.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/api/AlbumInfoApiController.java index 6c15ddc..78d873b 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/api/AlbumInfoApiController.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/api/AlbumInfoApiController.java @@ -76,6 +76,21 @@ public class AlbumInfoApiController { albumInfoService.updateAlbumInfo(id, albumInfoVo); return Result.ok(); } + /** + * TODO 改接口登录才能访问 + * 查询当前用户专辑列表 + * @return + */ + @Operation(summary = "查询当前用户专辑列表") + @GetMapping("/albumInfo/findUserAllAlbumList") + public Result> findUserAllAlbumList(){ + //1.获取用户ID + Long userId = AuthContextHolder.getUserId(); + //2.调用service方法查询 + List list = albumInfoService.findUserAllAlbumList(userId); + //3.响应结果 + return Result.ok(list); + } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/api/TrackInfoApiController.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/api/TrackInfoApiController.java index 7b067b6..c9c82b8 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/api/TrackInfoApiController.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/api/TrackInfoApiController.java @@ -1,10 +1,22 @@ package com.atguigu.tingshu.album.api; import com.atguigu.tingshu.album.service.TrackInfoService; +import com.atguigu.tingshu.album.service.VodService; +import com.atguigu.tingshu.common.result.Result; +import com.atguigu.tingshu.common.util.AuthContextHolder; +import com.atguigu.tingshu.model.album.TrackInfo; +import com.atguigu.tingshu.query.album.TrackInfoQuery; +import com.atguigu.tingshu.vo.album.TrackInfoVo; +import com.atguigu.tingshu.vo.album.TrackListVo; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Map; @Tag(name = "声音管理") @RestController @@ -15,5 +27,93 @@ public class TrackInfoApiController { @Autowired private TrackInfoService trackInfoService; + //这个接口是专门为了对上传的音频文件进行增删改查的 + //trackInfoService 这个接口是专门去写项目中关于声音的一些功能 + @Autowired + private VodService vodService; + + //用MultipartFile来接收文件 + @Operation(summary = "将音频文件上传到腾讯云点播平台") + @PostMapping("/trackInfo/uploadTrack") + public Result> uploadTrack(@RequestParam("file") MultipartFile file){ + Map map=vodService.uploadTrack(file); + return Result.ok(map); + + } + /** + * TODO 该接口必须登录才能访问 + * 保存声音 + * + * @param trackInfoVo + * @return + */ + @Operation(summary = "保存声音") + @PostMapping("/trackInfo/saveTrackInfo") + public Result saveTrackInfo(@Validated @RequestBody TrackInfoVo trackInfoVo) { + Long userId = AuthContextHolder.getUserId(); + trackInfoService.saveTrackInfo(trackInfoVo, userId); + return Result.ok(); + } + /** + * TODO 该接口必须登录才能访问 + * 分页条件查询当前用户声音列表 + * + * @param page + * @param limit + * @param trackInfoQuery + * @return + */ + @Operation(summary = "分页条件查询当前用户声音列表") + @PostMapping("/trackInfo/findUserTrackPage/{page}/{limit}") + public Result> findUserTrackPage( + @PathVariable Long page, + @PathVariable Long limit, + @RequestBody TrackInfoQuery trackInfoQuery + ){ + //1.获取用户ID + Long userId = AuthContextHolder.getUserId(); + trackInfoQuery.setUserId(userId); + //2.封装分页对象:页码、页大小 + Page pageInfo = new Page<>(page, limit); + //3.调用业务层分页获取结果 + pageInfo = trackInfoService.findUserTrackPage(pageInfo, trackInfoQuery); + //4.响应结果 + return Result.ok(pageInfo); + } + /** + * 查询声音信息 + * @param id + * @return + */ + @Operation(summary = "查询声音信息") + @GetMapping("/trackInfo/getTrackInfo/{id}") + public Result getTrackInfo(@PathVariable Long id){ + TrackInfo trackInfo = trackInfoService.getById(id); + return Result.ok(trackInfo); + } + /** + * 修改声音 + * @param id + * @param trackInfoVo + * @return + */ + @Operation(summary = "修改声音") + @PutMapping("/trackInfo/updateTrackInfo/{id}") + public Result updateTrackInfo(@PathVariable Long id, @Validated @RequestBody TrackInfoVo trackInfoVo){ + trackInfoService.updateTrackInfo(id, trackInfoVo); + return Result.ok(); + } + /** + * 删除声音 + * @param id + * @return + */ + @Operation(summary = "删除声音") + @DeleteMapping("/trackInfo/removeTrackInfo/{id}") + public Result removeTrackInfo(@PathVariable Long id){ + trackInfoService.removeTrackInfo(id); + return Result.ok(); + } + } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/config/VodConstantProperties.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/config/VodConstantProperties.java index 43ce17a..69be6df 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/config/VodConstantProperties.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/config/VodConstantProperties.java @@ -1,8 +1,11 @@ package com.atguigu.tingshu.album.config; +import com.qcloud.vod.VodUploadClient; +import com.tencentcloudapi.common.Credential; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @@ -18,4 +21,18 @@ public class VodConstantProperties { private String procedure; private String tempPath; private String playKey; + /** + * 注册用于文件上传客户端对象 + * + * @return + */ + @Bean + public VodUploadClient vodUploadClient() { + return new VodUploadClient(secretId, secretKey); + } + @Bean + public Credential credential(){ + return new Credential(secretId, secretKey); + } + } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/mapper/TrackInfoMapper.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/mapper/TrackInfoMapper.java index 4736db6..f9fba84 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/mapper/TrackInfoMapper.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/mapper/TrackInfoMapper.java @@ -1,11 +1,15 @@ package com.atguigu.tingshu.album.mapper; import com.atguigu.tingshu.model.album.TrackInfo; +import com.atguigu.tingshu.query.album.TrackInfoQuery; +import com.atguigu.tingshu.vo.album.TrackListVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Mapper; @Mapper public interface TrackInfoMapper extends BaseMapper { + Page findUserTrackPage(Page pageInfo, TrackInfoQuery trackInfoQuery); } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AlbumInfoService.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AlbumInfoService.java index 6907c48..7453c02 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AlbumInfoService.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AlbumInfoService.java @@ -7,6 +7,8 @@ import com.atguigu.tingshu.vo.album.AlbumListVo; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + public interface AlbumInfoService extends IService { @@ -23,4 +25,6 @@ public interface AlbumInfoService extends IService { AlbumInfo getAlbumInfo(Long id); void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo); + + List findUserAllAlbumList(Long userId); } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AuditService.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AuditService.java new file mode 100644 index 0000000..fb40953 --- /dev/null +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/AuditService.java @@ -0,0 +1,38 @@ +package com.atguigu.tingshu.album.service; + +import org.springframework.web.multipart.MultipartFile; + +public interface AuditService { + +//这个是专门封装出来为音频审核做的接口 + /** + * 对文本进行审核 + * @param content + * @return + */ + String auditText(String content); + + /** + * 对图片进行审核 + * @param file + * @return + */ + String auditImage(MultipartFile file); + + + /** + * 发起审核任务 + * @param mediaFileId + * @return 任务ID + */ + String startReviewTask(String mediaFileId); + + + /** + * 根据任务ID 获取审核结果 + * @param taskId + * @return 建议 + */ + String getReviewResult(String taskId); + +} diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/TrackInfoService.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/TrackInfoService.java index 4bba8f2..ffbbf89 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/TrackInfoService.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/TrackInfoService.java @@ -1,8 +1,35 @@ package com.atguigu.tingshu.album.service; import com.atguigu.tingshu.model.album.TrackInfo; +import com.atguigu.tingshu.query.album.TrackInfoQuery; +import com.atguigu.tingshu.vo.album.TrackInfoVo; +import com.atguigu.tingshu.vo.album.TrackListVo; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.Map; + public interface TrackInfoService extends IService { + + /** + * 保存声音 + * + * @param trackInfoVo + * @param userId + */ + void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId); + /** + * 保存声音统计信息 + * @param trackId 声音ID + * @param statType 统计类型 + * @param statNum 统计数值 + */ + void saveTrackStat(Long trackId, String statType, int statNum); + + Page findUserTrackPage(Page pageInfo, TrackInfoQuery trackInfoQuery); + + void updateTrackInfo(Long id, TrackInfoVo trackInfoVo); + + void removeTrackInfo(Long id); } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/VodService.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/VodService.java index 72fead0..89427f4 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/VodService.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/VodService.java @@ -1,5 +1,19 @@ package com.atguigu.tingshu.album.service; +import com.atguigu.tingshu.vo.album.TrackMediaInfoVo; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Map; + public interface VodService { + Map uploadTrack(MultipartFile file); + + TrackMediaInfoVo getMediaInfo(String mediaFileId); + /** + * 从点播平台删除音频 + * @param mediaFileId + */ + void deleteMedia(String mediaFileId); + } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java index f5f6b97..38d8b12 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java @@ -18,7 +18,7 @@ import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo; import com.atguigu.tingshu.vo.album.AlbumInfoVo; import com.atguigu.tingshu.vo.album.AlbumListVo; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; @@ -173,4 +173,23 @@ public class AlbumInfoServiceImpl extends ServiceImpl findUserAllAlbumList(Long userId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + //1.查询当前用户专辑列表 + queryWrapper.eq(AlbumInfo::getUserId, userId); + //2.专辑状态为审核通过 + queryWrapper.eq(AlbumInfo::getStatus,SystemConstant.ALBUM_STATUS_PASS); + //3.专辑ID,专辑标题 + queryWrapper.select(AlbumInfo::getId, AlbumInfo::getAlbumTitle); + //4.限制返回记录数,造成前端卡顿 TODO 后期前端改为带分页下拉框 + queryWrapper.last("limit 200"); + //5.按照专辑ID降序 + queryWrapper.orderByDesc(AlbumInfo::getId); + return albumInfoMapper.selectList(queryWrapper); + + + + } } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AuditServiceImpl.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AuditServiceImpl.java new file mode 100644 index 0000000..675d74d --- /dev/null +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AuditServiceImpl.java @@ -0,0 +1,153 @@ +package com.atguigu.tingshu.album.service.impl; + +import cn.hutool.core.codec.Base64; +import com.atguigu.tingshu.album.config.VodConstantProperties; +import com.atguigu.tingshu.album.service.AuditService; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.ims.v20201229.ImsClient; +import com.tencentcloudapi.ims.v20201229.models.ImageModerationRequest; +import com.tencentcloudapi.ims.v20201229.models.ImageModerationResponse; +import com.tencentcloudapi.tms.v20201229.TmsClient; +import com.tencentcloudapi.tms.v20201229.models.TextModerationRequest; +import com.tencentcloudapi.tms.v20201229.models.TextModerationResponse; +import com.tencentcloudapi.vod.v20180717.VodClient; +import com.tencentcloudapi.vod.v20180717.models.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +/** + * @author: atguigu + * @create: 2025-07-19 14:24 + */ +@Slf4j +@Service +public class AuditServiceImpl implements AuditService { + + + @Autowired + private Credential credential; + + @Autowired + private VodConstantProperties vodConstantProperties; + + /** + * 审核文本 + * + * @param content + * @return + */ + @Override + public String auditText(String content) { + try { + //1.实例化要请求产品的client对象,clientProfile是可选的 + TmsClient client = new TmsClient(credential, vodConstantProperties.getRegion()); + //2.实例化一个请求对象,每个接口都会对应一个request对象 + TextModerationRequest req = new TextModerationRequest(); + //对文本进行Base64编码 + req.setContent(Base64.encode(content)); + //3.返回的resp是一个TextModerationResponse的实例,与请求对象对应 + TextModerationResponse resp = client.TextModeration(req); + if (resp != null) { + String suggestion = resp.getSuggestion(); + return suggestion.toLowerCase(); + } + } catch (TencentCloudSDKException e) { + log.error("文本审核失败"); + } + return null; + } + + /** + * 对图片进行审核 + * + * @param file + * @return + */ + @Override + public String auditImage(MultipartFile file) { + try { + //1.实例化要请求产品的client对象,clientProfile是可选的 + ImsClient client = new ImsClient(credential, vodConstantProperties.getRegion()); + //2.实例化一个请求对象,每个接口都会对应一个request对象 + ImageModerationRequest req = new ImageModerationRequest(); + req.setFileContent(Base64.encode(file.getInputStream())); + //3.返回的resp是一个ImageModerationResponse的实例,与请求对象对应 + ImageModerationResponse resp = client.ImageModeration(req); + if (resp != null) { + String suggestion = resp.getSuggestion(); + return suggestion.toLowerCase(); + } + } catch (Exception e) { + log.error("图片审核失败"); + } + return null; + } + + /** + * 发起审核任务 + * + * @param mediaFileId + * @return 任务ID + */ + @Override + public String startReviewTask(String mediaFileId) { + try { + //1.实例化要请求产品的client对象,clientProfile是可选的 + VodClient client = new VodClient(credential, vodConstantProperties.getRegion()); + //2.实例化一个请求对象,每个接口都会对应一个request对象 + ReviewAudioVideoRequest req = new ReviewAudioVideoRequest(); + req.setFileId(mediaFileId); + //3.返回的resp是一个ReviewAudioVideoResponse的实例,与请求对象对应 + ReviewAudioVideoResponse resp = client.ReviewAudioVideo(req); + if (resp != null) { + return resp.getTaskId(); + } + } catch (TencentCloudSDKException e) { + log.error("音视频审核任务发起失败"); + } + return null; + } + + /** + * 根据任务ID 获取审核结果 + * + * @param taskId + * @return 建议 + */ + @Override + public String getReviewResult(String taskId) { + try { + //1.实例化要请求产品的client对象,clientProfile是可选的 + VodClient client = new VodClient(credential, vodConstantProperties.getRegion()); + //2.例化一个请求对象,每个接口都会对应一个request对象 + DescribeTaskDetailRequest req = new DescribeTaskDetailRequest(); + req.setTaskId(taskId); + //3.返回的resp是一个DescribeTaskDetailResponse的实例,与请求对象对应 + DescribeTaskDetailResponse resp = client.DescribeTaskDetail(req); + //4.解析任务状态以及审核任务建议结果 + if (resp != null) { + String taskType = resp.getTaskType(); + //4.1 获取任务类型是否为音频审核 + if ("ReviewAudioVideo".equals(taskType)) { + //4.2 获取任务状态是否为已完成 + String status = resp.getStatus(); + if ("FINISH".equals(status)) { + ReviewAudioVideoTask reviewAudioVideoTask = resp.getReviewAudioVideoTask(); + if (reviewAudioVideoTask != null) { + ReviewAudioVideoTaskOutput output = reviewAudioVideoTask.getOutput(); + String suggestion = output.getSuggestion(); + //4.3 获取建议 + return suggestion.toLowerCase(); + } + } + } + } + } catch (TencentCloudSDKException e) { + System.out.println(e.toString()); + } + return null; + } +} diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.java index 57b418b..47e6416 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.java @@ -1,12 +1,32 @@ package com.atguigu.tingshu.album.service.impl; +import cn.hutool.core.bean.BeanUtil; +import com.atguigu.tingshu.album.mapper.AlbumInfoMapper; import com.atguigu.tingshu.album.mapper.TrackInfoMapper; +import com.atguigu.tingshu.album.mapper.TrackStatMapper; +import com.atguigu.tingshu.album.service.AuditService; import com.atguigu.tingshu.album.service.TrackInfoService; +import com.atguigu.tingshu.album.service.VodService; +import com.atguigu.tingshu.common.constant.SystemConstant; +import com.atguigu.tingshu.model.album.AlbumInfo; import com.atguigu.tingshu.model.album.TrackInfo; +import com.atguigu.tingshu.model.album.TrackStat; +import com.atguigu.tingshu.query.album.TrackInfoQuery; +import com.atguigu.tingshu.vo.album.TrackInfoVo; +import com.atguigu.tingshu.vo.album.TrackListVo; +import com.atguigu.tingshu.vo.album.TrackMediaInfoVo; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.Map; @Slf4j @Service @@ -15,5 +35,176 @@ public class TrackInfoServiceImpl extends ServiceImpl findUserTrackPage(Page pageInfo, TrackInfoQuery trackInfoQuery) { + return trackInfoMapper.findUserTrackPage(pageInfo, trackInfoQuery); + } + + @Override + public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) { + //1. 根据id查询声音信息 得到"原有的"音频唯一标识 + TrackInfo trackInfo = trackInfoMapper.selectById(id); + String oldMediaFileId = trackInfo.getMediaFileId(); + + //对文本进行审核 + String text = trackInfoVo.getTrackTitle() + trackInfoVo.getTrackIntro(); + String suggestion = auditService.auditText(text); + if ("pass".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS); + } else if ("block".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_NO_PASS); + } else if ("review".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_ARTIFICIAL); + } + + //2. 判断音频文件是否发生更新,如果更新 + if (!trackInfoVo.getMediaFileId().equals(oldMediaFileId)) { + // 2.1 调用点播平台获取最新音频详情信息 + TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId()); + if (mediaInfo != null) { + trackInfo.setMediaFileId(trackInfoVo.getMediaFileId()); + trackInfo.setMediaUrl(trackInfoVo.getMediaUrl()); + trackInfo.setMediaDuration(BigDecimal.valueOf(mediaInfo.getDuration())); + trackInfo.setMediaType(mediaInfo.getType()); + trackInfo.setMediaSize(mediaInfo.getSize()); + // 2.2 TODO 再次对变更后音频文件进行内容审核 + String reviewTaskId = auditService.startReviewTask(trackInfo.getMediaFileId()); + trackInfo.setStatus(SystemConstant.TRACK_STATUS_REVIEWING); + trackInfo.setReviewTaskId(reviewTaskId); + + // 2.3原有音频从点播平台删除 + vodService.deleteMedia(oldMediaFileId); + } + } + trackInfo.setTrackTitle(trackInfoVo.getTrackTitle()); + trackInfo.setTrackIntro(trackInfoVo.getTrackIntro()); + trackInfo.setCoverUrl(trackInfoVo.getCoverUrl()); + + + //3. 更新声音记录 + trackInfoMapper.updateById(trackInfo); + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeTrackInfo(Long id) { + //1.根据ID查询要被删除声音记录 得到专辑ID跟序号 + TrackInfo trackInfo = trackInfoMapper.selectById(id); + Long albumId = trackInfo.getAlbumId(); + Integer orderNum = trackInfo.getOrderNum(); + + //2.更新序号确保声音表中序号连续 + trackInfoMapper.update( + null, + new LambdaUpdateWrapper() + .eq(TrackInfo::getAlbumId, albumId) + .gt(TrackInfo::getOrderNum, orderNum) + .setSql("order_num = order_num - 1") + ); + + //3.删除声音 + trackInfoMapper.deleteById(id); + + //4.删除统计信息 + trackStatMapper.delete( + new LambdaQueryWrapper() + .eq(TrackStat::getTrackId, id) + ); + + //5.更新专辑包含声音数量 + albumInfoMapper.update(null, + new LambdaUpdateWrapper().eq(AlbumInfo::getId, albumId) + .setSql("include_track_count = include_track_count - 1") + ); + + //6.删除点播平台音频文件 + vodService.deleteMedia(trackInfo.getMediaFileId()); + + } + } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/VodServiceImpl.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/VodServiceImpl.java index b7fbb23..1a631c7 100644 --- a/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/VodServiceImpl.java +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/VodServiceImpl.java @@ -2,14 +2,105 @@ package com.atguigu.tingshu.album.service.impl; import com.atguigu.tingshu.album.config.VodConstantProperties; import com.atguigu.tingshu.album.service.VodService; +import com.atguigu.tingshu.common.util.UploadFileUtil; +import com.atguigu.tingshu.vo.album.TrackMediaInfoVo; +import com.qcloud.vod.VodUploadClient; +import com.qcloud.vod.model.VodUploadRequest; +import com.qcloud.vod.model.VodUploadResponse; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.vod.v20180717.VodClient; +import com.tencentcloudapi.vod.v20180717.models.*; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Map; +@Slf4j @Service public class VodServiceImpl implements VodService { @Autowired private VodConstantProperties vodConstantProperties; + @Autowired + private VodUploadClient vodUploadClient; + @Autowired + private Credential credential; + @Override + public Map uploadTrack(MultipartFile file) { + //1.首先将上传文件保存到本地临时文件夹中 后期采取定时任务去清理临时文件夹 + try { + String tempPath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file); + //2.上传到腾讯云点播平台 + //2.1 构造上传请求对象 + VodUploadRequest request = new VodUploadRequest(); + request.setMediaFilePath(tempPath); + //2.2 调用上传 + VodUploadResponse response = vodUploadClient.upload(vodConstantProperties.getRegion(), request); + //2.3 获取上传结果得到音频媒体唯一标识mediaFileId,以及音频在线地址mediaUrl + if (response != null) { + String fileId = response.getFileId(); + String mediaUrl = response.getMediaUrl(); + return Map.of("mediaFileId", fileId, "mediaUrl", mediaUrl); + } + return null; + } catch (Exception e) { + log.error("上传音频文件失败"); + throw new RuntimeException(e); + } + } + + @Override + public TrackMediaInfoVo getMediaInfo(String mediaFileId) { + try { + //1.实例化要请求产品的client对象, + VodClient client = new VodClient(credential, vodConstantProperties.getRegion()); + //2.实例化一个请求对象,每个接口都会对应一个request对象 + DescribeMediaInfosRequest req = new DescribeMediaInfosRequest(); + String[] fileIds1 = {mediaFileId}; + req.setFileIds(fileIds1); + //3.返回的resp是一个DescribeMediaInfosResponse的实例,与请求对象对应 + DescribeMediaInfosResponse resp = client.DescribeMediaInfos(req); + //4.解析结果,获取基本信息中类型以及元数据时长跟大小 + if (resp != null) { + MediaInfo mediaInfo = resp.getMediaInfoSet()[0]; + if (mediaInfo != null) { + //4.1 获取基本信息 + MediaBasicInfo basicInfo = mediaInfo.getBasicInfo(); + //4.2 获取元数据 + MediaMetaData metaData = mediaInfo.getMetaData(); + //4.3 封装音频文件详情VO + TrackMediaInfoVo trackMediaInfoVo = new TrackMediaInfoVo(); + trackMediaInfoVo.setType(basicInfo.getType()); + trackMediaInfoVo.setSize(metaData.getSize()); + trackMediaInfoVo.setDuration(metaData.getDuration()); + return trackMediaInfoVo; + } + } + } catch (TencentCloudSDKException e) { + log.error("获取音频信息失败"); + throw new RuntimeException(e); + } + return null; + } + + @Override + public void deleteMedia(String mediaFileId) { + try { + //1.实例化要请求产品的client对象,clientProfile是可选的 + VodClient client = new VodClient(credential, vodConstantProperties.getRegion()); + //2.实例化一个请求对象,每个接口都会对应一个request对象 + DeleteMediaRequest req = new DeleteMediaRequest(); + req.setFileId(mediaFileId); + //3.返回的resp是一个DeleteMediaResponse的实例,与请求对象对应 + client.DeleteMedia(req); + } catch (TencentCloudSDKException e) { + log.error("删除失败"); + } + + } } diff --git a/service/service-album/src/main/java/com/atguigu/tingshu/album/task/ReviewTask.java b/service/service-album/src/main/java/com/atguigu/tingshu/album/task/ReviewTask.java new file mode 100644 index 0000000..28d7e6e --- /dev/null +++ b/service/service-album/src/main/java/com/atguigu/tingshu/album/task/ReviewTask.java @@ -0,0 +1,63 @@ +package com.atguigu.tingshu.album.task; + +import cn.hutool.core.collection.CollUtil; +import com.atguigu.tingshu.album.mapper.TrackInfoMapper; +import com.atguigu.tingshu.album.service.AuditService; +import com.atguigu.tingshu.common.constant.SystemConstant; +import com.atguigu.tingshu.model.album.TrackInfo; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author: atguigu + * @create: 2025-07-19 15:38 + */ +@Slf4j +@Component +public class ReviewTask { + + @Autowired + private TrackInfoMapper trackInfoMapper; + + @Autowired + private AuditService auditService; + + /** + * 每5秒检查一次审核结果 + */ + @Scheduled(cron = "0/5 * * * * ?") + public void checkReviewResultTask() { + log.info("开始检查审核任务"); + //1.查询审核状态为"审核中"声音列表 + List trackInfoList = trackInfoMapper.selectList( + new LambdaQueryWrapper() + .eq(TrackInfo::getStatus, SystemConstant.TRACK_STATUS_REVIEWING) + .select(TrackInfo::getId, TrackInfo::getReviewTaskId) + .last("limit 100") + ); + //2.遍历列表,查询审核结果 + if (CollUtil.isNotEmpty(trackInfoList)) { + for (TrackInfo trackInfo : trackInfoList) { + String suggestion = auditService.getReviewResult(trackInfo.getReviewTaskId()); + if (StringUtils.isNotBlank(suggestion)) { + //3.根据审核任务结果更新声音审核状态 + if ("pass".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS); + } else if ("block".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_NO_PASS); + } else if ("review".equals(suggestion)) { + trackInfo.setStatus(SystemConstant.TRACK_STATUS_ARTIFICIAL); + } + trackInfoMapper.updateById(trackInfo); + } + } + } + } + +} diff --git a/service/service-album/src/main/resources/mapper/TrackInfoMapper.xml b/service/service-album/src/main/resources/mapper/TrackInfoMapper.xml index 735afc4..b560231 100644 --- a/service/service-album/src/main/resources/mapper/TrackInfoMapper.xml +++ b/service/service-album/src/main/resources/mapper/TrackInfoMapper.xml @@ -3,7 +3,34 @@ - + diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/api/AlbumInfoApiController.class b/service/service-album/target/classes/com/atguigu/tingshu/album/api/AlbumInfoApiController.class index 0be8958d3df3f10b149d3eca90598f13a471d0df..149237ce8c72b63c93fd85e4f5eeefcd05256c43 100644 GIT binary patch delta 1930 zcmZ{l?Qc_69LK-sw%t?9T3p=#5fLyM8`4D=5%vJn@i6Fk5)cQd#oo=byLPU(^8vA< zATxnPa*f9L!eKNaG4c>dwi%ryzEl4KU(+(*$ZOvizvrC0a#y++z2~0a`JLbSe81;+ z(|?vvHP`+A-%qmux^UrU-M_xwK}7L<2%E7^AUtM{WX8=N>tt@EFFlx%YaJnUqDvq& zWZI<#fv)EGsl<39W+l=?v3Mpu)Un>li$|Xu$s|oHmXH-4;f zTBdFGCq_q8R4MR;Rww<5mH8Drol2e&s8#Z1fw`u(3T7A~GIeD;G57AG&<`*F4~@#Wl=s{-v(%f_9i{Xob{ zj}Y(Wx+(^}x6An4|J;z?9X|sdhIE@X}7T7QdbyRcwsh0b(MuWrFoAp zZo+W0YC7jmO=DPf!`lD8e zLp%5>RY71U$7+rNHQU8mj5EP8&@u&alP?DP_>{@OGVJCvq!X|Qan1yq&<{U$Ije)~ z@-nv`K0cphYz@L#tM;r`u?BY!(15+z$Gv`L?8gC~a*%rhf?+_?H8J!O6Aoo@7)SW> z@-c`kj^Y(A1_f6K_;QRtfoE`>3M9SrTd-R(G%^5eXhFMT>82VmuKDHL z2@*(sZFp6&$hX(4A(uHNjvZ289*sJ^ zB(NUCN}y};u&TMhVhbZYUR#`2RMoN#G*u@_w7myeSl(^KCD~%2f5SA|7qC!2k%R0l z*)00vBPEuI%MxVC3`SYdL!~`?tK73OWJ`2*Io&qoT%Qh*jdXd072bv!bo(kf6(?N3 z2QFNK3%hV&SIYj>aJ2@*sMML`c)JAljsjb1Ag_J%HfS$akxbsD!0z(338TNh0W;HuGi4VXbdf%bXfMjMLd^|hyT4Z0((x2&GtEv=8z$$FVKb#4k-yKi)r5=MvjD7 z?QOo+palV&WK@7MfDZrIZ3rnr2#>gn~n)P^l7)jsc%btX@|})(AFxLDwkD2g)jx?6Qh zX6>pXf76dR!rp~N-ah;<8GQ`8vnx~t3}<`t@u<3?_6bDfc<8PlhLLU_Hlj8cQ{AdF zyDDYTx{575ESYsBF)!_^u3Z+cpsh5-=is99LSYj_v48!4QnV9fyFK<9vx|DPtTd0; zh384b>*u%@@vf4J`K3sjv>Zt{7big=%m%~hX5;GpZ*ScH;o9AAKHd7`x2>C>Z~ggQ z^RvdiPj274{`1zYYug`h-u>#Q=H`v&7Y&A~Jrh?^VQrT~ep$zs8a#45GxXPmpAdN? zywh*IYm}Vm?w$_$U2QbIZ|@88qeR9wg(3I(MV*+cbQ6f-Sf_cr#_EJCESf<7!lM;l z%$I~aR5qjnVJI|zY!HXr*T3KX^6Fl_?rQs=6wxHJ55_tH_8t?xP1Ex|Ab8NVbvmQ) zGTkv5x}7rgJBsH(C#J6fTAxp)bn`qUqYR}QFOUYOT}EsF*zaJ!q$V%YzXJdc<0blc z0HlE9NbB&}ugIO+#FH7!kKe@84U+Z2;kX+Uc!e&&lPT8mmi`VF zS<>D~!W<&RSMeHYzfStjV@pyb$tX$s87Tr|^ki@wC28z;rnF(%SuocRDO##y}K m5ZtNG(Q_sy!we=QEp7{xG6TW`iVkGE*!ZKszSm;MHVk#BSW delta 201 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 diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/service/AlbumInfoService.class b/service/service-album/target/classes/com/atguigu/tingshu/album/service/AlbumInfoService.class index 27d70d8ca8b22b85b82b096fd9c160ba8a9f7324..48a1130827133063ce6738b133db13054a60c8e7 100644 GIT binary patch delta 384 zcmZ3*agUqp)W2Q(7#J9A8B{iMi8A~17p3Orm!&%9B$eiR=B4E`G6-wgOcp zrR)3T=cQX~hA}cQWu`DP@T8}fAgQ#)R5|%0lj!6cW-(Pp2L955l*AHblQGm!p2#FN zxtfVD6J&E(KG-6Ww9LGe(Bjl0$DACnT|Sw`C5#M8n07&&Sz3~rqYqMJ&B)+SP|@TM zKpShAr6$WWFK1+*e4IHji-nOvoI!$tk%1E!EUb(Sk_-$$At?rFbRiiAS*Q>v6G#;U g7g(hngFFKhOfxr7SQLnv7!-gQ!ct^V0*fdE0MfQx8vpFW?9b2JXx7FP>6wvK@=###30Tf0j4DZM$-vS diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/service/VodService.class b/service/service-album/target/classes/com/atguigu/tingshu/album/service/VodService.class index bd861de8d2dfe06980966c0a604dfafdca8bc5a7..21e73d70499ac8dbd6ef023ca3b52cb5793bff15 100644 GIT binary patch literal 390 zcmbtQOHRW;47Ec)v<1O2KtlKc0TwJ+H3BJ!y^~BQ(@rwcWTw3v3l6}c5Kbz@f+Y*f z&z9}?{64?lKLFq!&gYOI+?1{%4muhgDVSFGbtJY$Y^Ya$Z%RdPuF8*a4ikjSE$^8u zx0;@dtttb;Dt6X!_3F9YAv|8Ko!8WNUe0YiH|pU0jt;7zCfZ;+_JOh=^kl3`uh-+z z7>uQiyHr>*6>3+#@US10?-3>&8AVv+Mzh8!qzLSSRar(FOAcB^;i@sEY oT!f2XPi_b0GX#Vau@wNtqAAQEfw@#ugi}cii3FB1v>MUbH#*mL0{{R3 delta 34 ocmZo;ZfE2=^>5cc1_lOO2KI?uUXv{tHMkiV7#UcBLQD*70HcKlk^lez diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.class b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.class index 1c782ee616e6cabfb671995227b81fe7831b6529..c7b1301e51ca5883fade69b35bc37bf77c497f2d 100644 GIT binary patch literal 11935 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 delta 1109 zcmZXT+iz4=6vlsh+Ue;W4g-u+&=zV74XJIDVl9XUjR?vmARz=0QDA^d0>fZz=$jV8 z0~SRnTTrXqyekTY0a~fW3Mf$SC@2Wt{sF?fA%6P|7@{-Td#}B2-&)_=XZs6hYW?0@ zhYkae@z-9zwXncro#7$7%1dtY2H4(YJmJ$qlh1nI^w4RKgHU%48Z|9+yrvHa0YR{AO>IJrLy&L#b^a zGRW4K-`mU<@+o$0h=B;z)L?i=a)HiwL*0B9{7<)v)&J2s|7aN1rl?xojLv9P2WD@W z<~{As2}*fid*I}RVz#nPSHpI8kVl)nS-!Iw=RH|ws3Xou?qL)qJWM%{sKiI59m8lI z=LyF0r2fw^ju}i;sgp@Fg_TU@RcY5UP4k)_B2L7UJzysvs1j(s4eg{4`6#Tdm5=#^ z=7>Po@F}0EqB`dDxs>?=oWmCijt1OqkgRt5vE`9UC-+?aq6X-rOA&qGS!H1bMv*+x+zy0mYncp7&_%ndhxRpi% z9U784I?=_jbez-}hS3)@!_Z?1IVY;MX+u^RcJvSA)(M%FK1E2bcA!tg zOFDL97sE(9S0t-?E)S*c@cEkK8Kn!hBj)LqVRIM>*1cTq-{>Ug`4$gq%3;|zs$$vm zuk&S5WYD2* zdvxr@t5gSpkaNu{{Rl!9>&-+daqa>(4p?#{9!YPJSB%sed7(-UW zxK4db?YJqb%&5fjMvWoil^GVA35Yv5+f-f8A*mPC6Z_=&ZHDdZ-EjV1?{#5PR&4TjGU|b+V{bFh$z4y}fpflLUS~Mh|DyA&QEt@K z<)~Q{;`NNzXE1ezY)om*kB1n;;b-=6H0=m)$`^4vGxR@GsowYujQHzoLenTbMYw{? zaP+w&r%s-gL>o16lno8uKhEJeWDPeMc)N0V%Beth@jHq0zq_hh)pa_H~Z`A~^ z_fHo4Y5XL>a1|Zct)>wD*Cf>63CR}dxr^2hBN?4hEwT=Jr{5mBe?&Vtt&G;r!Bw!k zk;=z(SD%6H_=N7tC~d%}xJE0(XE4YuDKm~FG?HB#ybo;!n~tnud;S433#)kf^6=0K zUZD^B;*ST0S8#YNnMwYNJ(=VRhQ~V9a%`-t_e7?%_hhDP4R76Hck+ZjO?KEID-Qiq=S{?Fh=P-J&ggff$?3=9mm4B`{H^x4=MI2ajBCq9&#m@EzCa4|CI06CM(Sw$u`1WxW` zJu$hC!@r1~fr){UffISg&QiyzyJUMwG-6<