소스 검색

add 媒体设备刷新通道

18339543638 3 년 전
부모
커밋
970da9be83

+ 2 - 4
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/media/controller/MediaDeviceChannelController.java

@@ -6,11 +6,9 @@ import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.annotation.Resource;
 import org.hswebframework.web.crud.service.ReactiveCrudService;
-import org.hswebframework.web.crud.web.reactive.ReactiveServiceQueryController;
-import org.jetlinks.community.media.entity.MediaDevice;
+import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
 import org.jetlinks.community.media.entity.MediaDeviceChannel;
 import org.jetlinks.community.media.service.LocalMediaDeviceChannelService;
-import org.jetlinks.community.media.service.LocalMediaDeviceService;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -28,7 +26,7 @@ import org.springframework.web.bind.annotation.RestController;
 @Resource(id="media-channel",name = "媒体流设备通道")
 @AllArgsConstructor
 @Tag(name = "媒体视频设备")
-public class MediaDeviceChannelController implements ReactiveServiceQueryController<MediaDeviceChannel, String> {
+public class MediaDeviceChannelController implements ReactiveServiceCrudController<MediaDeviceChannel, String> {
     private LocalMediaDeviceChannelService mediaDeviceChannelService;
     @Override
     public ReactiveCrudService<MediaDeviceChannel, String> getService() {

+ 74 - 0
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/media/controller/MediaDeviceController.java

@@ -28,6 +28,8 @@ import org.jetlinks.core.device.DeviceRegistry;
 import org.jetlinks.core.device.StandaloneDeviceMessageBroker;
 import org.jetlinks.core.exception.DeviceOperationException;
 import org.jetlinks.core.message.DeviceMessageReply;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -184,6 +186,78 @@ public class MediaDeviceController implements ReactiveServiceCrudController<Medi
             );
     }
 
+
+    /***
+     * 云台控制
+     * @param deviceId 设备id
+     * @param channelId 通道id
+     * @param command	控制指令 允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop
+
+     * @return String 控制结果
+     */
+    @Operation(summary = "云台控制")
+    @PostMapping("/{deviceId}/{channelId}/_ptz/{command}/{speed}")
+    public Mono<Void> ptz(@PathVariable("deviceId") String deviceId, @PathVariable("channelId") String channelId, @PathVariable("command") String command, @PathVariable("speed") int speed){
+       return  mediaDeviceService.findById(deviceId)
+           .switchIfEmpty(Mono.error(new BusinessException("设备已注销")))
+            .flatMap(device->{
+                if(device.getState()==DeviceState.offline){
+                    return Mono.error(new BusinessException("设备已下线"));
+                }
+                int cmdCode = 0;
+                //orizonSpeed	水平移动速度
+                int horizonSpeed=0;
+                // verticalSpeed	垂直移动速度
+                int verticalSpeed=0;
+                //zoomSpeed	    缩放速度
+                int zoomSpeed=0;
+                switch (command){
+                    case "left":
+                        cmdCode = 2;
+                        horizonSpeed=speed;
+                        break;
+                    case "right":
+                        cmdCode = 1;
+                        horizonSpeed=speed;
+                        break;
+                    case "up":
+                        cmdCode = 8;
+                        verticalSpeed=speed;
+                        break;
+                    case "down":
+                        cmdCode = 4;
+                        verticalSpeed=speed;
+                        break;
+                    case "upleft":
+                        cmdCode = 10;
+                        break;
+                    case "upright":
+                        cmdCode = 9;
+                        break;
+                    case "downleft":
+                        cmdCode = 6;
+                        break;
+                    case "downright":
+                        cmdCode = 5;
+                        break;
+                    case "zoomin":
+                        cmdCode = 16;
+                        zoomSpeed=speed;
+                        break;
+                    case "zoomout":
+                        cmdCode = 32;
+                        zoomSpeed=speed;
+                        break;
+                    case "stop":
+                        cmdCode = 0;
+                        break;
+                    default:
+                        break;
+                }
+                return cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
+            });
+
+    }
     private Flux<Object> convertReply(DeviceMessageReply reply){
         if(reply instanceof MediaMessageReply){
             MediaMessageReply<Object> messageReply= (MediaMessageReply<Object>) reply;

+ 4 - 2
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/media/service/LocalPlayService.java

@@ -114,8 +114,9 @@ public class LocalPlayService  {
                             MediaMessageReply messageReply = MediaMessageReply.of("点播失败, 请求已超时",null);
                             messageReply.setSuccess(false);
                             return Mono.empty();
+                        }else {
+                            redisCatchStorage.cacheStreamId(streamId,device);
                         }
-                        redisCatchStorage.cacheStreamId(streamId,device);
                         return    Mono.justOrEmpty(redisCatchStorage.getMediaServerItem(streamInfo.getMediaServerId()))
                             .flatMap(mediaInfo->{
                                 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
@@ -134,6 +135,7 @@ public class LocalPlayService  {
                                 } else {
                                     // TODO 点播前是否重置状态
                                     redisCatchStorage.stopPlay(streamInfo);
+                                    redisCatchStorage.removeCacheDeviceByStream(streamId);
                                     deviceChannelService.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
                                     SSRCInfo ssrcInfo;
                                     String streamId2 = null;
@@ -141,7 +143,7 @@ public class LocalPlayService  {
                                         streamId2 = String.format("%s_%s", device.getId(), channelId);
                                     }
                                     ssrcInfo = mediaServerItemService.openRTPServer(mediaServerItem, streamId2);
-
+                                    redisCatchStorage.cacheStreamId(ssrcInfo.getStreamId(),device);
                                     return cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
                                         log.info("收到订阅消息: " + response.toString());
                                         onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId).subscribe();

+ 5 - 0
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/media/storage/impl/RedisCacheStorageImpl.java

@@ -543,4 +543,9 @@ public class RedisCacheStorageImpl {
         String key=VideoManagerConstants.MEDIA_STREAM_PREFIX+serverId+"_CACHE_"+streamId;
         return (MediaDevice) redis.get(key);
     }
+
+    public void removeCacheDeviceByStream(String streamId) {
+        String key=VideoManagerConstants.MEDIA_STREAM_PREFIX+serverId+"_CACHE_"+streamId;
+        redis.del(key);
+    }
 }

+ 52 - 0
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/media/transmit/cmd/SipCommander.java

@@ -421,6 +421,58 @@ public class SipCommander {
         });
     }
 
+    public Mono<Void> frontEndCmd(MediaDevice device, String channelId, int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed) {
+        try {
+            String cmdStr= frontEndCmdString(cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
+            log.debug("控制字符串:" + cmdStr);
+            StringBuffer ptzXml = new StringBuffer(200);
+            ptzXml.append("<?xml version=\"1.0\" ?>\r\n");
+            ptzXml.append("<Control>\r\n");
+            ptzXml.append("<CmdType>DeviceControl</CmdType>\r\n");
+            ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
+            ptzXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
+            ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>\r\n");
+            ptzXml.append("<Info>\r\n");
+            ptzXml.append("</Info>\r\n");
+            ptzXml.append("</Control>\r\n");
+
+            String tm = Long.toString(System.currentTimeMillis());
+
+            CallIdHeader callIdHeader = SipContext.getSipProvider().getNewCallId();
+
+            Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+            return transmitRequest(SipContext.getSipProvider(), request);
+        } catch (SipException | ParseException | InvalidArgumentException e) {
+            log.error("发送cmd命令失败,",e);
+            return Mono.error(new BusinessException("系统繁忙,请稍后再试"));
+        }
+    }
+
+    /**
+     * 云台指令码计算
+     *
+     * @param cmdCode 		指令码
+     * @param parameter1	数据1
+     * @param parameter2	数据2
+     * @param combineCode2	组合码2
+     */
+    public static String frontEndCmdString(int cmdCode, int parameter1, int parameter2, int combineCode2) {
+        StringBuilder builder = new StringBuilder("A50F01");
+        String strTmp;
+        strTmp = String.format("%02X", cmdCode);
+        builder.append(strTmp, 0, 2);
+        strTmp = String.format("%02X", parameter1);
+        builder.append(strTmp, 0, 2);
+        strTmp = String.format("%02X", parameter2);
+        builder.append(strTmp, 0, 2);
+        strTmp = String.format("%X", combineCode2);
+        builder.append(strTmp, 0, 1).append("0");
+        //计算校验码
+        int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 & 0XF0)) % 0X100;
+        strTmp = String.format("%02X", checkCode);
+        builder.append(strTmp, 0, 2);
+        return builder.toString();
+    }
 
 //    private Mono<Void> transmitRequest(SipProvider sipProvider, Request request, SipSubscribe.Event event) throws SipException {
 //        ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

+ 1 - 2
jetlinks-manager/media-manager/src/main/java/org/jetlinks/community/utils/XmlUtil.java

@@ -257,8 +257,7 @@ public class XmlUtil {
         } else {
             deviceChannel.setLatitude(0.00);
         }
-        if (XmlUtil.getText(itemDevice, "PTZType") == null
-            || XmlUtil.getText(itemDevice, "PTZType") == "") {
+        if (StringUtils.isEmpty(XmlUtil.getText(itemDevice, "PTZType"))) {
             deviceChannel.setPtzType(PtzType.UNKNOWN);
         } else {
             deviceChannel.setPtzType(PtzType.of(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))));