Showing
10 changed files
with
181 additions
and
45 deletions
... | ... | @@ -20,6 +20,7 @@ import org.thingsboard.server.controller.BaseController; |
20 | 20 | import org.thingsboard.server.dao.yunteng.entities.TkVideoEntity; |
21 | 21 | import org.thingsboard.server.dao.yunteng.service.TkVideoService; |
22 | 22 | |
23 | +import java.io.IOException; | |
23 | 24 | import java.util.HashMap; |
24 | 25 | import java.util.List; |
25 | 26 | import java.util.Map; |
... | ... | @@ -87,7 +88,7 @@ public class TkVideoController extends BaseController { |
87 | 88 | @GetMapping("url/{entityId}") |
88 | 89 | @ApiOperation("获取平台视频流播放地址") |
89 | 90 | public ResponseResult<Map<String, String>> getCameraPreviewURL( |
90 | - @PathVariable("entityId") String entityId) throws ThingsboardException { | |
91 | + @PathVariable("entityId") String entityId) throws ThingsboardException, IOException { | |
91 | 92 | return getCameraURL(entityId, null); |
92 | 93 | } |
93 | 94 | |
... | ... | @@ -96,7 +97,7 @@ public class TkVideoController extends BaseController { |
96 | 97 | public ResponseResult<Map<String, String>> getCameraPreviewURL( |
97 | 98 | @PathVariable("entityId") String entityId, |
98 | 99 | @PathVariable("protocolType") ProtocolType protocolType) |
99 | - throws ThingsboardException { | |
100 | + throws ThingsboardException, IOException { | |
100 | 101 | if (!protocolType.equals(ProtocolType.RTSP) |
101 | 102 | && !protocolType.equals(ProtocolType.RTMP) |
102 | 103 | && !protocolType.equals(ProtocolType.HLS)) { |
... | ... | @@ -128,13 +129,12 @@ public class TkVideoController extends BaseController { |
128 | 129 | getCurrentUser().getCurrentTenantId(), |
129 | 130 | organizationId, |
130 | 131 | action, |
131 | - command, | |
132 | - FastIotConstants.HkwsBuinessType.CONTROLLING | |
132 | + command | |
133 | 133 | )); |
134 | 134 | } |
135 | 135 | |
136 | 136 | private ResponseResult<Map<String, String>> getCameraURL( |
137 | - String entityId, ProtocolType protocolType) throws ThingsboardException { | |
137 | + String entityId, ProtocolType protocolType) throws ThingsboardException, IOException { | |
138 | 138 | if (protocolType == null) { |
139 | 139 | protocolType = ProtocolType.HLS; |
140 | 140 | } |
... | ... | @@ -144,8 +144,7 @@ public class TkVideoController extends BaseController { |
144 | 144 | getCurrentUser().getCurrentUserId(), |
145 | 145 | getCurrentUser().getCurrentTenantId(), |
146 | 146 | entityId, |
147 | - protocolType, | |
148 | - FastIotConstants.HkwsBuinessType.GET_URL); | |
147 | + protocolType); | |
149 | 148 | Map<String, String> map = new HashMap<>(); |
150 | 149 | map.put("url", url); |
151 | 150 | return ResponseResult.success(map); | ... | ... |
... | ... | @@ -212,6 +212,7 @@ public interface FastIotConstants { |
212 | 212 | public static String CONTROLLING = "controlling"; |
213 | 213 | } |
214 | 214 | |
215 | + | |
215 | 216 | class TkNodeClassName{ |
216 | 217 | public static String GET_ORIGINATOR_FIELDS_NODE = "org.thingsboard.rule.engine.metadata.TbGetOriginatorFieldsNode"; |
217 | 218 | public static String TB_SCENE_REACT_NODE= "org.thingsboard.rule.engine.yunteng.scene.TbSceneReactNode"; | ... | ... |
... | ... | @@ -117,8 +117,11 @@ public enum ErrorMessage { |
117 | 117 | GET_DEVICE_lIST_ERROR(400092, "请先在组态编辑页面绑定产品"), |
118 | 118 | CATEGORY_DELETE_ERROR(400093,"删除品类前,请先删除绑定的产品。"), |
119 | 119 | IMPORT_TCP_SERVICE_ERROR(400094,"品类无法创建TCP产品的服务,请在产品内添加"), |
120 | + EZVIZ_API_ERROR(400095,"荧石视频获取TokenAPI调用失败【%s】,错误码【%s】"), | |
121 | + EZVIZ_GET_URL_ERROR(400083,"荧石API调用获取URL失败!!"), | |
120 | 122 | HAVE_NO_PERMISSION(500002,"没有修改权限"), |
121 | 123 | NOT_ALLOED_ISOLATED_IN_MONOLITH(500003,"【monolith】模式下,不能选择【isolated】类型的租户配置"); |
124 | + | |
122 | 125 | private final int code; |
123 | 126 | private String message; |
124 | 127 | ... | ... |
... | ... | @@ -19,7 +19,6 @@ public class TkVideoPlatformDTO extends TenantDTO { |
19 | 19 | private Integer type; |
20 | 20 | |
21 | 21 | @ApiModelProperty(value = "平台地址+端口", required = true) |
22 | - @NotEmpty(message = "平台地址+端口不能为空") | |
23 | 22 | @Size(max = 36, message = "平台地址最大长度36") |
24 | 23 | private String host; |
25 | 24 | |
... | ... | @@ -34,7 +33,6 @@ public class TkVideoPlatformDTO extends TenantDTO { |
34 | 33 | private String appSecret; |
35 | 34 | |
36 | 35 | @ApiModelProperty(value = "流媒体部署环境", required = true) |
37 | - @NotNull(message = "流媒体部署环境不能为空") | |
38 | 36 | @Max(value = 2, message = "平台类型最大长度2") |
39 | 37 | private Integer ssl; |
40 | 38 | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/utils/HttpClientUtils.java
0 → 100644
1 | +package org.thingsboard.server.common.data.yunteng.utils; | |
2 | + | |
3 | +import java.io.BufferedReader; | |
4 | +import java.io.IOException; | |
5 | +import java.io.InputStreamReader; | |
6 | +import java.io.OutputStream; | |
7 | +import java.net.HttpURLConnection; | |
8 | +import java.net.URL; | |
9 | +import java.nio.charset.StandardCharsets; | |
10 | + | |
11 | +public class HttpClientUtils { | |
12 | + | |
13 | + public static String sendGet(String url) throws IOException{ | |
14 | + HttpURLConnection httpClient = (HttpURLConnection) new URL(url).openConnection(); | |
15 | + httpClient.setRequestMethod("GET"); | |
16 | + | |
17 | + BufferedReader reader = new BufferedReader(new InputStreamReader(httpClient.getInputStream())); | |
18 | + StringBuilder response = new StringBuilder(); | |
19 | + String line; | |
20 | + while ((line = reader.readLine())!=null){ | |
21 | + response.append(line); | |
22 | + } | |
23 | + reader.close(); | |
24 | + | |
25 | + return response.toString(); | |
26 | + } | |
27 | + | |
28 | + public static String sendPOST(String url,String payload) throws IOException{ | |
29 | + HttpURLConnection httpClient = (HttpURLConnection) new URL(url).openConnection(); | |
30 | + httpClient.setRequestMethod("POST"); | |
31 | + httpClient.setRequestProperty("Content-Type","application/json"); | |
32 | + httpClient.setDoOutput(true); | |
33 | + | |
34 | + try(OutputStream os = httpClient.getOutputStream()) { | |
35 | + byte[] input = payload.getBytes(StandardCharsets.UTF_8); | |
36 | + os.write(input,0,input.length); | |
37 | + } | |
38 | + | |
39 | + BufferedReader reader = new BufferedReader(new InputStreamReader(httpClient.getInputStream())); | |
40 | + StringBuilder response = new StringBuilder(); | |
41 | + String line; | |
42 | + while ((line = reader.readLine())!=null){ | |
43 | + response.append(line); | |
44 | + } | |
45 | + reader.close(); | |
46 | + | |
47 | + return response.toString(); | |
48 | + | |
49 | + } | |
50 | + | |
51 | + public static void main(String[] args) throws IOException { | |
52 | +// String url = "https://open.ys7.com/api/lapp/token/get?appKey=0cf3f1753e6941e3b5dfe3c00162924e&appSecret=cbe2f41bebee529fde568143109a9903"; | |
53 | +// String param = "{\"appKey\":\"0cf3f1753e6941e3b5dfe3c00162924e\",\"appSecret\":\"cbe2f41bebee529fde568143109a9903\"}"; | |
54 | +// String response = sendPOST(url,param);System.out.println(response); | |
55 | + String url2 = "https://open.ys7.com/api/lapp/v2/live/address/get?accessToken=at.cm82uxq261a7ji0xcf32z4su2f5vc066-2krkymy3is-1of7jb5-v1jamwzxw" + | |
56 | + "&deviceSerial=E53165567&protocol=4"; | |
57 | + String response = sendPOST(url2,""); | |
58 | + System.out.println(response); | |
59 | + } | |
60 | + | |
61 | +} | ... | ... |
common/data/src/main/java/org/thingsboard/server/common/data/yunteng/utils/tools/EzvizUtils.java
0 → 100644
1 | +package org.thingsboard.server.common.data.yunteng.utils.tools; | |
2 | + | |
3 | + | |
4 | +import com.fasterxml.jackson.databind.JsonNode; | |
5 | +import org.apache.commons.lang3.StringUtils; | |
6 | +import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; | |
7 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | |
8 | +import org.thingsboard.server.common.data.yunteng.utils.HttpClientUtils; | |
9 | +import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; | |
10 | + | |
11 | +import java.io.IOException; | |
12 | + | |
13 | +public class EzvizUtils { | |
14 | + //萤石开放平台API | |
15 | + private static String url = "https://open.ys7.com/api/lapp/"; | |
16 | + | |
17 | + public static String getCameraPreviewURL( String appKey, String appSecret,String sn) throws IOException { | |
18 | + String accessToken = getAccessTokenByUrl(appKey,appSecret); | |
19 | + String cameraPreviewURL = url+"v2/live/address/get?accessToken="+accessToken+ | |
20 | + "&deviceSerial="+sn+"&protocol=4&quality=1"; | |
21 | + //调用接口 | |
22 | + String result = HttpClientUtils.sendPOST(cameraPreviewURL,""); | |
23 | + //返回url地址 | |
24 | + if (StringUtils.isNotEmpty(result)) { | |
25 | + JsonNode json = JacksonUtil.toJsonNode(result); | |
26 | + if(json.get("code").asText().equals("200")){ | |
27 | + json = json.get("data"); | |
28 | + String message = null; | |
29 | + if(null == json || json.get("url") == null){ | |
30 | + if(null == json){ | |
31 | + message = ErrorMessage.EZVIZ_GET_URL_ERROR.getMessage(); | |
32 | + } | |
33 | + throw new TkDataValidationException(message); | |
34 | + } | |
35 | + return json.get("url").textValue(); | |
36 | + }else{ | |
37 | + String errorCode = json.get("code").asText(); | |
38 | + String msg = json.get("msg").asText(); | |
39 | + throw new TkDataValidationException(String.format(ErrorMessage.EZVIZ_API_ERROR.getMessage(),msg,errorCode)); | |
40 | + } | |
41 | + } else { | |
42 | + throw new TkDataValidationException(ErrorMessage.VIDEO_PLATFORM_CONFIG_ERROR.getMessage()); | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + /** 获取token */ | |
47 | + private static String getAccessTokenByUrl(String appKey, String appSecret) { | |
48 | + try { | |
49 | + String tokenUrl = url+"token/get?appKey="+appKey+"&appSecret="+appSecret; | |
50 | + String result = HttpClientUtils.sendPOST(tokenUrl,""); | |
51 | + JsonNode json = JacksonUtil.toJsonNode(result); | |
52 | + if(json.get("code").asText().equals("200")){ | |
53 | + json = json.get("data"); | |
54 | + return json.get("accessToken").textValue(); | |
55 | + }else{ | |
56 | + String errorCode = json.get("code").asText(); | |
57 | + String msg = json.get("msg").asText(); | |
58 | + throw new TkDataValidationException(String.format(ErrorMessage.EZVIZ_API_ERROR.getMessage(),msg,errorCode)); | |
59 | + } | |
60 | + } catch (Exception e) { | |
61 | + e.printStackTrace(); | |
62 | + throw new TkDataValidationException(ErrorMessage.OPERATION_FAILED.getMessage()); | |
63 | + } | |
64 | + } | |
65 | + | |
66 | +} | ... | ... |
... | ... | @@ -35,9 +35,9 @@ public class HikVisionArtemisPostUtils { |
35 | 35 | } |
36 | 36 | |
37 | 37 | public static String getCameraPreviewURL(String host, String appKey, String appSecret, int ssl, |
38 | - ProtocolType protocolType,String businessType,String body) { | |
38 | + ProtocolType protocolType,String body) { | |
39 | 39 | //获取url链接 |
40 | - Map<String, String> path = getUrl(host, appKey, appSecret, ssl, businessType); | |
40 | + Map<String, String> path = getUrl(host, appKey, appSecret, ssl, FastIotConstants.HkwsBuinessType.GET_URL); | |
41 | 41 | //设置参数提交方式 |
42 | 42 | String contentType = "application/json"; |
43 | 43 | //调用接口 |
... | ... | @@ -72,9 +72,9 @@ public class HikVisionArtemisPostUtils { |
72 | 72 | /** |
73 | 73 | *根据监控点编号进行云台操作 |
74 | 74 | * */ |
75 | - public static String controlli(String host, String appKey, String appSecret, int ssl,String businessType,String body) { | |
75 | + public static String controlli(String host, String appKey, String appSecret, int ssl ,String body) { | |
76 | 76 | //获取url链接 |
77 | - Map<String, String> path = getUrl(host, appKey, appSecret, ssl, businessType); | |
77 | + Map<String, String> path = getUrl(host, appKey, appSecret, ssl, FastIotConstants.HkwsBuinessType.CONTROLLING); | |
78 | 78 | //设置参数提交方式 |
79 | 79 | String contentType = "application/json"; |
80 | 80 | ... | ... |
... | ... | @@ -13,11 +13,9 @@ import org.thingsboard.server.common.data.StringUtils; |
13 | 13 | import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; |
14 | 14 | import org.thingsboard.server.common.data.yunteng.core.exception.TkDataValidationException; |
15 | 15 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; |
16 | -import org.thingsboard.server.common.data.yunteng.dto.BaseDTO; | |
17 | -import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO; | |
18 | -import org.thingsboard.server.common.data.yunteng.dto.OrganizationDTO; | |
19 | -import org.thingsboard.server.common.data.yunteng.dto.TkVideoDTO; | |
16 | +import org.thingsboard.server.common.data.yunteng.dto.*; | |
20 | 17 | import org.thingsboard.server.common.data.yunteng.utils.JacksonUtil; |
18 | +import org.thingsboard.server.common.data.yunteng.utils.tools.EzvizUtils; | |
21 | 19 | import org.thingsboard.server.common.data.yunteng.utils.tools.HikVisionArtemisPostUtils; |
22 | 20 | import org.thingsboard.server.common.data.yunteng.utils.tools.ProtocolType; |
23 | 21 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; |
... | ... | @@ -28,6 +26,7 @@ import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
28 | 26 | import org.thingsboard.server.dao.yunteng.service.UserOrganizationMappingService; |
29 | 27 | import org.thingsboard.server.dao.yunteng.service.TkVideoService; |
30 | 28 | |
29 | +import java.io.IOException; | |
31 | 30 | import java.util.ArrayList; |
32 | 31 | import java.util.List; |
33 | 32 | import java.util.Set; |
... | ... | @@ -94,8 +93,8 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid |
94 | 93 | } |
95 | 94 | |
96 | 95 | @Override |
97 | - public String getCameraPreviewURL(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, | |
98 | - ProtocolType protocolType,String businessType) { | |
96 | + public String getCameraPreviewURL(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, | |
97 | + ProtocolType protocolType) throws IOException { | |
99 | 98 | if (isTenantAdmin) { |
100 | 99 | customerUserId = null; |
101 | 100 | } |
... | ... | @@ -106,30 +105,18 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid |
106 | 105 | throw new TkDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); |
107 | 106 | } |
108 | 107 | TkVideoDTO videoDTO = videoDTOList.get(0); |
109 | - if(protocolType!=null && protocolType.equals(ProtocolType.HLS)){ | |
110 | - protocolType = videoDTO.getPlayProtocol() == 0 ? ProtocolType.HLS : ProtocolType.HLSS; | |
108 | + TkVideoPlatformDTO videoPlatformDTO = videoDTO.getVideoPlatformDTO(); | |
109 | + if(videoPlatformDTO.getType()==0){//如果为海康威视 | |
110 | + return HikVisionArtemis(videoDTO,protocolType); | |
111 | 111 | } |
112 | - | |
113 | - //设置参数提交方式 | |
114 | - String contentType = "application/json"; | |
115 | - //组装请求参数 | |
116 | - ObjectNode jsonBody = JacksonUtil.newObjectNode(); | |
117 | - jsonBody.put("cameraIndexCode", videoDTO.getSn()); | |
118 | - //0:主码流 1:子码流 2:第三码流 https://open.hikvision.com/docs/8530061f19534a9993e2afeb70e7c96a | |
119 | - jsonBody.put("streamType", videoDTO.getStreamType()); | |
120 | - jsonBody.put("protocol", protocolType.getValue()); | |
121 | - jsonBody.put("transmode", 1); | |
122 | - jsonBody.put("expand", "transcode=1"); | |
123 | - String body = jsonBody.toString(); | |
124 | - | |
125 | - | |
126 | - return HikVisionArtemisPostUtils.getCameraPreviewURL(videoDTO.getVideoPlatformDTO().getHost(), | |
127 | - videoDTO.getVideoPlatformDTO().getAppKey(), videoDTO.getVideoPlatformDTO().getAppSecret(), | |
128 | - videoDTO.getVideoPlatformDTO().getSsl(),protocolType,businessType,body); | |
112 | + if (videoPlatformDTO.getType()==1){ | |
113 | + return EzvizUtils.getCameraPreviewURL(videoPlatformDTO.getAppKey(),videoPlatformDTO.getAppSecret(),videoDTO.getSn()); | |
114 | + } | |
115 | + return null; | |
129 | 116 | } |
130 | 117 | |
131 | 118 | @Override |
132 | - public String controlli(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, int action, String command,String businessType) { | |
119 | + public String controlli(boolean isTenantAdmin, String customerUserId, String tenantId, String entityId, int action, String command ) { | |
133 | 120 | if (isTenantAdmin) { |
134 | 121 | customerUserId = null; |
135 | 122 | } |
... | ... | @@ -153,7 +140,7 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid |
153 | 140 | |
154 | 141 | return HikVisionArtemisPostUtils.controlli(videoDTO.getVideoPlatformDTO().getHost(), |
155 | 142 | videoDTO.getVideoPlatformDTO().getAppKey(), videoDTO.getVideoPlatformDTO().getAppSecret(), |
156 | - videoDTO.getVideoPlatformDTO().getSsl(),businessType,body); | |
143 | + videoDTO.getVideoPlatformDTO().getSsl(),body); | |
157 | 144 | } |
158 | 145 | |
159 | 146 | @Override |
... | ... | @@ -188,4 +175,24 @@ public class TkVideoServiceImpl extends AbstractBaseService<TkVideoMapper, TkVid |
188 | 175 | return null; |
189 | 176 | } |
190 | 177 | |
178 | + private String HikVisionArtemis(TkVideoDTO videoDTO, ProtocolType protocolType){ | |
179 | + if(protocolType!=null && protocolType.equals(ProtocolType.HLS)){ | |
180 | + protocolType = videoDTO.getPlayProtocol() == 0 ? ProtocolType.HLS : ProtocolType.HLSS; | |
181 | + } | |
182 | + //设置参数提交方式 | |
183 | + String contentType = "application/json"; | |
184 | + //组装请求参数 | |
185 | + ObjectNode jsonBody = JacksonUtil.newObjectNode(); | |
186 | + jsonBody.put("cameraIndexCode", videoDTO.getSn()); | |
187 | + //0:主码流 1:子码流 2:第三码流 https://open.hikvision.com/docs/8530061f19534a9993e2afeb70e7c96a | |
188 | + jsonBody.put("streamType", videoDTO.getStreamType()); | |
189 | + jsonBody.put("protocol", protocolType.getValue()); | |
190 | + jsonBody.put("transmode", 1); | |
191 | + jsonBody.put("expand", "transcode=1"); | |
192 | + String body = jsonBody.toString(); | |
193 | + return HikVisionArtemisPostUtils.getCameraPreviewURL(videoDTO.getVideoPlatformDTO().getHost(), | |
194 | + videoDTO.getVideoPlatformDTO().getAppKey(), videoDTO.getVideoPlatformDTO().getAppSecret(), | |
195 | + videoDTO.getVideoPlatformDTO().getSsl(),protocolType,body); | |
196 | + } | |
197 | + | |
191 | 198 | } | ... | ... |
... | ... | @@ -7,6 +7,7 @@ import org.thingsboard.server.common.data.yunteng.utils.tools.ProtocolType; |
7 | 7 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; |
8 | 8 | import org.thingsboard.server.dao.yunteng.entities.TkVideoEntity; |
9 | 9 | |
10 | +import java.io.IOException; | |
10 | 11 | import java.util.List; |
11 | 12 | import java.util.Set; |
12 | 13 | |
... | ... | @@ -64,8 +65,7 @@ public interface TkVideoService extends BaseService<TkVideoEntity> { |
64 | 65 | String customerUserId, |
65 | 66 | String tenantId, |
66 | 67 | String entityId, |
67 | - ProtocolType protocolType, | |
68 | - String businessType); | |
68 | + ProtocolType protocolType) throws IOException; | |
69 | 69 | |
70 | 70 | |
71 | 71 | /** |
... | ... | @@ -85,8 +85,7 @@ public interface TkVideoService extends BaseService<TkVideoEntity> { |
85 | 85 | String tenantId, |
86 | 86 | String entityId, |
87 | 87 | int action, |
88 | - String command, | |
89 | - String businessType | |
88 | + String command | |
90 | 89 | ); |
91 | 90 | |
92 | 91 | /** | ... | ... |
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | <result property="ssl" column="ssl"/> |
32 | 32 | <result property="protocolType" column="protocol_type" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/> |
33 | 33 | <result property="remark" column="remark"/> |
34 | + <result property="type" column="type"/> | |
34 | 35 | </association> |
35 | 36 | </resultMap> |
36 | 37 | |
... | ... | @@ -44,7 +45,8 @@ |
44 | 45 | |
45 | 46 | <sql id="detailColumns"> |
46 | 47 | <include refid="basicColumns"/> |
47 | - ,org.name AS organization_name,ivp.host,ivp.app_key,ivp.app_secret,ivp.ssl,ivp.remark,ivp.protocol_type | |
48 | + ,org.name AS organization_name,ivp.host,ivp.app_key,ivp.app_secret,ivp.ssl,ivp.remark,ivp.protocol_type, | |
49 | + ivp.type | |
48 | 50 | </sql> |
49 | 51 | <select id="getVideoPage" resultMap="videoMap"> |
50 | 52 | SELECT | ... | ... |