ard-admin/src/main/java/com/ard/web/controller/vtdu/MediaMTXController.java
@@ -5,7 +5,7 @@ import com.ard.common.core.page.TableDataInfo; import com.ard.vtdu.domain.ArdVtdu; import com.ard.vtdu.domain.Conf; import com.ard.vtdu.service.IArdMediaMTXService; import com.ard.vtdu.service.IArdMediaService; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -27,14 +27,14 @@ public class MediaMTXController extends BaseController { @Resource private IArdMediaMTXService mediaService; private IArdMediaService mediaService; /** * 增加通道 */ @PostMapping() @ApiOperation("增加通道") @ApiOperationSupport(includeParameters = {"ardVtdu.name", "ardVtdu.rtspSource", "ardVtdu.mode", "ardVtdu.isCode", "ardVtdu.isRecord"}, order = 1) @ApiOperationSupport(includeParameters = {"ardVtdu.name", "ardVtdu.rtspSource"}, order = 1) public AjaxResult addPath(@RequestBody ArdVtdu ardVtdu) { if (StringUtils.isEmpty(ardVtdu.getName())) { return AjaxResult.error("通道名称不能为空"); @@ -50,7 +50,7 @@ * 修改通道 */ @ApiOperation("修改通道") @ApiOperationSupport(includeParameters = {"ardVtdu.name", "ardVtdu.rtspSource", "ardVtdu.mode", "ardVtdu.isCode", "ardVtdu.isRecord"}, order = 2) @ApiOperationSupport(includeParameters = {"ardVtdu.name", "ardVtdu.rtspSource"}, order = 2) @PutMapping public AjaxResult edit(@RequestBody ArdVtdu ardVtdu) { return AjaxResult.success(mediaService.editPath(ardVtdu)); ard-admin/src/main/java/com/ard/web/core/config/SwaggerConfig.java
@@ -91,6 +91,25 @@ .securitySchemes(securitySchemes()) .securityContexts(securityContexts()); } @Bean public Docket mediaMTXApi() { return new Docket(DocumentationType.SWAGGER_2) .enable(true) .groupName("流媒体接口") // 分组名 .apiInfo(apiInfo("流媒体管理接口")) .select() // 扫描指定包下,但只扫描加了 @ApiOperation 注解的方法 .apis(requestHandler -> requestHandler.declaringClass().getPackage().getName().startsWith("com.ard.web.controller" + ".vtdu") && requestHandler.isAnnotatedWith(io.swagger.annotations.ApiOperation.class) ) .paths(PathSelectors.any()) .build() /* 设置安全模式,swagger可以设置访问token */ .securitySchemes(securitySchemes()) .securityContexts(securityContexts()); } /** * 安全模式,这里指定token通过Authorization头请求头传递 */ ard-admin/src/main/resources/logback.xml
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 日志存放路径 --> <property name="log.path" value="/home/ruoyi/logs" /> <property name="log.path" value="/home/ard/jar/logs" /> <!-- 日志输出格式 --> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> ard-device/src/main/java/com/ard/device/camera/service/impl/ArdCameraServiceImpl.java
@@ -25,6 +25,7 @@ import org.springframework.boot.ApplicationRunner; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.validation.Validator; @@ -54,6 +55,7 @@ @Resource protected Validator validator; @Override public void run(ApplicationArguments args) { @@ -353,5 +355,32 @@ // SDK 登录成功后写入 Redis redisService.setCacheObject(getCacheKey(camera.getId()), camera); } /** * 同步设备通道与本地通道库信息 * * @author 刘苏义 * @date 2024/8/22 14:37 */ @Scheduled(cron = "0/10 * * * * ?") public void syncChannel() { try { log.info("定时执行同步通道任务"); List<ArdCamera> ardCameraList = this.selectArdCameraList(new ArdCamera()); if (!ardCameraList.isEmpty()) { ardCameraList .forEach(ardCamera -> { //SDK获取实际通道 List<ArdChannel> ardChannelListSDK = cameraSDKService.getChannels(ardCamera); //数据库获取通道 ArdChannel ardChannel = new ArdChannel(); ardChannel.setDeviceId(ardCamera.getId()); List<ArdChannel> ardChannelListDb = ardChannelService.selectArdChannelList(ardChannel); //同步通道 asyncChannel(ardChannelListDb, ardChannelListSDK); }); } } catch (Exception ex) { log.error("定时执行同步通道任务异常:{}", ex.getMessage()); } } } ard-device/src/main/java/com/ard/device/component/sdk/hik/service/impl/HikVisionSDK.java
@@ -111,7 +111,7 @@ SdkErrorCodeEnum.getDescByCode(errorCode), errorCode); return AjaxResult.warn("设备[" + camera.getIp() + ":" + camera.getPort() + "]登录失败: " + SdkErrorCodeEnum.getDescByCode(errorCode) + "(" + errorCode + ")"); } log.debug("Login Success 【 {}:{} 】", camera.getIp(), camera.getPort()); log.info("Login Success 【 {}:{} 】", camera.getIp(), camera.getPort()); GlobalVariable.loginMap.put(camera.getId(), loginId); GlobalVariable.hikLoginMap.put(loginId, camera); ard-device/src/main/java/com/ard/device/component/sdk/service/CameraSDK.java
@@ -3,7 +3,10 @@ import com.ard.common.core.domain.AjaxResult; import com.ard.device.camera.domain.ArdCamera; import com.ard.device.camera.domain.CameraCmd; import com.ard.device.channel.domain.ArdChannel; import com.ard.device.channel.domain.VideoCompressionCfg; import java.util.List; /** @@ -25,4 +28,6 @@ //获取码流压缩参数 VideoCompressionCfg getVideoCompressionCfg(CameraCmd cmd); //获取相机通道信息 public List<ArdChannel> getChannels(ArdCamera camera); } ard-device/src/main/java/com/ard/device/component/sdk/service/CameraSDKService.java
@@ -5,6 +5,7 @@ import com.ard.common.core.redis.RedisCache; import com.ard.device.camera.domain.ArdCamera; import com.ard.device.camera.domain.CameraCmd; import com.ard.device.channel.domain.ArdChannel; import com.ard.device.channel.domain.VideoCompressionCfg; import com.ard.device.component.sdk.common.GlobalVariable; import com.ard.device.component.sdk.factory.CameraSDKFactory; @@ -105,5 +106,14 @@ } } //获取通道列表 public List<ArdChannel> getChannels(ArdCamera camera) { try { CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(camera.getFactory()); return cameraSDK.getChannels(camera); } catch (Exception ex) { log.error("获取相机通道异常:{}", ex.getMessage()); return null; } } } ard-sample/src/main/java/com/ard/sample/manage/service/impl/LiveStreamServiceImpl.java
@@ -20,7 +20,7 @@ import com.ard.sample.manage.service.ILiveStreamService; import com.ard.vtdu.config.MediamtxConfig; import com.ard.vtdu.domain.ArdVtdu; import com.ard.vtdu.service.IArdMediaMTXService; import com.ard.vtdu.service.IArdMediaService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -52,7 +52,7 @@ private IMessageSenderService messageSender; @Resource private IArdMediaMTXService mediaService; private IArdMediaService ardMediaService; @Resource private MediamtxConfig mediamtxConfig; @@ -118,7 +118,8 @@ case RTMP: ArdVtdu vtdu = new ArdVtdu(); vtdu.setName(liveParam.getVideoId()); vtdu = mediaService.addPath(vtdu); vtdu.setRtspSource("publisher"); vtdu = ardMediaService.addPath(vtdu); live.setRtmpUrl(vtdu.getRtmpUrl()); live.setRtspUrl(vtdu.getRtspUrl()); live.setWebrtcUrl(vtdu.getWebrtcUrl()); @@ -147,7 +148,7 @@ if (receiveReply.getResult() != 0) { return ResponseResult.error(LiveErrorEnum.find(receiveReply.getResult())); } mediaService.removePath(videoId); ardMediaService.removePath(videoId); return ResponseResult.success(); } ard-vtdu/src/main/java/com/ard/vtdu/domain/StreamInfo.java
@@ -67,17 +67,6 @@ String remoteAddr; /** * 解码模式 * 0-gpu硬解码 1-cpu软解码 */ Integer mode; /** * 是否转码 * 0-不转码 1-转码 */ Integer isCode; /** * 媒体类型(webRTCSession/rtspSession) */ String sessionType; ard-vtdu/src/main/java/com/ard/vtdu/service/IArdMediaMTXService.java
File was deleted ard-vtdu/src/main/java/com/ard/vtdu/service/IArdMediaService.java
File was renamed from ard-vtdu/src/main/java/com/ard/vtdu/service/IMediaService.java @@ -5,7 +5,7 @@ import java.util.List; public interface IMediaService { public interface IArdMediaService { /** * 增加路径 */ ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java
File was renamed from ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdMediaServiceImpl.java @@ -5,7 +5,7 @@ import com.ard.vtdu.client.MediaClient; import com.ard.vtdu.config.MediamtxConfig; import com.ard.vtdu.domain.*; import com.ard.vtdu.service.IMediaService; import com.ard.vtdu.service.IArdMediaService; import com.ard.vtdu.util.ArdTool; import com.dtflys.forest.exceptions.ForestRuntimeException; import lombok.extern.slf4j.Slf4j; @@ -29,7 +29,7 @@ **/ @Service @Slf4j public class ArdMediaServiceImpl implements IMediaService { public class ArdArdMediaServiceImpl implements IArdMediaService { @Resource MediaClient mediaClient; @@ -88,8 +88,8 @@ String webrtcUrl = protocol + mediamtxConfig.getPlayHost() + ":8889/" + ardVtdu.getName(); Conf conf = new Conf(); conf.setName(ardVtdu.getName()); conf.setSource(ardVtdu.getRtspSource()); conf.setName(ardVtdu.getName()); conf.setRunOnDemand(""); conf.setRunOnDemandRestart(false); conf.setRunOnDemandCloseAfter("5s"); @@ -148,17 +148,8 @@ if (StringUtils.isNotEmpty(conf.getRunOnDemand())) { runOn = conf.getRunOnDemand(); } //RTSP源地址 Matcher matcher = Pattern.compile("rtsp://[^\\s\"]+").matcher(runOn); if (matcher.find()) { info.setRtspSource(matcher.group()); info.setIsCode(1); } else { info.setRtspSource(conf.getSource()); info.setIsCode(0); } //传输协议 matcher = Pattern.compile("-rtsp_transport\\s+(\\w+)").matcher(runOn); Matcher matcher = Pattern.compile("-rtsp_transport\\s+(\\w+)").matcher(runOn); if (matcher.find()) { info.setProtocol(matcher.group(1)); } ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdMediaMTXServiceImpl.java
File was deleted ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdVtduServiceImpl.java
@@ -1,12 +1,11 @@ package com.ard.vtdu.service.impl; import com.ard.common.utils.DateUtils; import com.ard.vtdu.config.MediamtxConfig; import com.ard.vtdu.domain.ArdVtdu; import com.ard.vtdu.domain.Conf; import com.ard.vtdu.mapper.ArdVtduMapper; import com.ard.vtdu.service.IArdVtduService; import com.ard.vtdu.service.IMediaService; import com.ard.vtdu.service.IArdMediaService; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -29,7 +28,7 @@ @Resource private ArdVtduMapper ardVtduMapper; @Resource private IMediaService mediaService; private IArdMediaService mediaService; ard-vtdu/src/main/resources/mapper/ArdVtduMapper.xml
@@ -4,7 +4,7 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ard.vtdu.mapper.ArdVtduMapper"> <resultMap type="com.ard.vtdu.mapper.ArdVtduMapper" id="ArdVtduResult"> <resultMap type="ArdVtdu" id="ArdVtduResult"> <result property="name" column="name"/> <result property="rtspSource" column="rtsp_source"/> <result property="rtspUrl" column="rtsp_url"/>