Commit 85893e4cfb427ca2209af2f8212de5376c7ca375

Authored by xp.Huang
1 parent 93d5f400

perf: 优化萤石云、海康ISC视频播放,并移除退出视频流播放接口

... ... @@ -9,7 +9,6 @@ import org.springframework.validation.annotation.Validated;
9 9 import org.springframework.web.bind.annotation.*;
10 10 import org.thingsboard.server.common.data.exception.ThingsboardException;
11 11 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
12   -import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
13 12 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
14 13 import org.thingsboard.server.common.data.yunteng.dto.TkVideoDTO;
15 14 import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
... ... @@ -91,18 +90,6 @@ public class TkVideoController extends BaseController {
91 90 @PathVariable("entityId") String entityId) throws ThingsboardException, IOException {
92 91 return getCameraURL(entityId, null);
93 92 }
94   -
95   - @GetMapping("outVideo/{entityId}")
96   - @ApiOperation("退出视频流播放")
97   - public void outVideo(
98   - @PathVariable("entityId") String entityId) throws ThingsboardException {
99   - videoService.outVideo(
100   - getCurrentUser().isTenantAdmin(),
101   - getCurrentUser().getCurrentUserId(),
102   - getCurrentUser().getCurrentTenantId(),
103   - entityId);
104   - }
105   -
106 93 @GetMapping("url/{entityId}/{protocolType}")
107 94 @ApiOperation("获取平台视频流播放地址")
108 95 public ResponseResult<Map<String, String>> getCameraPreviewURL(
... ...
... ... @@ -9,7 +9,8 @@ import org.thingsboard.server.common.data.yunteng.utils.HttpClientUtils;
9 9 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
10 10
11 11 import java.io.IOException;
12   -import java.text.SimpleDateFormat;
  12 +import java.time.LocalDateTime;
  13 +import java.time.format.DateTimeFormatter;
13 14 import java.util.Date;
14 15 import java.util.HashMap;
15 16 import java.util.Map;
... ... @@ -22,8 +23,9 @@ public class EzvizUtils {
22 23 private static Long expireTime;
23 24
24 25 public static String getCameraPreviewURL(String appKey, String appSecret, String sn,Integer streamType) throws IOException {
  26 + String key = appKey+sn;
25 27 //查询缓存中是否已有该设备的直播url
26   - String videoUrl = VideoNumbersUtils.getUrl(appKey+sn+streamType);
  28 + String videoUrl = VideoUrlUtils.getUrl(key);
27 29 if(!StringUtils.isEmpty(videoUrl)){
28 30 return videoUrl;
29 31 }
... ... @@ -44,8 +46,10 @@ public class EzvizUtils {
44 46 }
45 47 throw new TkDataValidationException(message);
46 48 }
  49 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  50 + LocalDateTime expireTime = LocalDateTime.parse(json.get("expireTime").asText(), formatter);
47 51 //将获取到的rul放入缓存
48   - VideoNumbersUtils.putVideoUrl(appKey+sn,json.get("url").textValue());
  52 + VideoUrlUtils.putVideoUrl(key,json.get("url").textValue(),expireTime);
49 53 return json.get("url").textValue();
50 54 }else{
51 55 String errorCode = json.get("code").asText();
... ... @@ -92,12 +96,4 @@ public class EzvizUtils {
92 96 throw new TkDataValidationException(ErrorMessage.OPERATION_FAILED.getMessage());
93 97 }
94 98 }
95   -
96   - public static void main(String[] args) {
97   - Date date = new Date(1703235281);
98   - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
99   -
100   - System.out.println(sdf.format(date));
101   - }
102   -
103 99 }
... ...
... ... @@ -2,7 +2,6 @@ package org.thingsboard.server.common.data.yunteng.utils.tools;
2 2
3 3
4 4 import com.fasterxml.jackson.databind.JsonNode;
5   -import com.fasterxml.jackson.databind.node.ObjectNode;
6 5 import com.hikvision.artemis.sdk.ArtemisHttpUtil;
7 6 import com.hikvision.artemis.sdk.config.ArtemisConfig;
8 7 import org.apache.commons.lang3.StringUtils;
... ... @@ -11,6 +10,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio
11 10 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
12 11 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
13 12
  13 +import java.time.LocalDateTime;
