package com.ruoyi.media.service.impl; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.device.camera.domain.ArdCameras; import com.ruoyi.device.camera.domain.CameraCmd; import com.ruoyi.device.camera.factory.CameraSDK; import com.ruoyi.device.camera.factory.CameraSDKFactory; import com.ruoyi.device.channel.domain.ArdChannel; import com.ruoyi.media.domain.StreamInfo; import com.ruoyi.media.service.IMediaService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.ruoyi.media.mapper.VtduMapper; import com.ruoyi.media.domain.Vtdu; import com.ruoyi.media.service.IVtduService; import javax.annotation.PostConstruct; import javax.annotation.Resource; /** * 流媒体管理Service业务层处理 * * @author ard * @date 2023-08-29 */ @Service @Slf4j(topic = "vtdu") public class VtduServiceImpl implements IVtduService { @Resource private VtduMapper vtduMapper; @Resource private IMediaService mediaService; @Resource private CameraSDKFactory cameraSDKFactory; @Value("${mediamtx.host}") String mediamtxHost; /** * 查询流媒体管理 * * @param name 流媒体管理主键 * @return 流媒体管理 */ @Override public Vtdu selectVtduByName(String name) { return vtduMapper.selectVtduByName(name); } /** * 查询流媒体管理列表 * * @param vtdu 流媒体管理 * @return 流媒体管理 */ @Override public List selectVtduList(Vtdu vtdu) { return vtduMapper.selectVtduList(vtdu); } /** * 新增流媒体管理 * * @param vtdu 流媒体管理 * @return 结果 */ @Override public int insertVtdu(Vtdu vtdu) { return vtduMapper.insertVtdu(vtdu); } /** * 修改流媒体管理 * * @param vtdu 流媒体管理 * @return 结果 */ @Override public int updateVtdu(Vtdu vtdu) { Map map = mediaService.editPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode()); vtdu.setName(vtdu.getName()); vtdu.setRtspSource(vtdu.getRtspSource()); vtdu.setIsCode(vtdu.getIsCode()); vtdu.setMode(vtdu.getMode()); vtdu.setRtspUrl(map.get("rtspUrl")); vtdu.setRtmpUrl(map.get("rtmpUrl")); vtdu.setWebrtcUrl(map.get("webrtcUrl")); vtdu.setUpdateTime(DateUtils.getNowDate()); return vtduMapper.updateVtdu(vtdu); } /** * 批量删除流媒体管理 * * @param names 需要删除的数据主键集合 * @return 结果 */ @Override public int deleteVtduByNames(String[] names) { for (String name : names) { log.debug("流媒体【" + name + "】通道删除"); } mediaService.removePath(names); return vtduMapper.deleteVtduByNames(names); } /** * 删除流媒体管理 * * @param name 流媒体通道名称 * @return 结果 */ @Override public int deleteVtduByName(String name) { mediaService.removePath(name); log.debug("流媒体【" + name + "】通道删除"); return vtduMapper.deleteVtduByName(name); } /** * 删除流媒体管理信息 * * @param cameraId 相机ID * @return 结果 */ @Override public int deleteVtduByCameraId(String cameraId) { Vtdu vtdu = new Vtdu(); vtdu.setCameraId(cameraId); List vtdus = vtduMapper.selectVtduList(vtdu); if (vtdus.size() > 0) { for (Vtdu v : vtdus) { mediaService.removePath(v.getName()); } } return vtduMapper.deleteVtduByCameraId(cameraId); } /** * @return * @Author 刘苏义 * @Description 清除所有流媒体数据 * @Date 2024/7/10 13:31 * @Param */ public void clearVtdu() { vtduMapper.clearVtdu(); } //需要更新的(流媒体和vtdu相同) @Override public List sameList(List vtdus, List names) { return vtdus.stream().filter(vtdu -> names.contains(vtdu.getName())).collect(Collectors.toList()); } //需要删除的(流媒体中多的) @Override public List diffListToDel(List vtdus, List names) { if (vtdus.size() >= names.size()) { List nameList = vtdus.stream().map(Vtdu::getName) .filter(item -> !names.contains(item)) .collect(Collectors.toList()); return nameList; } else { List nameList = names.stream().filter(item -> !vtdus.stream().map(Vtdu::getName).collect(Collectors.toList()).contains(item)) .collect(Collectors.toList()); return nameList; } } //需要新增的(流媒体中少的) @Override public List diffListToAdd(List vtdus, List names) { return vtdus.stream().filter(vtdu -> !names.contains(vtdu.getName())).collect(Collectors.toList()); } /** * @return * @Author 刘苏义 * @Description 同步本地vtdu库和流媒体中的数据 * @Date 2024/7/10 15:26 * @Param vtdus vtdu库的集合 * @Param names 流媒体的name集合 */ @Override public void asyncVtdu(List vtdus, List names) { //需要更新的数据,参数顺序注意 sameList(vtdus, names).stream().forEach(vtdu -> { StreamInfo streamInfo = mediaService.getPathInfo(vtdu.getName()); if (!streamInfo.getRtspSource().equals(vtdu.getRtspSource())) { mediaService.editPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode()); } }); //需要删除的数据 diffListToDel(vtdus, names).stream().forEach(name -> { mediaService.removePath(name); }); //需要新增的数据 diffListToAdd(vtdus, names).stream().forEach(vtdu -> { mediaService.addPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode()); }); } @Override public void addChanToVtdu(ArdCameras camera, ArdChannel channel) { String name = camera.getId() + "_" + channel.getChanNo(); String rtspSource=""; switch (camera.getFactory()) { case "1": rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream";break; case "2": rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/cam/realmonitor?channel=" + channel.getChanNo() + "&subtype=0";break; } //删除流媒体 if (selectVtduByName(name) != null) { deleteVtduByName(name); } //添加到流媒体 CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo()); CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(camera.getFactory()); Map videoCompressionCfg = cameraSDK.getVideoCompressionCfg(cmd); Vtdu vtdu = new Vtdu(); if (videoCompressionCfg.get("videoEncType") != null) { if (videoCompressionCfg.get("videoEncType").equals("标准h264")) { vtdu.setIsCode("0");//默认不转码 } else { vtdu.setIsCode("1");//默认转码 } } else { vtdu.setIsCode("0");//默认不转码 } vtdu.setRtspSource(rtspSource); vtdu.setName(name); vtdu.setMode("1");//默认CPU软解码 vtdu.setCameraId(camera.getId()); String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name; String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name; String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name; vtdu.setRtmpUrl(rtmpUrl); vtdu.setWebrtcUrl(webrtcUrl); vtdu.setRtspUrl(rtspUrl); insertVtdu(vtdu); } }