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 0be8958..149237c 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/api/AlbumInfoApiController.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/api/AlbumInfoApiController.class differ diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/api/TrackInfoApiController.class b/service/service-album/target/classes/com/atguigu/tingshu/album/api/TrackInfoApiController.class index e2dae1d..ed07ac5 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/api/TrackInfoApiController.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/api/TrackInfoApiController.class differ diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/config/VodConstantProperties.class b/service/service-album/target/classes/com/atguigu/tingshu/album/config/VodConstantProperties.class index 38fecfa..7035c93 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/config/VodConstantProperties.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/config/VodConstantProperties.class differ 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 27d70d8..48a1130 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/service/AlbumInfoService.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/service/AlbumInfoService.class differ 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 bd861de..21e73d7 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/service/VodService.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/service/VodService.class differ 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 1c782ee..c7b1301 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.class differ diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.class b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.class index fd86e9b..e00f28d 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/TrackInfoServiceImpl.class differ diff --git a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/VodServiceImpl.class b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/VodServiceImpl.class index a6b1ebd..5112c84 100644 Binary files a/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/VodServiceImpl.class and b/service/service-album/target/classes/com/atguigu/tingshu/album/service/impl/VodServiceImpl.class differ