14 14 import java.util.HashMap;
15 15 import java.util.Map;
16 16 import java.util.Objects;
... ... @@ -36,7 +36,8 @@ public class HikVisionArtemisPostUtils {
36 36
37 37 public static String getCameraPreviewURL(String host, String appKey, String appSecret, int ssl,
38 38 ProtocolType protocolType,String body,String sn ) {
39   - String videoUrl = VideoNumbersUtils.getUrl(appKey+sn);
  39 + String key = appKey+sn;
  40 + String videoUrl = VideoUrlUtils.getUrl(key);
40 41 if(!StringUtils.isEmpty(videoUrl)){
41 42 return videoUrl;
42 43 }
... ... @@ -62,7 +63,7 @@ public class HikVisionArtemisPostUtils {
62 63 }
63 64 throw new TkDataValidationException(message);
64 65 }
65   - VideoNumbersUtils.putVideoUrl(appKey+sn,json.get("url").textValue());
  66 + VideoUrlUtils.putVideoUrl(key,json.get("url").textValue(), LocalDateTime.now().plusMinutes(5));
66 67 return json.get("url").textValue();
67 68 }else{
68 69 String errorCode = json.get("code").asText();
... ...
1   -package org.thingsboard.server.common.data.yunteng.utils.tools;
2   -
3   -import java.util.HashMap;
4   -import java.util.Map;
5   -
6   -public class VideoNumbersUtils {
7   -
8   - private static Map<String, Map<String,Object>> number = new HashMap<>();
9   -
10   -
11   - public static void putVideoUrl(String key,String url) {
12   - Map<String,Object> newVideo = new HashMap<>();
13   - newVideo.put("url",url);
14   - newVideo.put("number",1);
15   - number.put(key,newVideo);
16   - }
17   -
18   - public static String getUrl(String key) {
19   - //获取已有直播链接并加入人数
20   - Map<String,Object> oldVideo = number.get(key);
21   - if(oldVideo==null){
22   - return null;
23   - }
24   - oldVideo.put("number",(int)oldVideo.get("number")+1);
25   - return oldVideo.get("url").toString();
26   - }
27   -
28   - public static void deleteVideoNumber(String key) {
29   - //减少直播间人数
30   - Map<String,Object> oldVideo = number.get(key);
31   - int videoNumber = (int) oldVideo.get("number");
32   - //只有一个人并且需要减少则直接删除
33   - if(videoNumber==1){
34   - number.remove(key);
35   - return;
36   - }
37   - oldVideo.put("number",(int)oldVideo.get("number")-1);
38   - }
39   -
40   -
41   -}
  1 +package org.thingsboard.server.common.data.yunteng.utils.tools;
  2 +
  3 +import java.time.LocalDateTime;
  4 +import java.util.HashMap;
  5 +import java.util.Map;
  6 +
  7 +public class VideoUrlUtils {
  8 +
  9 + private static Map<String, Map<String,Object>> videoUrlData = new HashMap<>();
  10 +
  11 +
  12 + public static void putVideoUrl(String key, String url, LocalDateTime expireTime) {
  13 + Map<String,Object> videoUrlInfo = new HashMap<>();
  14 + videoUrlInfo.put("url",url);
  15 + videoUrlInfo.put("expireTime",expireTime);
  16 + videoUrlData.put(key,videoUrlInfo);
  17 + }
  18 +
  19 + public static String getUrl(String key) {
  20 + Map<String,Object> videoUrlInfo = videoUrlData.get(key);
  21 + if(videoUrlInfo==null || videoUrlInfo.isEmpty()){
  22 + return null;
  23 + }
  24 + LocalDateTime expireTime = (LocalDateTime) videoUrlInfo.get("expireTime");
  25 + LocalDateTime nowTime = LocalDateTime.now();
  26 + //如果过期了返回null
  27 + return nowTime.isAfter(expireTime) ? null : videoUrlInfo.get("url").toString();
  28 + }
  29 +}
... ...
... ... @@ -93,16 +93,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
93 93 @Override
94 94 public String getCameraPreviewURL(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId,
95 95 ProtocolType protocolType) throws IOException {
96   - if (isTenantAdmin) {
97   - customerUserId = null;
98   - }
99   - //通过流媒体方式获取视频流的列表
100   - List<TkVideoDTO> videoDTOList = baseMapper.getVideoInfosByTenantIdOrAccessModeOrId(tenantId, entityId,
101   - FastIotConstants.MagicNumber.ONE, customerUserId);
102   - if (videoDTOList.size() == 0) {
103   - throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
104   - }
105   - TkVideoDTO videoDTO = videoDTOList.get(0);
  96 + TkVideoDTO videoDTO = getVideoInfo(isTenantAdmin,customerUserId,tenantId,entityId);
106 97 TkVideoPlatformDTO videoPlatformDTO = videoDTO.getVideoPlatformDTO();
107 98 if(videoPlatformDTO.getType()==0){//如果为海康威视
108 99 return HikVisionArtemis(videoDTO,protocolType);
... ... @@ -115,16 +106,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
115 106
116 107 @Override
117 108 public String controlli(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, int action, String command ) {
118   - if (isTenantAdmin) {
119   - customerUserId = null;
120   - }
121   - //通过流媒体方式获取视频流的列表
122   - List<TkVideoDTO> videoDTOList = baseMapper.getVideoInfosByTenantIdOrAccessModeOrId(tenantId, entityId,
123   - FastIotConstants.MagicNumber.ONE, customerUserId);
124   - if (videoDTOList.size() == 0) {
125   - throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
126   - }
127   - TkVideoDTO videoDTO = videoDTOList.get(0);
  109 + TkVideoDTO videoDTO = getVideoInfo(isTenantAdmin,customerUserId,tenantId,entityId);
128 110
129 111 //组装请求参数
130 112 ObjectNode jsonBody = JacksonUtil.newObjectNode();
... ... @@ -172,22 +154,6 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
172 154 }
173 155 return null;
174 156 }
175   -
176   - @Override
177   - public void outVideo(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId) {
178   - if (isTenantAdmin) {
179   - customerUserId = null;
180   - }
181   - //通过流媒体方式获取视频流的列表
182   - List<TkVideoDTO> videoDTOList = baseMapper.getVideoInfosByTenantIdOrAccessModeOrId(tenantId, entityId,
183   - FastIotConstants.MagicNumber.ONE, customerUserId);
184   - if (videoDTOList.size() == 0) {
185   - throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
186   - }
187   - TkVideoDTO videoDTO = videoDTOList.get(0);
188   - VideoNumbersUtils.deleteVideoNumber(videoDTO.getVideoPlatformDTO().getAppKey()+videoDTO.getSn());
189   - }
190   -
191 157 private String HikVisionArtemis(TkVideoDTO videoDTO, ProtocolType protocolType){
192 158 if(protocolType!=null && protocolType.equals(ProtocolType.HLS)){
193 159 protocolType = videoDTO.getPlayProtocol() == 0 ? ProtocolType.HLS : ProtocolType.HLSS;
... ... @@ -208,4 +174,17 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
208 174 videoDTO.getVideoPlatformDTO().getSsl(),protocolType,body,videoDTO.getSn());
209 175 }
210 176
  177 + private TkVideoDTO getVideoInfo(boolean isTenantAdmin,String customerUserId, String tenantId, String entityId){
  178 + if (isTenantAdmin) {
  179 + customerUserId = null;
  180 + }
  181 + //通过流媒体方式获取视频流的列表
  182 + List<TkVideoDTO> videoDTOList = baseMapper.getVideoInfosByTenantIdOrAccessModeOrId(tenantId, entityId,
  183 + FastIotConstants.MagicNumber.ONE, customerUserId);
  184 + if (videoDTOList.size() == 0) {
  185 + throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  186 + }
  187 + return videoDTOList.get(0);
  188 + }
  189 +
211 190 }
... ...
... ... @@ -104,9 +104,4 @@ public interface TkVideoService extends BaseService<TkVideoEntity> {
104 104 * @return 视频列表
105 105 */
106 106 List<TkVideoDTO> getVideoList(String organizationId, String tenantId);
107   -
108   - void outVideo( boolean isTenantAdmin,
109   - String customerUserId,
110   - String tenantId,
111   - String entityId);
112 107 }
... ...