Commit 85893e4cfb427ca2209af2f8212de5376c7ca375

Authored by xp.Huang
1 parent 93d5f400

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

@@ -9,7 +9,6 @@ import org.springframework.validation.annotation.Validated; @@ -9,7 +9,6 @@ import org.springframework.validation.annotation.Validated;
9 import org.springframework.web.bind.annotation.*; 9 import org.springframework.web.bind.annotation.*;
10 import org.thingsboard.server.common.data.exception.ThingsboardException; 10 import org.thingsboard.server.common.data.exception.ThingsboardException;
11 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup; 11 import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
12 -import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;  
13 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; 12 import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
14 import org.thingsboard.server.common.data.yunteng.dto.TkVideoDTO; 13 import org.thingsboard.server.common.data.yunteng.dto.TkVideoDTO;
15 import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; 14 import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
@@ -91,18 +90,6 @@ public class TkVideoController extends BaseController { @@ -91,18 +90,6 @@ public class TkVideoController extends BaseController {
91 @PathVariable("entityId") String entityId) throws ThingsboardException, IOException { 90 @PathVariable("entityId") String entityId) throws ThingsboardException, IOException {
92 return getCameraURL(entityId, null); 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 @GetMapping("url/{entityId}/{protocolType}") 93 @GetMapping("url/{entityId}/{protocolType}")
107 @ApiOperation("获取平台视频流播放地址") 94 @ApiOperation("获取平台视频流播放地址")
108 public ResponseResult<Map<String, String>> getCameraPreviewURL( 95 public ResponseResult<Map<String, String>> getCameraPreviewURL(
@@ -9,7 +9,8 @@ import org.thingsboard.server.common.data.yunteng.utils.HttpClientUtils; @@ -9,7 +9,8 @@ import org.thingsboard.server.common.data.yunteng.utils.HttpClientUtils;
9 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; 9 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
10 10
11 import java.io.IOException; 11 import java.io.IOException;
12 -import java.text.SimpleDateFormat; 12 +import java.time.LocalDateTime;
  13 +import java.time.format.DateTimeFormatter;
13 import java.util.Date; 14 import java.util.Date;
14 import java.util.HashMap; 15 import java.util.HashMap;
15 import java.util.Map; 16 import java.util.Map;
@@ -22,8 +23,9 @@ public class EzvizUtils { @@ -22,8 +23,9 @@ public class EzvizUtils {
22 private static Long expireTime; 23 private static Long expireTime;
23 24
24 public static String getCameraPreviewURL(String appKey, String appSecret, String sn,Integer streamType) throws IOException { 25 public static String getCameraPreviewURL(String appKey, String appSecret, String sn,Integer streamType) throws IOException {
  26 + String key = appKey+sn;
25 //查询缓存中是否已有该设备的直播url 27 //查询缓存中是否已有该设备的直播url
26 - String videoUrl = VideoNumbersUtils.getUrl(appKey+sn+streamType); 28 + String videoUrl = VideoUrlUtils.getUrl(key);
27 if(!StringUtils.isEmpty(videoUrl)){ 29 if(!StringUtils.isEmpty(videoUrl)){
28 return videoUrl; 30 return videoUrl;
29 } 31 }
@@ -44,8 +46,10 @@ public class EzvizUtils { @@ -44,8 +46,10 @@ public class EzvizUtils {
44 } 46 }
45 throw new TkDataValidationException(message); 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 //将获取到的rul放入缓存 51 //将获取到的rul放入缓存
48 - VideoNumbersUtils.putVideoUrl(appKey+sn,json.get("url").textValue()); 52 + VideoUrlUtils.putVideoUrl(key,json.get("url").textValue(),expireTime);
49 return json.get("url").textValue(); 53 return json.get("url").textValue();
50 }else{ 54 }else{
51 String errorCode = json.get("code").asText(); 55 String errorCode = json.get("code").asText();
@@ -92,12 +96,4 @@ public class EzvizUtils { @@ -92,12 +96,4 @@ public class EzvizUtils {
92 throw new TkDataValidationException(ErrorMessage.OPERATION_FAILED.getMessage()); 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,7 +2,6 @@ package org.thingsboard.server.common.data.yunteng.utils.tools;
2 2
3 3
4 import com.fasterxml.jackson.databind.JsonNode; 4 import com.fasterxml.jackson.databind.JsonNode;
5 -import com.fasterxml.jackson.databind.node.ObjectNode;  
6 import com.hikvision.artemis.sdk.ArtemisHttpUtil; 5 import com.hikvision.artemis.sdk.ArtemisHttpUtil;
7 import com.hikvision.artemis.sdk.config.ArtemisConfig; 6 import com.hikvision.artemis.sdk.config.ArtemisConfig;
8 import org.apache.commons.lang3.StringUtils; 7 import org.apache.commons.lang3.StringUtils;
@@ -11,6 +10,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio @@ -11,6 +10,7 @@ import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidatio
11 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; 10 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
12 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; 11 import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil;
13 12
  13 +import java.time.LocalDateTime;
14 import java.util.HashMap; 14 import java.util.HashMap;
15 import java.util.Map; 15 import java.util.Map;
16 import java.util.Objects; 16 import java.util.Objects;
@@ -36,7 +36,8 @@ public class HikVisionArtemisPostUtils { @@ -36,7 +36,8 @@ public class HikVisionArtemisPostUtils {
36 36
37 public static String getCameraPreviewURL(String host, String appKey, String appSecret, int ssl, 37 public static String getCameraPreviewURL(String host, String appKey, String appSecret, int ssl,
38 ProtocolType protocolType,String body,String sn ) { 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 if(!StringUtils.isEmpty(videoUrl)){ 41 if(!StringUtils.isEmpty(videoUrl)){
41 return videoUrl; 42 return videoUrl;
42 } 43 }
@@ -62,7 +63,7 @@ public class HikVisionArtemisPostUtils { @@ -62,7 +63,7 @@ public class HikVisionArtemisPostUtils {
62 } 63 }
63 throw new TkDataValidationException(message); 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 return json.get("url").textValue(); 67 return json.get("url").textValue();
67 }else{ 68 }else{
68 String errorCode = json.get("code").asText(); 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,16 +93,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
93 @Override 93 @Override
94 public String getCameraPreviewURL(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, 94 public String getCameraPreviewURL(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId,
95 ProtocolType protocolType) throws IOException { 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 TkVideoPlatformDTO videoPlatformDTO = videoDTO.getVideoPlatformDTO(); 97 TkVideoPlatformDTO videoPlatformDTO = videoDTO.getVideoPlatformDTO();
107 if(videoPlatformDTO.getType()==0){//如果为海康威视 98 if(videoPlatformDTO.getType()==0){//如果为海康威视
108 return HikVisionArtemis(videoDTO,protocolType); 99 return HikVisionArtemis(videoDTO,protocolType);
@@ -115,16 +106,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid @@ -115,16 +106,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
115 106
116 @Override 107 @Override
117 public String controlli(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, int action, String command ) { 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 ObjectNode jsonBody = JacksonUtil.newObjectNode(); 112 ObjectNode jsonBody = JacksonUtil.newObjectNode();
@@ -172,22 +154,6 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid @@ -172,22 +154,6 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
172 } 154 }
173 return null; 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 private String HikVisionArtemis(TkVideoDTO videoDTO, ProtocolType protocolType){ 157 private String HikVisionArtemis(TkVideoDTO videoDTO, ProtocolType protocolType){
192 if(protocolType!=null && protocolType.equals(ProtocolType.HLS)){ 158 if(protocolType!=null && protocolType.equals(ProtocolType.HLS)){
193 protocolType = videoDTO.getPlayProtocol() == 0 ? ProtocolType.HLS : ProtocolType.HLSS; 159 protocolType = videoDTO.getPlayProtocol() == 0 ? ProtocolType.HLS : ProtocolType.HLSS;
@@ -208,4 +174,17 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid @@ -208,4 +174,17 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid
208 videoDTO.getVideoPlatformDTO().getSsl(),protocolType,body,videoDTO.getSn()); 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,9 +104,4 @@ public interface TkVideoService extends BaseService<TkVideoEntity> {
104 * @return 视频列表 104 * @return 视频列表
105 */ 105 */
106 List<TkVideoDTO> getVideoList(String organizationId, String tenantId); 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 }