Showing
6 changed files
with
163 additions
and
20 deletions
| @@ -51,6 +51,13 @@ public class BackupMaterialController { | @@ -51,6 +51,13 @@ public class BackupMaterialController { | ||
| 51 | return backupMaterialService.getByRoom(roomId); | 51 | return backupMaterialService.getByRoom(roomId); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | + /** | ||
| 55 | + * @description 修改审片间垫片配置 | ||
| 56 | + * @author W5669 | ||
| 57 | + * @date 2025/7/24 | ||
| 58 | + * @param backupChangeDto | ||
| 59 | + * @return ResultBean | ||
| 60 | + */ | ||
| 54 | @PostMapping("change") | 61 | @PostMapping("change") |
| 55 | ResultBean change(@RequestBody BackupChangeDto backupChangeDto){ | 62 | ResultBean change(@RequestBody BackupChangeDto backupChangeDto){ |
| 56 | return backupMaterialService.change(backupChangeDto); | 63 | return backupMaterialService.change(backupChangeDto); |
| @@ -18,5 +18,7 @@ public class BackupUploadVo { | @@ -18,5 +18,7 @@ public class BackupUploadVo { | ||
| 18 | private Long roomId; | 18 | private Long roomId; |
| 19 | //1:垫片1,2:垫片2 | 19 | //1:垫片1,2:垫片2 |
| 20 | private Integer backupOrder; | 20 | private Integer backupOrder; |
| 21 | + //垫片状态 0-默认 1-当前选中 | ||
| 22 | + private String backupStatus; | ||
| 21 | 23 | ||
| 22 | } | 24 | } |
| 1 | +package com.wondertek.dto; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +import java.util.List; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * @Description: 切换频道源请求参数 | ||
| 9 | + * @DateTime: 2020/7/25 10:05 | ||
| 10 | + */ | ||
| 11 | +@Data | ||
| 12 | +public class ChangeSourceParam { | ||
| 13 | + private String taskId; | ||
| 14 | + private List<SourceUrl> sourceUrls; | ||
| 15 | + private String backupUrl; | ||
| 16 | + /** | ||
| 17 | + * 是否切当前任务使用的源至pri=0的源; | ||
| 18 | + * true,如果当前任务使用非pri=0的源则切至pri=0的源【即:如果当前任务在垫片上则切至主源上】; | ||
| 19 | + * false,不执行切换源操作; | ||
| 20 | + * 默认false | ||
| 21 | + */ | ||
| 22 | + private boolean switchMaster; | ||
| 23 | +} |
| @@ -2,35 +2,40 @@ package com.wondertek.service.impl; | @@ -2,35 +2,40 @@ package com.wondertek.service.impl; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollectionUtil; | 3 | import cn.hutool.core.collection.CollectionUtil; |
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | +import cn.hutool.http.HttpRequest; | ||
| 6 | +import cn.hutool.http.HttpResponse; | ||
| 5 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 7 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 6 | import com.baomidou.mybatisplus.core.metadata.IPage; | 8 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 9 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | 10 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| 9 | -import com.wondertek.dto.BackupChangeDto; | ||
| 10 | -import com.wondertek.dto.BackupMaterialDto; | ||
| 11 | -import com.wondertek.dto.BackupUploadVo; | 11 | +import com.fasterxml.jackson.core.type.TypeReference; |
| 12 | +import com.wondertek.dto.*; | ||
| 12 | import com.wondertek.entity.BackupConfig; | 13 | import com.wondertek.entity.BackupConfig; |
| 13 | import com.wondertek.entity.BackupMaterial; | 14 | import com.wondertek.entity.BackupMaterial; |
| 14 | import com.wondertek.entity.StreamTask; | 15 | import com.wondertek.entity.StreamTask; |
| 16 | +import com.wondertek.enums.PlayTypeEnum; | ||
| 15 | import com.wondertek.exception.BusinessException; | 17 | import com.wondertek.exception.BusinessException; |
| 16 | import com.wondertek.mapper.BackupConfigMapper; | 18 | import com.wondertek.mapper.BackupConfigMapper; |
| 17 | import com.wondertek.mapper.BackupMaterialMapper; | 19 | import com.wondertek.mapper.BackupMaterialMapper; |
| 20 | +import com.wondertek.mapper.StreamTaskMapper; | ||
| 18 | import com.wondertek.service.BackupMaterialService; | 21 | import com.wondertek.service.BackupMaterialService; |
| 19 | import com.wondertek.service.FileService; | 22 | import com.wondertek.service.FileService; |
| 20 | -import com.wondertek.util.FileUtils; | ||
| 21 | -import com.wondertek.util.PageBean; | ||
| 22 | -import com.wondertek.util.ResultBean; | ||
| 23 | -import com.wondertek.util.UUIDUtil; | 23 | +import com.wondertek.util.*; |
| 24 | import jakarta.annotation.Resource; | 24 | import jakarta.annotation.Resource; |
| 25 | +import lombok.extern.slf4j.Slf4j; | ||
| 25 | import org.apache.commons.lang3.StringUtils; | 26 | import org.apache.commons.lang3.StringUtils; |
| 26 | import org.springframework.beans.factory.annotation.Value; | 27 | import org.springframework.beans.factory.annotation.Value; |
| 27 | import org.springframework.stereotype.Service; | 28 | import org.springframework.stereotype.Service; |
| 28 | import org.springframework.web.multipart.MultipartFile; | 29 | import org.springframework.web.multipart.MultipartFile; |
| 29 | 30 | ||
| 30 | import java.time.LocalDateTime; | 31 | import java.time.LocalDateTime; |
| 32 | +import java.util.Arrays; | ||
| 33 | +import java.util.HashMap; | ||
| 31 | import java.util.List; | 34 | import java.util.List; |
| 35 | +import java.util.Map; | ||
| 32 | 36 | ||
| 33 | @Service | 37 | @Service |
| 38 | +@Slf4j | ||
| 34 | public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, BackupMaterial> implements BackupMaterialService { | 39 | public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, BackupMaterial> implements BackupMaterialService { |
| 35 | 40 | ||
| 36 | @Resource | 41 | @Resource |
| @@ -41,6 +46,12 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | @@ -41,6 +46,12 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | ||
| 41 | private String realPath; | 46 | private String realPath; |
| 42 | @Resource | 47 | @Resource |
| 43 | private BackupConfigMapper backupConfigMapper; | 48 | private BackupConfigMapper backupConfigMapper; |
| 49 | + @Resource | ||
| 50 | + private StreamTaskMapper streamTaskMapper; | ||
| 51 | + @Value("${transcode.switchStreamUrl}") | ||
| 52 | + private String switchStreamUrl; | ||
| 53 | + @Value("${transcode.swapBackupUrl}") | ||
| 54 | + private String swapBackupUrl; | ||
| 44 | 55 | ||
| 45 | 56 | ||
| 46 | @Override | 57 | @Override |
| @@ -66,22 +77,30 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | @@ -66,22 +77,30 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | ||
| 66 | 77 | ||
| 67 | @Override | 78 | @Override |
| 68 | public ResultBean upload(MultipartFile backupFile, BackupUploadVo backupUploadVo) { | 79 | public ResultBean upload(MultipartFile backupFile, BackupUploadVo backupUploadVo) { |
| 69 | - //上传文件 | 80 | + //校验 |
| 70 | if(!"mp4".equalsIgnoreCase(backupUploadVo.getFileType())){ | 81 | if(!"mp4".equalsIgnoreCase(backupUploadVo.getFileType())){ |
| 71 | throw new BusinessException("仅支持上传mp4格式的垫片文件!"); | 82 | throw new BusinessException("仅支持上传mp4格式的垫片文件!"); |
| 72 | } | 83 | } |
| 73 | - | 84 | + //对应垫片任务 |
| 85 | + LambdaQueryWrapper<StreamTask> backupWrapper = new LambdaQueryWrapper<>(); | ||
| 86 | + backupWrapper.eq(StreamTask::getRoomId,backupUploadVo.getRoomId()); | ||
| 87 | + String palyType = backupUploadVo.getBackupOrder() == 1? PlayTypeEnum.BACKUP1.getCode() : PlayTypeEnum.BACKUP2.getCode(); | ||
| 88 | + backupWrapper.eq(StreamTask::getPlayType,palyType); | ||
| 89 | + StreamTask streamTask = streamTaskMapper.selectOne(backupWrapper); | ||
| 90 | + if (streamTask == null){ | ||
| 91 | + return ResultBean.error("未找到该直播间对应的垫片任务"); | ||
| 92 | + } | ||
| 93 | + //文件上传 | ||
| 74 | String fileId = UUIDUtil.randomUUID(); | 94 | String fileId = UUIDUtil.randomUUID(); |
| 75 | String fileName = backupUploadVo.getBackupName() + "." + backupUploadVo.getFileType(); | 95 | String fileName = backupUploadVo.getBackupName() + "." + backupUploadVo.getFileType(); |
| 76 | ///home/wondertek/material_file_assets/dianpian/2025/07/24/roomid/ | 96 | ///home/wondertek/material_file_assets/dianpian/2025/07/24/roomid/ |
| 77 | String filedir = FileUtils.generateDianPianDir(backupUploadVo.getRoomId().toString(), realPath); | 97 | String filedir = FileUtils.generateDianPianDir(backupUploadVo.getRoomId().toString(), realPath); |
| 78 | - String destFilePath = filedir + fileName;//文件上传目录 | 98 | + String destFilePath = filedir + fileName;//文件上传目录,绝对路径 |
| 79 | try { | 99 | try { |
| 80 | fileService.upload(backupFile, destFilePath); | 100 | fileService.upload(backupFile, destFilePath); |
| 81 | } catch (Exception e) { | 101 | } catch (Exception e) { |
| 82 | return ResultBean.error("上传文件异常"); | 102 | return ResultBean.error("上传文件异常"); |
| 83 | } | 103 | } |
| 84 | - | ||
| 85 | //保存垫片素材表 | 104 | //保存垫片素材表 |
| 86 | BackupMaterial backupMaterial = new BackupMaterial(); | 105 | BackupMaterial backupMaterial = new BackupMaterial(); |
| 87 | backupMaterial.setFileId(fileId); | 106 | backupMaterial.setFileId(fileId); |
| @@ -103,21 +122,85 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | @@ -103,21 +122,85 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | ||
| 103 | backupConfig.setRoomId(backupUploadVo.getRoomId()); | 122 | backupConfig.setRoomId(backupUploadVo.getRoomId()); |
| 104 | backupConfig.setBackupId(backupMaterial.getId()); | 123 | backupConfig.setBackupId(backupMaterial.getId()); |
| 105 | backupConfig.setBackupOrder(backupUploadVo.getBackupOrder()); | 124 | backupConfig.setBackupOrder(backupUploadVo.getBackupOrder()); |
| 125 | + backupConfig.setBackupStatus(backupUploadVo.getBackupStatus()); | ||
| 106 | backupConfigMapper.insertOrUpdate(backupConfig); | 126 | backupConfigMapper.insertOrUpdate(backupConfig); |
| 107 | 127 | ||
| 108 | - //对应垫片任务切源(转码平台演示环境已挂载统一存储) | ||
| 109 | - LambdaQueryWrapper<StreamTask> wrapper1 = new LambdaQueryWrapper<>(); | ||
| 110 | - wrapper1.eq(StreamTask::getRoomId,backupUploadVo.getRoomId()); | ||
| 111 | - wrapper1.eq(StreamTask::getPlayType,"play"); | ||
| 112 | - | ||
| 113 | - | ||
| 114 | - | ||
| 115 | - | 128 | + //对应垫片任务切源(转码平台演示环境已挂载统一存储),请求转码平台修改垫片任务直播源 |
| 129 | + changeChannelSource(streamTask.getTaskId(), destFilePath); | ||
| 116 | //判断是否需要修改当前播出流的垫片 | 130 | //判断是否需要修改当前播出流的垫片 |
| 131 | + if("1".equals(backupConfig.getBackupOrder())){ | ||
| 132 | + //切换播出流垫片(主、备) | ||
| 133 | + LambdaQueryWrapper<StreamTask> playWrapper = new LambdaQueryWrapper<>(); | ||
| 134 | + playWrapper.eq(StreamTask::getRoomId,backupUploadVo.getRoomId()); | ||
| 135 | + playWrapper.eq(StreamTask::getPlayType,"play"); | ||
| 136 | + List<StreamTask> playTasks = streamTaskMapper.selectList(playWrapper); | ||
| 137 | + if(CollectionUtil.isNotEmpty(playTasks)){ | ||
| 138 | + playTasks.forEach(playTask -> { | ||
| 139 | + changeChannelSource(playTask.getTaskId(), destFilePath); | ||
| 140 | + }); | ||
| 141 | + } | ||
| 142 | + } | ||
| 117 | 143 | ||
| 118 | return ResultBean.ok("上传成功"); | 144 | return ResultBean.ok("上传成功"); |
| 119 | } | 145 | } |
| 120 | 146 | ||
| 147 | + private void changeBackup(String taskId, String destFilePath) { | ||
| 148 | + Map<String, Object> paramsMap = new HashMap<>(); | ||
| 149 | + paramsMap.put("taskId", taskId); | ||
| 150 | + paramsMap.put("backupUrl", destFilePath); | ||
| 151 | + HttpResponse execute = null; | ||
| 152 | + try { | ||
| 153 | + execute = HttpRequest.post(swapBackupUrl) | ||
| 154 | + .header("Content-Type", "application/json") | ||
| 155 | + .body(JSONUtils.obj2json(paramsMap)).timeout(30000).execute(); | ||
| 156 | + if (execute.isOk()) { | ||
| 157 | + log.info("-->请求转码系统换垫片接口,url:{},paramsMap:{}",swapBackupUrl,paramsMap); | ||
| 158 | + String body = execute.body(); | ||
| 159 | + ResponseData response = JSONUtils.jsonToObject(body, new TypeReference<ResponseData>() { | ||
| 160 | + }); | ||
| 161 | + if (response.getResultCode().equals("0")) { | ||
| 162 | + log.info("请求转码系统换垫片接口成功"); | ||
| 163 | + }else { | ||
| 164 | + log.info("请求转码系统换垫片接口响应失败,response:{}",response); | ||
| 165 | + } | ||
| 166 | + } else { | ||
| 167 | + log.error("请求转码系统换垫片接口失败,url:{},body:{}", swapBackupUrl, execute.body()); | ||
| 168 | + } | ||
| 169 | + } catch (Exception e) { | ||
| 170 | + log.error("请求转码系统换垫片接口失败,url:{}", swapBackupUrl, e); | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + private void changeChannelSource(String taskId, String destFilePath) { | ||
| 175 | + ChangeSourceParam param = new ChangeSourceParam(); | ||
| 176 | + param.setTaskId(taskId); | ||
| 177 | + SourceUrl sourceUrl = new SourceUrl(); | ||
| 178 | + sourceUrl.setSourceUrl(destFilePath); | ||
| 179 | + sourceUrl.setPri(0); | ||
| 180 | + param.setSourceUrls(Arrays.asList(sourceUrl)); | ||
| 181 | + HttpResponse execute = null; | ||
| 182 | + try { | ||
| 183 | + execute = HttpRequest.post(switchStreamUrl) | ||
| 184 | + .header("Content-Type", "application/json") | ||
| 185 | + .body(JSONUtils.obj2json(param)).timeout(30000).execute(); | ||
| 186 | + if (execute.isOk()) { | ||
| 187 | + log.info("-->请求转码系统切换直播源接口,url:{},paramsMap:{}",switchStreamUrl,param); | ||
| 188 | + String body = execute.body(); | ||
| 189 | + ResponseData response = JSONUtils.jsonToObject(body, new TypeReference<ResponseData>() { | ||
| 190 | + }); | ||
| 191 | + if (response.getResultCode().equals("0")) { | ||
| 192 | + log.info("请求转码系统切换直播源接口成功"); | ||
| 193 | + }else { | ||
| 194 | + log.info("请求转码系统切换直播源接口响应失败,response:{}",response); | ||
| 195 | + } | ||
| 196 | + } else { | ||
| 197 | + log.error("请求转码系统切换直播源接口失败,url:{},body:{}", switchStreamUrl, execute.body()); | ||
| 198 | + } | ||
| 199 | + } catch (Exception e) { | ||
| 200 | + log.error("请求转码系统切换直播源接口失败,url:{}", switchStreamUrl, e); | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 121 | @Override | 204 | @Override |
| 122 | public ResultBean getByRoom(Long roomId) { | 205 | public ResultBean getByRoom(Long roomId) { |
| 123 | LambdaQueryWrapper<BackupConfig> wrapper = new LambdaQueryWrapper<>(); | 206 | LambdaQueryWrapper<BackupConfig> wrapper = new LambdaQueryWrapper<>(); |
| @@ -135,8 +218,19 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | @@ -135,8 +218,19 @@ public class BackupMaterialServiceImpl extends ServiceImpl<BackupMaterialMapper, | ||
| 135 | backupConfigs.forEach(backupConfig -> { | 218 | backupConfigs.forEach(backupConfig -> { |
| 136 | if(backupConfig.getBackupId().equals(backupChangeDto.getBackupId())){ | 219 | if(backupConfig.getBackupId().equals(backupChangeDto.getBackupId())){ |
| 137 | backupConfig.setBackupStatus("1"); | 220 | backupConfig.setBackupStatus("1"); |
| 138 | - //将播放流的垫片配置切到此垫片上 | 221 | + //将播放流的垫片配置切到此垫片上,播放流主、备都切换 |
| 222 | + LambdaQueryWrapper<StreamTask> playWrapper = new LambdaQueryWrapper<>(); | ||
| 223 | + playWrapper.eq(StreamTask::getRoomId,backupChangeDto.getRoomId()); | ||
| 224 | + playWrapper.eq(StreamTask::getPlayType,"play"); | ||
| 225 | + List<StreamTask> playTasks = streamTaskMapper.selectList(playWrapper); | ||
| 226 | + if(CollectionUtil.isNotEmpty(playTasks)){ | ||
| 227 | + String backupPath = realPath + backupConfig.getBackupPath(); | ||
| 228 | + playTasks.forEach(playTask -> { | ||
| 229 | + changeChannelSource(playTask.getTaskId(), backupPath); | ||
| 230 | + }); | ||
| 231 | + } | ||
| 139 | }else { | 232 | }else { |
| 233 | + //将其他垫片配置切到默认状态 | ||
| 140 | backupConfig.setBackupStatus("0"); | 234 | backupConfig.setBackupStatus("0"); |
| 141 | } | 235 | } |
| 142 | backupConfigMapper.updateById(backupConfig); | 236 | backupConfigMapper.updateById(backupConfig); |
| @@ -62,8 +62,13 @@ mybatis-plus: | @@ -62,8 +62,13 @@ mybatis-plus: | ||
| 62 | transcode: | 62 | transcode: |
| 63 | delayTimeUrl: http://192.168.1.237:9002/api/v1/delayTime # 延迟接口 | 63 | delayTimeUrl: http://192.168.1.237:9002/api/v1/delayTime # 延迟接口 |
| 64 | blockStatusUrl: http://192.168.1.237:9002/api/v1/blockStatus # 屏蔽/恢复 | 64 | blockStatusUrl: http://192.168.1.237:9002/api/v1/blockStatus # 屏蔽/恢复 |
| 65 | + switchStreamUrl: http://192.168.1.237:9002/api/v1/switchStream # 切换频道源 | ||
| 66 | + swapBackupUrl: http://192.168.1.237:9002/api/v1/swapBackup # 切垫片 | ||
| 65 | getTaskDetail: http://192.168.1.237:9002/api/v1/getTaskDetail | 67 | getTaskDetail: http://192.168.1.237:9002/api/v1/getTaskDetail |
| 66 | 68 | ||
| 69 | +file: | ||
| 70 | + realPath: /home/wondertek/material_file_assets/ | ||
| 71 | + | ||
| 67 | crp: | 72 | crp: |
| 68 | user: | 73 | user: |
| 69 | username: admin | 74 | username: admin |
-
Please register or login to post a comment