Commit afbec289067cc7f284dd135366b0f6febf13126b
1 parent
44b06e1b
增加推流鉴权。保护服务安全
Showing
32 changed files
with
784 additions
and
189 deletions
sql/update.sql
| ... | ... | @@ -52,10 +52,14 @@ alter table stream_proxy |
| 52 | 52 | alter table stream_push |
| 53 | 53 | add pushTime varchar(50) default null; |
| 54 | 54 | alter table stream_push |
| 55 | + add status int DEFAULT NULL; | |
| 56 | +alter table stream_push | |
| 55 | 57 | add updateTime varchar(50) default null; |
| 56 | 58 | alter table stream_push |
| 57 | 59 | change createStamp createTime varchar(50) default null; |
| 58 | 60 | |
| 61 | +alter table gb_stream | |
| 62 | + drop column status; | |
| 59 | 63 | |
| 60 | 64 | alter table user |
| 61 | 65 | add pushKey varchar(50) default null; | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
| ... | ... | @@ -9,6 +9,9 @@ public class StreamInfo { |
| 9 | 9 | private String deviceID; |
| 10 | 10 | private String channelId; |
| 11 | 11 | private String flv; |
| 12 | + | |
| 13 | + private String ip; | |
| 14 | + | |
| 12 | 15 | private String https_flv; |
| 13 | 16 | private String ws_flv; |
| 14 | 17 | private String wss_flv; |
| ... | ... | @@ -292,4 +295,12 @@ public class StreamInfo { |
| 292 | 295 | public void setProgress(double progress) { |
| 293 | 296 | this.progress = progress; |
| 294 | 297 | } |
| 298 | + | |
| 299 | + public String getIp() { | |
| 300 | + return ip; | |
| 301 | + } | |
| 302 | + | |
| 303 | + public void setIp(String ip) { | |
| 304 | + this.ip = ip; | |
| 305 | + } | |
| 295 | 306 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| ... | ... | @@ -58,6 +58,8 @@ public class VideoManagerConstants { |
| 58 | 58 | |
| 59 | 59 | public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_"; |
| 60 | 60 | |
| 61 | + public static final String MEDIA_STREAM_AUTHORITY = "MEDIA_STREAM_AUTHORITY_"; | |
| 62 | + | |
| 61 | 63 | public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_"; |
| 62 | 64 | |
| 63 | 65 | public static final String SIP_SN_PREFIX = "VMP_SIP_SN_"; |
| ... | ... | @@ -71,6 +73,8 @@ public class VideoManagerConstants { |
| 71 | 73 | public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_"; |
| 72 | 74 | |
| 73 | 75 | |
| 76 | + | |
| 77 | + | |
| 74 | 78 | //************************** redis 消息********************************* |
| 75 | 79 | |
| 76 | 80 | // 流变化的通知 |
| ... | ... | @@ -79,9 +83,15 @@ public class VideoManagerConstants { |
| 79 | 83 | // 接收推流设备的GPS变化通知 |
| 80 | 84 | public static final String VM_MSG_GPS = "VM_MSG_GPS"; |
| 81 | 85 | |
| 86 | + // 接收推流设备的GPS变化通知 | |
| 87 | + public static final String VM_MSG_PUSH_STREAM_STATUS_CHANGE = "VM_MSG_PUSH_STREAM_STATUS_CHANGE"; | |
| 88 | + | |
| 82 | 89 | // redis 消息通知设备推流到平台 |
| 83 | 90 | public static final String VM_MSG_STREAM_PUSH_REQUESTED = "VM_MSG_STREAM_PUSH_REQUESTED"; |
| 84 | 91 | |
| 92 | + // redis 消息请求所有的在线通道 | |
| 93 | + public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED"; | |
| 94 | + | |
| 85 | 95 | // 移动位置订阅通知 |
| 86 | 96 | public static final String VM_MSG_SUBSCRIBE_MOBILE_POSITION = "mobileposition"; |
| 87 | 97 | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| 1 | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | |
| 3 | -import java.util.ArrayList; | |
| 3 | +import java.util.HashMap; | |
| 4 | 4 | import java.util.List; |
| 5 | +import java.util.Map; | |
| 5 | 6 | |
| 6 | 7 | import com.alibaba.fastjson.JSON; |
| 7 | 8 | import com.genersoft.iot.vmp.common.StreamInfo; |
| ... | ... | @@ -21,6 +22,7 @@ import org.slf4j.LoggerFactory; |
| 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; |
| 22 | 23 | import org.springframework.http.HttpStatus; |
| 23 | 24 | import org.springframework.http.ResponseEntity; |
| 25 | +import org.springframework.util.StringUtils; | |
| 24 | 26 | import org.springframework.web.bind.annotation.PostMapping; |
| 25 | 27 | import org.springframework.web.bind.annotation.RequestBody; |
| 26 | 28 | import org.springframework.web.bind.annotation.RequestMapping; |
| ... | ... | @@ -80,6 +82,9 @@ public class ZLMHttpHookListener { |
| 80 | 82 | private UserSetting userSetting; |
| 81 | 83 | |
| 82 | 84 | @Autowired |
| 85 | + private IUserService userService; | |
| 86 | + | |
| 87 | + @Autowired | |
| 83 | 88 | private VideoStreamSessionManager sessionManager; |
| 84 | 89 | |
| 85 | 90 | /** |
| ... | ... | @@ -151,12 +156,14 @@ public class ZLMHttpHookListener { |
| 151 | 156 | */ |
| 152 | 157 | @ResponseBody |
| 153 | 158 | @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") |
| 154 | - public ResponseEntity<String> onPlay(@RequestBody JSONObject json){ | |
| 155 | - | |
| 159 | + public ResponseEntity<String> onPlay(@RequestBody OnPlayHookParam param){ | |
| 160 | + | |
| 161 | + JSONObject json = (JSONObject)JSON.toJSON(param); | |
| 162 | + | |
| 156 | 163 | if (logger.isDebugEnabled()) { |
| 157 | - logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + json.toString()); | |
| 164 | + logger.debug("[ ZLM HOOK ]on_play API调用,参数:" + JSON.toJSONString(param)); | |
| 158 | 165 | } |
| 159 | - String mediaServerId = json.getString("mediaServerId"); | |
| 166 | + String mediaServerId = param.getMediaServerId(); | |
| 160 | 167 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); |
| 161 | 168 | if (subscribe != null ) { |
| 162 | 169 | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| ... | ... | @@ -165,9 +172,20 @@ public class ZLMHttpHookListener { |
| 165 | 172 | } |
| 166 | 173 | } |
| 167 | 174 | JSONObject ret = new JSONObject(); |
| 175 | + if (!"rtp".equals(param.getApp())) { | |
| 176 | + Map<String, String> paramMap = urlParamToMap(param.getParams()); | |
| 177 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); | |
| 178 | + if (streamAuthorityInfo == null | |
| 179 | + || (streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId")))) { | |
| 180 | + ret.put("code", 401); | |
| 181 | + ret.put("msg", "Unauthorized"); | |
| 182 | + return new ResponseEntity<>(ret.toString(),HttpStatus.OK); | |
| 183 | + } | |
| 184 | + } | |
| 185 | + | |
| 168 | 186 | ret.put("code", 0); |
| 169 | 187 | ret.put("msg", "success"); |
| 170 | - return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); | |
| 188 | + return new ResponseEntity<>(ret.toString(),HttpStatus.OK); | |
| 171 | 189 | } |
| 172 | 190 | |
| 173 | 191 | /** |
| ... | ... | @@ -176,16 +194,49 @@ public class ZLMHttpHookListener { |
| 176 | 194 | */ |
| 177 | 195 | @ResponseBody |
| 178 | 196 | @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") |
| 179 | - public ResponseEntity<String> onPublish(@RequestBody JSONObject json) { | |
| 197 | + public ResponseEntity<String> onPublish(@RequestBody OnPublishHookParam param) { | |
| 198 | + | |
| 199 | + JSONObject json = (JSONObject) JSON.toJSON(param); | |
| 180 | 200 | |
| 181 | 201 | logger.info("[ ZLM HOOK ]on_publish API调用,参数:" + json.toString()); |
| 182 | 202 | JSONObject ret = new JSONObject(); |
| 203 | + if (!"rtp".equals(param.getApp())) { | |
| 204 | + // 推流鉴权 | |
| 205 | + if (param.getParams() == null) { | |
| 206 | + logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)"); | |
| 207 | + ret.put("code", 401); | |
| 208 | + ret.put("msg", "Unauthorized"); | |
| 209 | + return new ResponseEntity<>(ret.toString(), HttpStatus.OK); | |
| 210 | + } | |
| 211 | + Map<String, String> paramMap = urlParamToMap(param.getParams()); | |
| 212 | + String sign = paramMap.get("sign"); | |
| 213 | + if (sign == null) { | |
| 214 | + logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)"); | |
| 215 | + ret.put("code", 401); | |
| 216 | + ret.put("msg", "Unauthorized"); | |
| 217 | + return new ResponseEntity<>(ret.toString(), HttpStatus.OK); | |
| 218 | + } | |
| 219 | + // 推流自定义播放鉴权码 | |
| 220 | + String callId = paramMap.get("callId"); | |
| 221 | + // 鉴权配置 | |
| 222 | + boolean hasAuthority = userService.checkPushAuthority(callId, sign); | |
| 223 | + if (!hasAuthority) { | |
| 224 | + logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign); | |
| 225 | + ret.put("code", 401); | |
| 226 | + ret.put("msg", "Unauthorized"); | |
| 227 | + return new ResponseEntity<>(ret.toString(), HttpStatus.OK); | |
| 228 | + } | |
| 229 | + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); | |
| 230 | + streamAuthorityInfo.setCallId(callId); | |
| 231 | + streamAuthorityInfo.setSign(sign); | |
| 232 | + // 鉴权通过 | |
| 233 | + redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); | |
| 234 | + } | |
| 235 | + | |
| 183 | 236 | ret.put("code", 0); |
| 184 | 237 | ret.put("msg", "success"); |
| 185 | 238 | ret.put("enable_hls", true); |
| 186 | - if (json.getInteger("originType") == 1 | |
| 187 | - || json.getInteger("originType") == 2 | |
| 188 | - || json.getInteger("originType") == 3) { | |
| 239 | + if (!"rtp".equals(param.getApp())) { | |
| 189 | 240 | ret.put("enable_audio", true); |
| 190 | 241 | } |
| 191 | 242 | |
| ... | ... | @@ -200,14 +251,13 @@ public class ZLMHttpHookListener { |
| 200 | 251 | ret.put("msg", "zlm not register"); |
| 201 | 252 | } |
| 202 | 253 | } |
| 203 | - String app = json.getString("app"); | |
| 204 | - String stream = json.getString("stream"); | |
| 205 | - if ("rtp".equals(app)) { | |
| 254 | + | |
| 255 | + if ("rtp".equals(param.getApp())) { | |
| 206 | 256 | ret.put("enable_mp4", userSetting.getRecordSip()); |
| 207 | 257 | }else { |
| 208 | 258 | ret.put("enable_mp4", userSetting.isRecordPushLive()); |
| 209 | 259 | } |
| 210 | - List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, stream); | |
| 260 | + List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); | |
| 211 | 261 | if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { |
| 212 | 262 | String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); |
| 213 | 263 | String channelId = ssrcTransactionForAll.get(0).getChannelId(); |
| ... | ... | @@ -221,13 +271,14 @@ public class ZLMHttpHookListener { |
| 221 | 271 | ret.put("enable_mp4", true); |
| 222 | 272 | ret.put("enable_audio", true); |
| 223 | 273 | } |
| 224 | - | |
| 225 | 274 | } |
| 226 | 275 | |
| 227 | 276 | |
| 228 | 277 | return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); |
| 229 | 278 | } |
| 230 | - | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 231 | 282 | /** |
| 232 | 283 | * 录制mp4完成后通知事件;此事件对回复不敏感。 |
| 233 | 284 | * |
| ... | ... | @@ -312,9 +363,6 @@ public class ZLMHttpHookListener { |
| 312 | 363 | if (logger.isDebugEnabled()) { |
| 313 | 364 | logger.debug("[ ZLM HOOK ]on_shell_login API调用,参数:" + json.toString()); |
| 314 | 365 | } |
| 315 | - // TODO 如果是带有rtpstream则开启按需拉流 | |
| 316 | - // String app = json.getString("app"); | |
| 317 | - // String stream = json.getString("stream"); | |
| 318 | 366 | String mediaServerId = json.getString("mediaServerId"); |
| 319 | 367 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); |
| 320 | 368 | if (subscribe != null ) { |
| ... | ... | @@ -351,12 +399,24 @@ public class ZLMHttpHookListener { |
| 351 | 399 | } |
| 352 | 400 | // 流消失移除redis play |
| 353 | 401 | String app = item.getApp(); |
| 354 | - String streamId = item.getStream(); | |
| 402 | + String stream = item.getStream(); | |
| 355 | 403 | String schema = item.getSchema(); |
| 356 | 404 | List<MediaItem.MediaTrack> tracks = item.getTracks(); |
| 357 | 405 | boolean regist = item.isRegist(); |
| 406 | + if (regist) { | |
| 407 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 408 | + if (streamAuthorityInfo == null) { | |
| 409 | + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item); | |
| 410 | + }else { | |
| 411 | + streamAuthorityInfo.setOriginType(item.getOriginType()); | |
| 412 | + streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr()); | |
| 413 | + } | |
| 414 | + redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); | |
| 415 | + }else { | |
| 416 | + redisCatchStorage.removeStreamAuthorityInfo(app, stream); | |
| 417 | + } | |
| 358 | 418 | if ("rtmp".equals(schema)){ |
| 359 | - logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, streamId); | |
| 419 | + logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream); | |
| 360 | 420 | if (regist) { |
| 361 | 421 | mediaServerService.addCount(mediaServerId); |
| 362 | 422 | }else { |
| ... | ... | @@ -365,15 +425,15 @@ public class ZLMHttpHookListener { |
| 365 | 425 | if (item.getOriginType() == OriginType.PULL.ordinal() |
| 366 | 426 | || item.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) { |
| 367 | 427 | // 设置拉流代理上线/离线 |
| 368 | - streamProxyService.updateStatus(regist, app, streamId); | |
| 428 | + streamProxyService.updateStatus(regist, app, stream); | |
| 369 | 429 | } |
| 370 | 430 | if ("rtp".equals(app) && !regist ) { |
| 371 | - StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); | |
| 431 | + StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(stream); | |
| 372 | 432 | if (streamInfo!=null){ |
| 373 | 433 | redisCatchStorage.stopPlay(streamInfo); |
| 374 | 434 | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| 375 | 435 | }else{ |
| 376 | - streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); | |
| 436 | + streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null); | |
| 377 | 437 | if (streamInfo != null) { |
| 378 | 438 | redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(), |
| 379 | 439 | streamInfo.getStream(), null); |
| ... | ... | @@ -387,10 +447,12 @@ public class ZLMHttpHookListener { |
| 387 | 447 | |
| 388 | 448 | if (mediaServerItem != null){ |
| 389 | 449 | if (regist) { |
| 390 | - StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks); | |
| 450 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 451 | + StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, | |
| 452 | + app, stream, tracks, streamAuthorityInfo.getCallId()); | |
| 391 | 453 | item.setStreamInfo(streamInfoByAppAndStream); |
| 392 | 454 | |
| 393 | - redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item); | |
| 455 | + redisCatchStorage.addStream(mediaServerItem, type, app, stream, item); | |
| 394 | 456 | if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() |
| 395 | 457 | || item.getOriginType() == OriginType.RTMP_PUSH.ordinal() |
| 396 | 458 | || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { |
| ... | ... | @@ -413,23 +475,23 @@ public class ZLMHttpHookListener { |
| 413 | 475 | |
| 414 | 476 | }else { |
| 415 | 477 | // 兼容流注销时类型从redis记录获取 |
| 416 | - MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, streamId, mediaServerId); | |
| 478 | + MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, stream, mediaServerId); | |
| 417 | 479 | if (mediaItem != null) { |
| 418 | 480 | type = OriginType.values()[mediaItem.getOriginType()].getType(); |
| 419 | - redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, streamId); | |
| 481 | + redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, stream); | |
| 420 | 482 | } |
| 421 | - GbStream gbStream = storager.getGbStream(app, streamId); | |
| 483 | + GbStream gbStream = storager.getGbStream(app, stream); | |
| 422 | 484 | if (gbStream != null) { |
| 423 | 485 | // eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); |
| 424 | 486 | } |
| 425 | - zlmMediaListManager.removeMedia(app, streamId); | |
| 487 | + zlmMediaListManager.removeMedia(app, stream); | |
| 426 | 488 | } |
| 427 | 489 | if (type != null) { |
| 428 | 490 | // 发送流变化redis消息 |
| 429 | 491 | JSONObject jsonObject = new JSONObject(); |
| 430 | 492 | jsonObject.put("serverId", userSetting.getServerId()); |
| 431 | 493 | jsonObject.put("app", app); |
| 432 | - jsonObject.put("stream", streamId); | |
| 494 | + jsonObject.put("stream", stream); | |
| 433 | 495 | jsonObject.put("register", regist); |
| 434 | 496 | jsonObject.put("mediaServerId", mediaServerId); |
| 435 | 497 | redisCatchStorage.sendStreamChangeMsg(type, jsonObject); |
| ... | ... | @@ -565,4 +627,22 @@ public class ZLMHttpHookListener { |
| 565 | 627 | ret.put("msg", "success"); |
| 566 | 628 | return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); |
| 567 | 629 | } |
| 630 | + | |
| 631 | + private Map<String, String> urlParamToMap(String params) { | |
| 632 | + HashMap<String, String> map = new HashMap<>(); | |
| 633 | + if (StringUtils.isEmpty(params)) { | |
| 634 | + return map; | |
| 635 | + } | |
| 636 | + String[] paramsArray = params.split("&"); | |
| 637 | + if (paramsArray.length == 0) { | |
| 638 | + return map; | |
| 639 | + } | |
| 640 | + for (String param : paramsArray) { | |
| 641 | + String[] paramArray = param.split("="); | |
| 642 | + if (paramArray.length == 2){ | |
| 643 | + map.put(paramArray[0], paramArray[1]); | |
| 644 | + } | |
| 645 | + } | |
| 646 | + return map; | |
| 647 | + } | |
| 568 | 648 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
| ... | ... | @@ -115,64 +115,42 @@ public class ZLMMediaListManager { |
| 115 | 115 | public StreamPushItem addPush(MediaItem mediaItem) { |
| 116 | 116 | // 查找此直播流是否存在redis预设gbId |
| 117 | 117 | StreamPushItem transform = streamPushService.transform(mediaItem); |
| 118 | - // 从streamId取出查询关键值 | |
| 119 | - Pattern pattern = Pattern.compile(userSetting.getThirdPartyGBIdReg()); | |
| 120 | - Matcher matcher = pattern.matcher(mediaItem.getStream());// 指定要匹配的字符串 | |
| 121 | - String queryKey = null; | |
| 122 | - if (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配 | |
| 123 | - queryKey = matcher.group(); | |
| 124 | - } | |
| 125 | - if (queryKey != null) { | |
| 126 | - ThirdPartyGB thirdPartyGB = redisCatchStorage.queryMemberNoGBId(queryKey); | |
| 127 | - if (thirdPartyGB != null && !StringUtils.isEmpty(thirdPartyGB.getNationalStandardNo())) { | |
| 128 | - transform.setGbId(thirdPartyGB.getNationalStandardNo()); | |
| 129 | - transform.setName(thirdPartyGB.getName()); | |
| 130 | - } | |
| 131 | - } | |
| 132 | - if (!StringUtils.isEmpty(transform.getGbId())) { | |
| 133 | - // 如果这个国标ID已经给了其他推流且流已离线,则移除其他推流 | |
| 134 | - List<GbStream> gbStreams = gbStreamMapper.selectByGBId(transform.getGbId()); | |
| 135 | - if (gbStreams.size() > 0) { | |
| 136 | - for (GbStream gbStream : gbStreams) { | |
| 137 | - // 出现使用相同国标Id的视频流时,使用新流替换旧流, | |
| 138 | - if (queryKey != null && gbStream.getApp().equals(mediaItem.getApp())) { | |
| 139 | - Matcher matcherForStream = pattern.matcher(gbStream.getStream()); | |
| 140 | - String queryKeyForStream = null; | |
| 141 | - if (matcherForStream.find()) { //此处find()每次被调用后,会偏移到下一个匹配 | |
| 142 | - queryKeyForStream = matcherForStream.group(); | |
| 143 | - } | |
| 144 | - if (queryKeyForStream == null || !queryKeyForStream.equals(queryKey)) { | |
| 145 | - // 此时不是同一个流 | |
| 146 | - gbStreamMapper.del(gbStream.getApp(), gbStream.getStream()); | |
| 147 | - if (!gbStream.isStatus()) { | |
| 148 | - streamPushMapper.del(gbStream.getApp(), gbStream.getStream()); | |
| 149 | - } | |
| 150 | - } | |
| 151 | - } | |
| 152 | - } | |
| 153 | - } | |
| 154 | - List<GbStream> gbStreamList = gbStreamMapper.selectByGBId(transform.getGbId()); | |
| 155 | - if (gbStreamList != null && gbStreamList.size() == 1) { | |
| 156 | - transform.setGbStreamId(gbStreamList.get(0).getGbStreamId()); | |
| 157 | - transform.setPlatformId(gbStreamList.get(0).getPlatformId()); | |
| 158 | - transform.setCatalogId(gbStreamList.get(0).getCatalogId()); | |
| 159 | - transform.setGbId(gbStreamList.get(0).getGbId()); | |
| 160 | - gbStreamMapper.update(transform); | |
| 161 | - streamPushMapper.del(gbStreamList.get(0).getApp(), gbStreamList.get(0).getStream()); | |
| 162 | - }else { | |
| 163 | - transform.setCreateTime(DateUtil.getNow()); | |
| 164 | - transform.setUpdateTime(DateUtil.getNow()); | |
| 165 | - gbStreamMapper.add(transform); | |
| 166 | - } | |
| 167 | - if (transform != null) { | |
| 168 | - if (channelOnlineEvents.get(transform.getGbId()) != null) { | |
| 169 | - channelOnlineEvents.get(transform.getGbId()).run(transform.getApp(), transform.getStream(), transform.getServerId()); | |
| 170 | - channelOnlineEvents.remove(transform.getGbId()); | |
| 171 | - } | |
| 172 | - } | |
| 118 | + StreamPushItem pushInDb = streamPushService.getPush(mediaItem.getApp(), mediaItem.getStream()); | |
| 119 | + transform.setUpdateTime(DateUtil.getNow()); | |
| 120 | + transform.setPushTime(DateUtil.getNow()); | |
| 121 | + if (pushInDb == null) { | |
| 122 | + transform.setCreateTime(DateUtil.getNow()); | |
| 123 | + streamPushMapper.add(transform); | |
| 124 | + }else { | |
| 125 | + streamPushMapper.update(transform); | |
| 126 | + | |
| 127 | + | |
| 128 | +// if (!StringUtils.isEmpty(pushInDb.getGbId())) { | |
| 129 | +// List<GbStream> gbStreamList = gbStreamMapper.selectByGBId(transform.getGbId()); | |
| 130 | +// if (gbStreamList != null && gbStreamList.size() == 1) { | |
| 131 | +// transform.setGbStreamId(gbStreamList.get(0).getGbStreamId()); | |
| 132 | +// transform.setPlatformId(gbStreamList.get(0).getPlatformId()); | |
| 133 | +// transform.setCatalogId(gbStreamList.get(0).getCatalogId()); | |
| 134 | +// transform.setGbId(gbStreamList.get(0).getGbId()); | |
| 135 | +// gbStreamMapper.update(transform); | |
| 136 | +// streamPushMapper.del(gbStreamList.get(0).getApp(), gbStreamList.get(0).getStream()); | |
| 137 | +// }else { | |
| 138 | +// transform.setCreateTime(DateUtil.getNow()); | |
| 139 | +// transform.setUpdateTime(DateUtil.getNow()); | |
| 140 | +// gbStreamMapper.add(transform); | |
| 141 | +// } | |
| 142 | + // 通知通道上线 | |
| 143 | +// if (transform != null) { | |
| 144 | +// if (channelOnlineEvents.get(transform.getGbId()) != null) { | |
| 145 | +// channelOnlineEvents.get(transform.getGbId()).run(transform.getApp(), transform.getStream(), transform.getServerId()); | |
| 146 | +// channelOnlineEvents.remove(transform.getGbId()); | |
| 147 | +// } | |
| 148 | +// } | |
| 149 | +// } | |
| 173 | 150 | } |
| 174 | 151 | |
| 175 | - storager.updateMedia(transform); | |
| 152 | + | |
| 153 | + | |
| 176 | 154 | return transform; |
| 177 | 155 | } |
| 178 | 156 | |
| ... | ... | @@ -206,13 +184,13 @@ public class ZLMMediaListManager { |
| 206 | 184 | |
| 207 | 185 | public int removeMedia(String app, String streamId) { |
| 208 | 186 | // 查找是否关联了国标, 关联了不删除, 置为离线 |
| 209 | - StreamProxyItem streamProxyItem = gbStreamMapper.selectOne(app, streamId); | |
| 210 | - int result = 0; | |
| 211 | - if (streamProxyItem == null) { | |
| 187 | + GbStream gbStream = gbStreamMapper.selectOne(app, streamId); | |
| 188 | + int result; | |
| 189 | + if (gbStream == null) { | |
| 212 | 190 | result = storager.removeMedia(app, streamId); |
| 213 | 191 | }else { |
| 214 | 192 | // TODO 暂不设置为离线 |
| 215 | - result =storager.mediaOutline(app, streamId); | |
| 193 | + result =storager.mediaOffline(app, streamId); | |
| 216 | 194 | } |
| 217 | 195 | return result; |
| 218 | 196 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| ... | ... | @@ -66,7 +66,7 @@ public class ZLMRTPServerFactory { |
| 66 | 66 | String stream = UUID.randomUUID().toString(); |
| 67 | 67 | param.put("enable_tcp", 1); |
| 68 | 68 | param.put("stream_id", stream); |
| 69 | - param.put("port", 0); | |
| 69 | +// param.put("port", 0); | |
| 70 | 70 | JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); |
| 71 | 71 | |
| 72 | 72 | if (openRtpServerResultJson != null) { |
| ... | ... | @@ -101,9 +101,10 @@ public class ZLMRTPServerFactory { |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | Map<String, Object> param = new HashMap<>(); |
| 104 | - // 推流端口设置0则使用随机端口 | |
| 104 | + | |
| 105 | 105 | param.put("enable_tcp", 1); |
| 106 | 106 | param.put("stream_id", streamId); |
| 107 | + // 推流端口设置0则使用随机端口 | |
| 107 | 108 | param.put("port", 0); |
| 108 | 109 | param.put("ssrc", ssrc); |
| 109 | 110 | JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookParam.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.media.zlm.dto; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * zlm hook事件的参数 | |
| 5 | + * @author lin | |
| 6 | + */ | |
| 7 | +public class HookParam { | |
| 8 | + private String mediaServerId; | |
| 9 | + | |
| 10 | + public String getMediaServerId() { | |
| 11 | + return mediaServerId; | |
| 12 | + } | |
| 13 | + | |
| 14 | + public void setMediaServerId(String mediaServerId) { | |
| 15 | + this.mediaServerId = mediaServerId; | |
| 16 | + } | |
| 17 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.media.zlm.dto; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * zlm hook事件中的on_play事件的参数 | |
| 5 | + * @author lin | |
| 6 | + */ | |
| 7 | +public class OnPlayHookParam extends HookParam{ | |
| 8 | + private String id; | |
| 9 | + private String app; | |
| 10 | + private String stream; | |
| 11 | + private String ip; | |
| 12 | + private String params; | |
| 13 | + private int port; | |
| 14 | + private String schema; | |
| 15 | + private String vhost; | |
| 16 | + | |
| 17 | + | |
| 18 | + public String getId() { | |
| 19 | + return id; | |
| 20 | + } | |
| 21 | + | |
| 22 | + public void setId(String id) { | |
| 23 | + this.id = id; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public String getApp() { | |
| 27 | + return app; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setApp(String app) { | |
| 31 | + this.app = app; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public String getStream() { | |
| 35 | + return stream; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setStream(String stream) { | |
| 39 | + this.stream = stream; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public String getIp() { | |
| 43 | + return ip; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public void setIp(String ip) { | |
| 47 | + this.ip = ip; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public String getParams() { | |
| 51 | + return params; | |
| 52 | + } | |
| 53 | + | |
| 54 | + public void setParams(String params) { | |
| 55 | + this.params = params; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public int getPort() { | |
| 59 | + return port; | |
| 60 | + } | |
| 61 | + | |
| 62 | + public void setPort(int port) { | |
| 63 | + this.port = port; | |
| 64 | + } | |
| 65 | + | |
| 66 | + public String getSchema() { | |
| 67 | + return schema; | |
| 68 | + } | |
| 69 | + | |
| 70 | + public void setSchema(String schema) { | |
| 71 | + this.schema = schema; | |
| 72 | + } | |
| 73 | + | |
| 74 | + public String getVhost() { | |
| 75 | + return vhost; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public void setVhost(String vhost) { | |
| 79 | + this.vhost = vhost; | |
| 80 | + } | |
| 81 | + | |
| 82 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPublishHookParam.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.media.zlm.dto; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * zlm hook事件中的on_publish事件的参数 | |
| 5 | + * @author lin | |
| 6 | + */ | |
| 7 | +public class OnPublishHookParam extends HookParam{ | |
| 8 | + private String id; | |
| 9 | + private String app; | |
| 10 | + private String stream; | |
| 11 | + private String ip; | |
| 12 | + private String params; | |
| 13 | + private int port; | |
| 14 | + private String schema; | |
| 15 | + private String vhost; | |
| 16 | + | |
| 17 | + | |
| 18 | + public String getId() { | |
| 19 | + return id; | |
| 20 | + } | |
| 21 | + | |
| 22 | + public void setId(String id) { | |
| 23 | + this.id = id; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public String getApp() { | |
| 27 | + return app; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setApp(String app) { | |
| 31 | + this.app = app; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public String getStream() { | |
| 35 | + return stream; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setStream(String stream) { | |
| 39 | + this.stream = stream; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public String getIp() { | |
| 43 | + return ip; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public void setIp(String ip) { | |
| 47 | + this.ip = ip; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public String getParams() { | |
| 51 | + return params; | |
| 52 | + } | |
| 53 | + | |
| 54 | + public void setParams(String params) { | |
| 55 | + this.params = params; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public int getPort() { | |
| 59 | + return port; | |
| 60 | + } | |
| 61 | + | |
| 62 | + public void setPort(int port) { | |
| 63 | + this.port = port; | |
| 64 | + } | |
| 65 | + | |
| 66 | + public String getSchema() { | |
| 67 | + return schema; | |
| 68 | + } | |
| 69 | + | |
| 70 | + public void setSchema(String schema) { | |
| 71 | + this.schema = schema; | |
| 72 | + } | |
| 73 | + | |
| 74 | + public String getVhost() { | |
| 75 | + return vhost; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public void setVhost(String vhost) { | |
| 79 | + this.vhost = vhost; | |
| 80 | + } | |
| 81 | + | |
| 82 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.media.zlm.dto; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 流的鉴权信息 | |
| 5 | + * @author lin | |
| 6 | + */ | |
| 7 | +public class StreamAuthorityInfo { | |
| 8 | + | |
| 9 | + private String id; | |
| 10 | + private String app; | |
| 11 | + private String stream; | |
| 12 | + | |
| 13 | + /** | |
| 14 | + * 产生源类型, | |
| 15 | + * unknown = 0, | |
| 16 | + * rtmp_push=1, | |
| 17 | + * rtsp_push=2, | |
| 18 | + * rtp_push=3, | |
| 19 | + * pull=4, | |
| 20 | + * ffmpeg_pull=5, | |
| 21 | + * mp4_vod=6, | |
| 22 | + * device_chn=7 | |
| 23 | + */ | |
| 24 | + private int originType; | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 产生源类型的字符串描述 | |
| 28 | + */ | |
| 29 | + private String originTypeStr; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 推流时自定义的播放鉴权ID | |
| 33 | + */ | |
| 34 | + private String callId; | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 推流的鉴权签名 | |
| 38 | + */ | |
| 39 | + private String sign; | |
| 40 | + | |
| 41 | + public String getId() { | |
| 42 | + return id; | |
| 43 | + } | |
| 44 | + | |
| 45 | + public void setId(String id) { | |
| 46 | + this.id = id; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public String getApp() { | |
| 50 | + return app; | |
| 51 | + } | |
| 52 | + | |
| 53 | + public void setApp(String app) { | |
| 54 | + this.app = app; | |
| 55 | + } | |
| 56 | + | |
| 57 | + public String getStream() { | |
| 58 | + return stream; | |
| 59 | + } | |
| 60 | + | |
| 61 | + public void setStream(String stream) { | |
| 62 | + this.stream = stream; | |
| 63 | + } | |
| 64 | + | |
| 65 | + public int getOriginType() { | |
| 66 | + return originType; | |
| 67 | + } | |
| 68 | + | |
| 69 | + public void setOriginType(int originType) { | |
| 70 | + this.originType = originType; | |
| 71 | + } | |
| 72 | + | |
| 73 | + public String getOriginTypeStr() { | |
| 74 | + return originTypeStr; | |
| 75 | + } | |
| 76 | + | |
| 77 | + public void setOriginTypeStr(String originTypeStr) { | |
| 78 | + this.originTypeStr = originTypeStr; | |
| 79 | + } | |
| 80 | + | |
| 81 | + public String getCallId() { | |
| 82 | + return callId; | |
| 83 | + } | |
| 84 | + | |
| 85 | + public void setCallId(String callId) { | |
| 86 | + this.callId = callId; | |
| 87 | + } | |
| 88 | + | |
| 89 | + public String getSign() { | |
| 90 | + return sign; | |
| 91 | + } | |
| 92 | + | |
| 93 | + public void setSign(String sign) { | |
| 94 | + this.sign = sign; | |
| 95 | + } | |
| 96 | + | |
| 97 | + public static StreamAuthorityInfo getInstanceByHook(OnPublishHookParam hookParam) { | |
| 98 | + StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo(); | |
| 99 | + streamAuthorityInfo.setApp(hookParam.getApp()); | |
| 100 | + streamAuthorityInfo.setStream(hookParam.getStream()); | |
| 101 | + streamAuthorityInfo.setId(hookParam.getId()); | |
| 102 | + return streamAuthorityInfo; | |
| 103 | + } | |
| 104 | + | |
| 105 | + public static StreamAuthorityInfo getInstanceByHook(MediaItem mediaItem) { | |
| 106 | + StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo(); | |
| 107 | + streamAuthorityInfo.setApp(mediaItem.getApp()); | |
| 108 | + streamAuthorityInfo.setStream(mediaItem.getStream()); | |
| 109 | + streamAuthorityInfo.setId(mediaItem.getMediaServerId()); | |
| 110 | + streamAuthorityInfo.setOriginType(mediaItem.getOriginType()); | |
| 111 | + streamAuthorityInfo.setOriginTypeStr(mediaItem.getOriginTypeStr()); | |
| 112 | + return streamAuthorityInfo; | |
| 113 | + } | |
| 114 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
| ... | ... | @@ -15,7 +15,7 @@ public interface IMediaService { |
| 15 | 15 | * @param stream |
| 16 | 16 | * @return |
| 17 | 17 | */ |
| 18 | - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr); | |
| 18 | + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority); | |
| 19 | 19 | |
| 20 | 20 | |
| 21 | 21 | /** |
| ... | ... | @@ -24,7 +24,7 @@ public interface IMediaService { |
| 24 | 24 | * @param stream |
| 25 | 25 | * @return |
| 26 | 26 | */ |
| 27 | - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId); | |
| 27 | + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority); | |
| 28 | 28 | |
| 29 | 29 | /** |
| 30 | 30 | * 根据应用名和流ID获取播放地址, 只是地址拼接 |
| ... | ... | @@ -32,7 +32,7 @@ public interface IMediaService { |
| 32 | 32 | * @param stream |
| 33 | 33 | * @return |
| 34 | 34 | */ |
| 35 | - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks); | |
| 35 | + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks, String callId); | |
| 36 | 36 | |
| 37 | 37 | /** |
| 38 | 38 | * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 |
| ... | ... | @@ -40,5 +40,5 @@ public interface IMediaService { |
| 40 | 40 | * @param stream |
| 41 | 41 | * @return |
| 42 | 42 | */ |
| 43 | - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr); | |
| 43 | + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId); | |
| 44 | 44 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IUserService.java
src/main/java/com/genersoft/iot/vmp/service/bean/PushStreamStatusChangeFromRedisDto.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.service.bean; | |
| 2 | + | |
| 3 | +import java.util.List; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 收到redis通知修改推流通道状态 | |
| 7 | + * @author lin | |
| 8 | + */ | |
| 9 | +public class PushStreamStatusChangeFromRedisDto { | |
| 10 | + | |
| 11 | + private boolean setAllOffline; | |
| 12 | + | |
| 13 | + private List<StreamPushItemFromRedis> onlineStreams; | |
| 14 | + | |
| 15 | + private List<StreamPushItemFromRedis> offlineStreams; | |
| 16 | + | |
| 17 | + | |
| 18 | + public boolean isSetAllOffline() { | |
| 19 | + return setAllOffline; | |
| 20 | + } | |
| 21 | + | |
| 22 | + public void setSetAllOffline(boolean setAllOffline) { | |
| 23 | + this.setAllOffline = setAllOffline; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public List<StreamPushItemFromRedis> getOnlineStreams() { | |
| 27 | + return onlineStreams; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setOnlineStreams(List<StreamPushItemFromRedis> onlineStreams) { | |
| 31 | + this.onlineStreams = onlineStreams; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public List<StreamPushItemFromRedis> getOfflineStreams() { | |
| 35 | + return offlineStreams; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setOfflineStreams(List<StreamPushItemFromRedis> offlineStreams) { | |
| 39 | + this.offlineStreams = offlineStreams; | |
| 40 | + } | |
| 41 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/bean/StreamPushItemFromRedis.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.service.bean; | |
| 2 | + | |
| 3 | + | |
| 4 | +public class StreamPushItemFromRedis { | |
| 5 | + private String app; | |
| 6 | + private String stream; | |
| 7 | + private long timeStamp; | |
| 8 | + | |
| 9 | + public String getApp() { | |
| 10 | + return app; | |
| 11 | + } | |
| 12 | + | |
| 13 | + public void setApp(String app) { | |
| 14 | + this.app = app; | |
| 15 | + } | |
| 16 | + | |
| 17 | + public String getStream() { | |
| 18 | + return stream; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public void setStream(String stream) { | |
| 22 | + this.stream = stream; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public long getTimeStamp() { | |
| 26 | + return timeStamp; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public void setTimeStamp(long timeStamp) { | |
| 30 | + this.timeStamp = timeStamp; | |
| 31 | + } | |
| 32 | +} | |
| 33 | + | |
| 34 | + | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
| ... | ... | @@ -149,9 +149,9 @@ public class GbStreamServiceImpl implements IGbStreamService { |
| 149 | 149 | if (gbStream.getGbId() != null) { |
| 150 | 150 | gbStreams.add(gbStream); |
| 151 | 151 | }else { |
| 152 | - StreamProxyItem streamProxyItem = gbStreamMapper.selectOne(gbStream.getApp(), gbStream.getStream()); | |
| 153 | - if (streamProxyItem != null && streamProxyItem.getGbId() != null){ | |
| 154 | - gbStreams.add(streamProxyItem); | |
| 152 | + GbStream gbStreamIndb = gbStreamMapper.selectOne(gbStream.getApp(), gbStream.getStream()); | |
| 153 | + if (gbStreamIndb != null && gbStreamIndb.getGbId() != null){ | |
| 154 | + gbStreams.add(gbStreamIndb); | |
| 155 | 155 | } |
| 156 | 156 | } |
| 157 | 157 | sendCatalogMsgs(gbStreams, type); | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
| ... | ... | @@ -7,12 +7,15 @@ import com.genersoft.iot.vmp.common.StreamInfo; |
| 7 | 7 | import com.genersoft.iot.vmp.conf.MediaConfig; |
| 8 | 8 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 9 | 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 10 | +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam; | |
| 11 | +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; | |
| 10 | 12 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 11 | 13 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 12 | 14 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 13 | 15 | import com.genersoft.iot.vmp.service.IMediaService; |
| 14 | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| 15 | 17 | import org.springframework.stereotype.Service; |
| 18 | +import org.springframework.util.StringUtils; | |
| 16 | 19 | |
| 17 | 20 | @Service |
| 18 | 21 | public class MediaServiceImpl implements IMediaService { |
| ... | ... | @@ -36,20 +39,24 @@ public class MediaServiceImpl implements IMediaService { |
| 36 | 39 | |
| 37 | 40 | |
| 38 | 41 | @Override |
| 39 | - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks) { | |
| 40 | - return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); | |
| 42 | + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String callId) { | |
| 43 | + return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null, callId); | |
| 41 | 44 | } |
| 42 | 45 | |
| 43 | 46 | @Override |
| 44 | - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { | |
| 47 | + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) { | |
| 45 | 48 | StreamInfo streamInfo = null; |
| 46 | 49 | if (mediaServerId == null) { |
| 47 | 50 | mediaServerId = mediaConfig.getId(); |
| 48 | 51 | } |
| 49 | - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);; | |
| 52 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | |
| 50 | 53 | if (mediaInfo == null) { |
| 51 | 54 | return null; |
| 52 | 55 | } |
| 56 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 57 | + if (streamAuthorityInfo == null) { | |
| 58 | + return null; | |
| 59 | + } | |
| 53 | 60 | JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream); |
| 54 | 61 | if (mediaList != null) { |
| 55 | 62 | if (mediaList.getInteger("code") == 0) { |
| ... | ... | @@ -59,7 +66,12 @@ public class MediaServiceImpl implements IMediaService { |
| 59 | 66 | } |
| 60 | 67 | JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class); |
| 61 | 68 | JSONArray tracks = mediaJSON.getJSONArray("tracks"); |
| 62 | - streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks); | |
| 69 | + if (authority) { | |
| 70 | + streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, streamAuthorityInfo.getCallId()); | |
| 71 | + }else { | |
| 72 | + streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); | |
| 73 | + } | |
| 74 | + | |
| 63 | 75 | } |
| 64 | 76 | } |
| 65 | 77 | return streamInfo; |
| ... | ... | @@ -68,46 +80,48 @@ public class MediaServiceImpl implements IMediaService { |
| 68 | 80 | |
| 69 | 81 | |
| 70 | 82 | @Override |
| 71 | - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId) { | |
| 72 | - return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null); | |
| 83 | + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) { | |
| 84 | + return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority); | |
| 73 | 85 | } |
| 74 | 86 | |
| 75 | 87 | @Override |
| 76 | - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) { | |
| 88 | + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId) { | |
| 77 | 89 | StreamInfo streamInfoResult = new StreamInfo(); |
| 78 | 90 | streamInfoResult.setStream(stream); |
| 79 | 91 | streamInfoResult.setApp(app); |
| 80 | 92 | if (addr == null) { |
| 81 | 93 | addr = mediaInfo.getStreamIp(); |
| 82 | 94 | } |
| 95 | + streamInfoResult.setIp(addr); | |
| 83 | 96 | streamInfoResult.setMediaServerId(mediaInfo.getId()); |
| 84 | - streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", addr, mediaInfo.getRtmpPort(), app, stream)); | |
| 97 | + String callIdParam = StringUtils.isEmpty(callId)?"":"?callId=" + callId; | |
| 98 | + streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpPort(), app, stream, callIdParam)); | |
| 85 | 99 | if (mediaInfo.getRtmpSSlPort() != 0) { |
| 86 | - streamInfoResult.setRtmps(String.format("rtmps://%s:%s/%s/%s", addr, mediaInfo.getRtmpSSlPort(), app, stream)); | |
| 100 | + streamInfoResult.setRtmps(String.format("rtmps://%s:%s/%s/%s%s", addr, mediaInfo.getRtmpSSlPort(), app, stream, callIdParam)); | |
| 87 | 101 | } |
| 88 | - streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", addr, mediaInfo.getRtspPort(), app, stream)); | |
| 102 | + streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s%s", addr, mediaInfo.getRtspPort(), app, stream, callIdParam)); | |
| 89 | 103 | if (mediaInfo.getRtspSSLPort() != 0) { |
| 90 | - streamInfoResult.setRtsps(String.format("rtsps://%s:%s/%s/%s", addr, mediaInfo.getRtspSSLPort(), app, stream)); | |
| 104 | + streamInfoResult.setRtsps(String.format("rtsps://%s:%s/%s/%s%s", addr, mediaInfo.getRtspSSLPort(), app, stream, callIdParam)); | |
| 91 | 105 | } |
| 92 | - streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 93 | - streamInfoResult.setWs_flv(String.format("ws://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 94 | - streamInfoResult.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 95 | - streamInfoResult.setWs_hls(String.format("ws://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 96 | - streamInfoResult.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 97 | - streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 98 | - streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 99 | - streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpPort(), app, stream)); | |
| 106 | + streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 107 | + streamInfoResult.setWs_flv(String.format("ws://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 108 | + streamInfoResult.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 109 | + streamInfoResult.setWs_hls(String.format("ws://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 110 | + streamInfoResult.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 111 | + streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 112 | + streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 113 | + streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app, stream, callIdParam)); | |
| 100 | 114 | if (mediaInfo.getHttpSSlPort() != 0) { |
| 101 | - streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 102 | - streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 103 | - streamInfoResult.setHttps_hls(String.format("https://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 104 | - streamInfoResult.setWss_hls(String.format("wss://%s:%s/%s/%s/hls.m3u8", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 105 | - streamInfoResult.setHttps_fmp4(String.format("https://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 106 | - streamInfoResult.setWss_fmp4(String.format("wss://%s:%s/%s/%s.live.mp4", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 107 | - streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 108 | - streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 109 | - streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts", addr, mediaInfo.getHttpSSlPort(), app, stream)); | |
| 110 | - streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream)); | |
| 115 | + streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 116 | + streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 117 | + streamInfoResult.setHttps_hls(String.format("https://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 118 | + streamInfoResult.setWss_hls(String.format("wss://%s:%s/%s/%s/hls.m3u8%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 119 | + streamInfoResult.setHttps_fmp4(String.format("https://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 120 | + streamInfoResult.setWss_fmp4(String.format("wss://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 121 | + streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 122 | + streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 123 | + streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app, stream, callIdParam)); | |
| 124 | + streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app, stream, StringUtils.isEmpty(callId)?"":"&callId=" + callId)); | |
| 111 | 125 | } |
| 112 | 126 | |
| 113 | 127 | streamInfoResult.setTracks(tracks); | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| ... | ... | @@ -620,7 +620,7 @@ public class PlayServiceImpl implements IPlayService { |
| 620 | 620 | public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId) { |
| 621 | 621 | String streamId = resonse.getString("stream"); |
| 622 | 622 | JSONArray tracks = resonse.getJSONArray("tracks"); |
| 623 | - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); | |
| 623 | + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks, null); | |
| 624 | 624 | streamInfo.setDeviceID(deviceId); |
| 625 | 625 | streamInfo.setChannelId(channelId); |
| 626 | 626 | return streamInfo; | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGpsMsgListener.java
| ... | ... | @@ -25,9 +25,6 @@ public class RedisGpsMsgListener implements MessageListener { |
| 25 | 25 | |
| 26 | 26 | @Override |
| 27 | 27 | public void onMessage(@NotNull Message message, byte[] bytes) { |
| 28 | - if (logger.isDebugEnabled()) { | |
| 29 | - logger.debug("收到来自REDIS的GPS通知: {}", new String(message.getBody())); | |
| 30 | - } | |
| 31 | 28 | GPSMsgInfo gpsMsgInfo = JSON.parseObject(message.getBody(), GPSMsgInfo.class); |
| 32 | 29 | redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); |
| 33 | 30 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
| ... | ... | @@ -319,7 +319,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 319 | 319 | } |
| 320 | 320 | streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId); |
| 321 | 321 | // 其他的流设置离线 |
| 322 | - streamProxyMapper.updateStatusByMediaServerId(false, mediaServerId); | |
| 322 | + streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false); | |
| 323 | 323 | String type = "PULL"; |
| 324 | 324 | |
| 325 | 325 | // 发送redis消息 |
| ... | ... | @@ -346,7 +346,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 346 | 346 | |
| 347 | 347 | @Override |
| 348 | 348 | public int updateStatus(boolean status, String app, String stream) { |
| 349 | - return streamProxyMapper.updateStatus(status, app, stream); | |
| 349 | + return streamProxyMapper.updateStatus(app, stream, status); | |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | 352 | private void syncPullStream(String mediaServerId){ | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
| ... | ... | @@ -39,6 +39,9 @@ public class StreamPushServiceImpl implements IStreamPushService { |
| 39 | 39 | private StreamPushMapper streamPushMapper; |
| 40 | 40 | |
| 41 | 41 | @Autowired |
| 42 | + private StreamProxyMapper streamProxyMapper; | |
| 43 | + | |
| 44 | + @Autowired | |
| 42 | 45 | private ParentPlatformMapper parentPlatformMapper; |
| 43 | 46 | |
| 44 | 47 | @Autowired |
| ... | ... | @@ -285,7 +288,8 @@ public class StreamPushServiceImpl implements IStreamPushService { |
| 285 | 288 | streamPushMapper.deleteWithoutGBId(mediaServerId); |
| 286 | 289 | gbStreamMapper.deleteWithoutGBId("push", mediaServerId); |
| 287 | 290 | // 其他的流设置未启用 |
| 288 | - gbStreamMapper.updateStatusByMediaServerId(mediaServerId, false); | |
| 291 | + streamPushMapper.updateStatusByMediaServerId(mediaServerId, false); | |
| 292 | + streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false); | |
| 289 | 293 | // 发送流停止消息 |
| 290 | 294 | String type = "PUSH"; |
| 291 | 295 | // 发送redis消息 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java
| ... | ... | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.storager.dao.UserMapper; |
| 5 | 5 | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| 6 | 6 | import org.springframework.beans.factory.annotation.Autowired; |
| 7 | 7 | import org.springframework.stereotype.Service; |
| 8 | +import org.springframework.util.StringUtils; | |
| 8 | 9 | |
| 9 | 10 | import java.util.List; |
| 10 | 11 | |
| ... | ... | @@ -55,4 +56,12 @@ public class UserServiceImpl implements IUserService { |
| 55 | 56 | } |
| 56 | 57 | |
| 57 | 58 | |
| 59 | + @Override | |
| 60 | + public boolean checkPushAuthority(String callId, String sign) { | |
| 61 | + if (StringUtils.isEmpty(callId)) { | |
| 62 | + return userMapper.checkPushAuthorityByCallId(sign).size() > 0; | |
| 63 | + }else { | |
| 64 | + return userMapper.checkPushAuthorityByCallIdAndSign(callId, sign).size() > 0; | |
| 65 | + } | |
| 66 | + } | |
| 58 | 67 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| ... | ... | @@ -3,9 +3,7 @@ package com.genersoft.iot.vmp.storager; |
| 3 | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; | |
| 7 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 8 | -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | |
| 6 | +import com.genersoft.iot.vmp.media.zlm.dto.*; | |
| 9 | 7 | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| 10 | 8 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 11 | 9 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| ... | ... | @@ -213,4 +211,26 @@ public interface IRedisCatchStorage { |
| 213 | 211 | */ |
| 214 | 212 | public boolean deviceIsOnline(String deviceId); |
| 215 | 213 | |
| 214 | + /** | |
| 215 | + * 存储推流的鉴权信息 | |
| 216 | + * @param app 应用名 | |
| 217 | + * @param stream 流 | |
| 218 | + * @param streamAuthorityInfo 鉴权信息 | |
| 219 | + */ | |
| 220 | + void updateStreamAuthorityInfo(String app, String stream, StreamAuthorityInfo streamAuthorityInfo); | |
| 221 | + | |
| 222 | + /** | |
| 223 | + * 移除推流的鉴权信息 | |
| 224 | + * @param app 应用名 | |
| 225 | + * @param streamId 流 | |
| 226 | + */ | |
| 227 | + void removeStreamAuthorityInfo(String app, String streamId); | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * 获取推流的鉴权信息 | |
| 231 | + * @param app 应用名 | |
| 232 | + * @param stream 流 | |
| 233 | + * @return | |
| 234 | + */ | |
| 235 | + StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream); | |
| 216 | 236 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
| ... | ... | @@ -372,14 +372,16 @@ public interface IVideoManagerStorage { |
| 372 | 372 | |
| 373 | 373 | /** |
| 374 | 374 | * 设置流离线 |
| 375 | - * @param app | |
| 376 | - * @param streamId | |
| 377 | 375 | */ |
| 378 | - int mediaOutline(String app, String streamId); | |
| 376 | + int mediaOffline(String app, String streamId); | |
| 377 | + | |
| 378 | + /** | |
| 379 | + * 设置流上线 | |
| 380 | + */ | |
| 381 | + int mediaOnline(String app, String streamId); | |
| 379 | 382 | |
| 380 | 383 | /** |
| 381 | 384 | * 设置平台在线/离线 |
| 382 | - * @param online | |
| 383 | 385 | */ |
| 384 | 386 | void updateParentPlatformStatus(String platformGbID, boolean online); |
| 385 | 387 | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
| ... | ... | @@ -68,7 +68,7 @@ public interface GbStreamMapper { |
| 68 | 68 | List<GbStream> selectAll(String platformId, String catalogId, String query, Boolean pushing, String mediaServerId); |
| 69 | 69 | |
| 70 | 70 | @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}") |
| 71 | - StreamProxyItem selectOne(String app, String stream); | |
| 71 | + GbStream selectOne(String app, String stream); | |
| 72 | 72 | |
| 73 | 73 | @Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}") |
| 74 | 74 | List<GbStream> selectByGBId(String gbId); |
| ... | ... | @@ -88,16 +88,6 @@ public interface GbStreamMapper { |
| 88 | 88 | "ON gs.gbStreamId = pgs.gbStreamId WHERE pgs.gbStreamId is NULL") |
| 89 | 89 | List<GbStream> queryStreamNotInPlatform(); |
| 90 | 90 | |
| 91 | - @Update("UPDATE gb_stream " + | |
| 92 | - "SET status=${status} " + | |
| 93 | - "WHERE app=#{app} AND stream=#{stream}") | |
| 94 | - int setStatus(String app, String stream, boolean status); | |
| 95 | - | |
| 96 | - @Update("UPDATE gb_stream " + | |
| 97 | - "SET status=${status} " + | |
| 98 | - "WHERE mediaServerId=#{mediaServerId} ") | |
| 99 | - void updateStatusByMediaServerId(String mediaServerId, boolean status); | |
| 100 | - | |
| 101 | 91 | @Delete("DELETE FROM gb_stream WHERE streamType=#{type} AND gbId=NULL AND mediaServerId=#{mediaServerId}") |
| 102 | 92 | void deleteWithoutGBId(String type, String mediaServerId); |
| 103 | 93 | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
| ... | ... | @@ -62,12 +62,12 @@ public interface StreamProxyMapper { |
| 62 | 62 | @Update("UPDATE stream_proxy " + |
| 63 | 63 | "SET status=#{status} " + |
| 64 | 64 | "WHERE mediaServerId=#{mediaServerId}") |
| 65 | - void updateStatusByMediaServerId(boolean status, String mediaServerId); | |
| 65 | + void updateStatusByMediaServerId(String mediaServerId, boolean status); | |
| 66 | 66 | |
| 67 | 67 | @Update("UPDATE stream_proxy " + |
| 68 | 68 | "SET status=${status} " + |
| 69 | 69 | "WHERE app=#{app} AND stream=#{stream}") |
| 70 | - int updateStatus(boolean status, String app, String stream); | |
| 70 | + int updateStatus(String app, String stream, boolean status); | |
| 71 | 71 | |
| 72 | 72 | @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}") |
| 73 | 73 | void deleteAutoRemoveItemByMediaServerId(String mediaServerId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
| ... | ... | @@ -14,21 +14,23 @@ import java.util.List; |
| 14 | 14 | public interface StreamPushMapper { |
| 15 | 15 | |
| 16 | 16 | @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + |
| 17 | - "createStamp, aliveSecond, mediaServerId, serverId) VALUES" + | |
| 17 | + "pushTime, aliveSecond, mediaServerId, serverId, updateTime, createTime) VALUES" + | |
| 18 | 18 | "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " + |
| 19 | - "'${createStamp}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' )") | |
| 19 | + "'${pushTime}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' , '${updateTime}' , '${createTime}' )") | |
| 20 | 20 | int add(StreamPushItem streamPushItem); |
| 21 | 21 | |
| 22 | - @Update("UPDATE stream_push " + | |
| 23 | - "SET app=#{app}," + | |
| 24 | - "stream=#{stream}," + | |
| 25 | - "mediaServerId=#{mediaServerId}," + | |
| 26 | - "totalReaderCount=#{totalReaderCount}, " + | |
| 27 | - "originType=#{originType}," + | |
| 28 | - "originTypeStr=#{originTypeStr}, " + | |
| 29 | - "createStamp=#{createStamp}, " + | |
| 30 | - "aliveSecond=#{aliveSecond} " + | |
| 31 | - "WHERE app=#{app} AND stream=#{stream}") | |
| 22 | + | |
| 23 | + @Update(value = {" <script>" + | |
| 24 | + "UPDATE stream_push " + | |
| 25 | + "SET updateTime='${updateTime}'" + | |
| 26 | + "<if test=\"mediaServerId != null\">, mediaServerId='${mediaServerId}'</if>" + | |
| 27 | + "<if test=\"totalReaderCount != null\">, totalReaderCount='${totalReaderCount}'</if>" + | |
| 28 | + "<if test=\"originType != null\">, originType=${originType}</if>" + | |
| 29 | + "<if test=\"originTypeStr != null\">, originTypeStr='${originTypeStr}'</if>" + | |
| 30 | + "<if test=\"pushTime != null\">, pushTime='${pushTime}'</if>" + | |
| 31 | + "<if test=\"aliveSecond != null\">, aliveSecond='${aliveSecond}'</if>" + | |
| 32 | + "WHERE app=#{app} AND stream=#{stream}"+ | |
| 33 | + " </script>"}) | |
| 32 | 34 | int update(StreamPushItem streamPushItem); |
| 33 | 35 | |
| 34 | 36 | @Delete("DELETE FROM stream_push WHERE app=#{app} AND stream=#{stream}") |
| ... | ... | @@ -62,7 +64,7 @@ public interface StreamPushMapper { |
| 62 | 64 | @Select(value = {" <script>" + |
| 63 | 65 | "SELECT " + |
| 64 | 66 | "st.*, " + |
| 65 | - "gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude, gs.gbStreamId " + | |
| 67 | + "gs.gbId, gs.name, gs.longitude, gs.latitude, gs.gbStreamId " + | |
| 66 | 68 | "from " + |
| 67 | 69 | "stream_push st " + |
| 68 | 70 | "LEFT JOIN gb_stream gs " + |
| ... | ... | @@ -70,25 +72,25 @@ public interface StreamPushMapper { |
| 70 | 72 | "WHERE " + |
| 71 | 73 | "1=1 " + |
| 72 | 74 | " <if test='query != null'> AND (st.app LIKE '%${query}%' OR st.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " + |
| 73 | - " <if test='pushing == true' > AND (gs.gbId is null OR gs.status=1)</if>" + | |
| 74 | - " <if test='pushing == false' > AND gs.status=0</if>" + | |
| 75 | + " <if test='pushing == true' > AND (gs.gbId is null OR st.status=1)</if>" + | |
| 76 | + " <if test='pushing == false' > AND st.status=0</if>" + | |
| 75 | 77 | " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" + |
| 76 | - "order by st.createStamp desc" + | |
| 78 | + "order by st.createTime desc" + | |
| 77 | 79 | " </script>"}) |
| 78 | 80 | List<StreamPushItem> selectAllForList(String query, Boolean pushing, String mediaServerId); |
| 79 | 81 | |
| 80 | - @Select("SELECT st.*, gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream order by st.createStamp desc") | |
| 82 | + @Select("SELECT st.*, gs.gbId, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream order by st.createTime desc") | |
| 81 | 83 | List<StreamPushItem> selectAll(); |
| 82 | 84 | |
| 83 | - @Select("SELECT st.*, gs.gbId, gs.status, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream WHERE st.app=#{app} AND st.stream=#{stream}") | |
| 85 | + @Select("SELECT st.*, gs.gbId, gs.name, gs.longitude, gs.latitude FROM stream_push st LEFT JOIN gb_stream gs on st.app = gs.app AND st.stream = gs.stream WHERE st.app=#{app} AND st.stream=#{stream}") | |
| 84 | 86 | StreamPushItem selectOne(String app, String stream); |
| 85 | 87 | |
| 86 | 88 | @Insert("<script>" + |
| 87 | 89 | "Insert IGNORE INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + |
| 88 | - "createStamp, aliveSecond, mediaServerId) " + | |
| 90 | + "createTime, aliveSecond, mediaServerId) " + | |
| 89 | 91 | "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" + |
| 90 | 92 | "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', #{item.originType}, " + |
| 91 | - "'${item.originTypeStr}',#{item.createStamp}, #{item.aliveSecond}, '${item.mediaServerId}' )" + | |
| 93 | + "'${item.originTypeStr}',#{item.createTime}, #{item.aliveSecond}, '${item.mediaServerId}' )" + | |
| 92 | 94 | " </foreach>" + |
| 93 | 95 | "</script>") |
| 94 | 96 | @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") |
| ... | ... | @@ -106,4 +108,13 @@ public interface StreamPushMapper { |
| 106 | 108 | @Select("SELECT sp.* FROM stream_push sp left join gb_stream gs on gs.app = sp.app and gs.stream= sp.stream WHERE sp.mediaServerId=#{mediaServerId} and gs.gbId is null") |
| 107 | 109 | List<StreamPushItem> selectAllByMediaServerIdWithOutGbID(String mediaServerId); |
| 108 | 110 | |
| 111 | + @Update("UPDATE stream_push " + | |
| 112 | + "SET status=${status} " + | |
| 113 | + "WHERE app=#{app} AND stream=#{stream}") | |
| 114 | + int updateStatus(String app, String stream, boolean status); | |
| 115 | + | |
| 116 | + @Update("UPDATE stream_push " + | |
| 117 | + "SET status=#{status} " + | |
| 118 | + "WHERE mediaServerId=#{mediaServerId}") | |
| 119 | + void updateStatusByMediaServerId(String mediaServerId, boolean status); | |
| 109 | 120 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
| ... | ... | @@ -49,4 +49,10 @@ public interface UserMapper { |
| 49 | 49 | @Select("select u.*, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u, user_role r WHERE u.roleId=r.id") |
| 50 | 50 | @ResultMap(value="roleMap") |
| 51 | 51 | List<User> selectAll(); |
| 52 | + | |
| 53 | + @Select("select * from (select user.*, concat('${callId}_', pushKey) as str1 from user) as u where md5(u.str1) = '${sign}'") | |
| 54 | + List<User> checkPushAuthorityByCallIdAndSign(String callId, String sign); | |
| 55 | + | |
| 56 | + @Select("select * from user where md5(pushKey) = '${sign}'") | |
| 57 | + List<User> checkPushAuthorityByCallId(String sign); | |
| 52 | 58 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| ... | ... | @@ -9,6 +9,8 @@ import com.genersoft.iot.vmp.conf.UserSetting; |
| 9 | 9 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 10 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; |
| 11 | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 12 | +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam; | |
| 13 | +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; | |
| 12 | 14 | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| 13 | 15 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 14 | 16 | import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; |
| ... | ... | @@ -20,6 +22,7 @@ import org.slf4j.Logger; |
| 20 | 22 | import org.slf4j.LoggerFactory; |
| 21 | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 22 | 24 | import org.springframework.stereotype.Component; |
| 25 | +import org.springframework.util.StringUtils; | |
| 23 | 26 | |
| 24 | 27 | import java.util.*; |
| 25 | 28 | |
| ... | ... | @@ -599,6 +602,26 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 599 | 602 | } |
| 600 | 603 | |
| 601 | 604 | @Override |
| 605 | + public void updateStreamAuthorityInfo(String app, String stream, StreamAuthorityInfo streamAuthorityInfo) { | |
| 606 | + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream; | |
| 607 | + redis.set(key, streamAuthorityInfo); | |
| 608 | + } | |
| 609 | + | |
| 610 | + @Override | |
| 611 | + public void removeStreamAuthorityInfo(String app, String stream) { | |
| 612 | + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ; | |
| 613 | + redis.del(key); | |
| 614 | + } | |
| 615 | + | |
| 616 | + @Override | |
| 617 | + public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) { | |
| 618 | + String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ; | |
| 619 | + return (StreamAuthorityInfo) redis.get(key); | |
| 620 | + | |
| 621 | + } | |
| 622 | + | |
| 623 | + | |
| 624 | + @Override | |
| 602 | 625 | public MediaItem getStreamInfo(String app, String streamId, String mediaServerId) { |
| 603 | 626 | String scanKey = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_*_" + app + "_" + streamId + "_" + mediaServerId; |
| 604 | 627 | |
| ... | ... | @@ -682,4 +705,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { |
| 682 | 705 | public boolean deviceIsOnline(String deviceId) { |
| 683 | 706 | return getDevice(deviceId).getOnline() == 1; |
| 684 | 707 | } |
| 708 | + | |
| 709 | + | |
| 685 | 710 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
| ... | ... | @@ -848,7 +848,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 848 | 848 | streamPushMapper.addAll(streamPushItems); |
| 849 | 849 | // TODO 待优化 |
| 850 | 850 | for (int i = 0; i < streamPushItems.size(); i++) { |
| 851 | - int onlineResult = gbStreamMapper.setStatus(streamPushItems.get(i).getApp(), streamPushItems.get(i).getStream(), true); | |
| 851 | + int onlineResult = mediaOnline(streamPushItems.get(i).getApp(), streamPushItems.get(i).getStream()); | |
| 852 | 852 | if (onlineResult > 0) { |
| 853 | 853 | // 发送上线通知 |
| 854 | 854 | eventPublisher.catalogEventPublishForStream(null, streamPushItems.get(i), CatalogEvent.ON); |
| ... | ... | @@ -856,11 +856,13 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 856 | 856 | } |
| 857 | 857 | } |
| 858 | 858 | |
| 859 | + | |
| 860 | + | |
| 859 | 861 | @Override |
| 860 | 862 | public void updateMedia(StreamPushItem streamPushItem) { |
| 861 | 863 | streamPushMapper.del(streamPushItem.getApp(), streamPushItem.getStream()); |
| 862 | 864 | streamPushMapper.add(streamPushItem); |
| 863 | - gbStreamMapper.setStatus(streamPushItem.getApp(), streamPushItem.getStream(), true); | |
| 865 | + mediaOffline(streamPushItem.getApp(), streamPushItem.getStream()); | |
| 864 | 866 | |
| 865 | 867 | if(!StringUtils.isEmpty(streamPushItem.getGbId() )){ |
| 866 | 868 | // 查找开启了全部直播流共享的上级平台 |
| ... | ... | @@ -897,8 +899,26 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 897 | 899 | } |
| 898 | 900 | |
| 899 | 901 | @Override |
| 900 | - public int mediaOutline(String app, String streamId) { | |
| 901 | - return gbStreamMapper.setStatus(app, streamId, false); | |
| 902 | + public int mediaOffline(String app, String stream) { | |
| 903 | + GbStream gbStream = gbStreamMapper.selectOne(app, stream); | |
| 904 | + int result; | |
| 905 | + if ("proxy".equals(gbStream.getStreamType())) { | |
| 906 | + result = streamProxyMapper.updateStatus(app, stream, false); | |
| 907 | + }else { | |
| 908 | + result = streamPushMapper.updateStatus(app, stream, false); | |
| 909 | + } | |
| 910 | + return result; | |
| 911 | + } | |
| 912 | + | |
| 913 | + public int mediaOnline(String app, String stream) { | |
| 914 | + GbStream gbStream = gbStreamMapper.selectOne(app, stream); | |
| 915 | + int result; | |
| 916 | + if ("proxy".equals(gbStream.getStreamType())) { | |
| 917 | + result = streamProxyMapper.updateStatus(app, stream, true); | |
| 918 | + }else { | |
| 919 | + result = streamPushMapper.updateStatus(app, stream, true); | |
| 920 | + } | |
| 921 | + return result; | |
| 902 | 922 | } |
| 903 | 923 | |
| 904 | 924 | @Override | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
| 1 | 1 | package com.genersoft.iot.vmp.vmanager.gb28181.media; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | +import com.genersoft.iot.vmp.conf.security.SecurityUtils; | |
| 5 | +import com.genersoft.iot.vmp.conf.security.dto.LoginUser; | |
| 6 | +import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam; | |
| 7 | +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; | |
| 4 | 8 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 5 | 9 | import com.genersoft.iot.vmp.service.IStreamPushService; |
| 6 | 10 | import com.genersoft.iot.vmp.service.IMediaService; |
| 11 | +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 7 | 12 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 8 | 13 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 9 | 14 | import io.swagger.annotations.Api; |
| ... | ... | @@ -16,6 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; |
| 16 | 21 | import org.springframework.stereotype.Controller; |
| 17 | 22 | import org.springframework.web.bind.annotation.*; |
| 18 | 23 | |
| 24 | +import javax.servlet.http.HttpServletRequest; | |
| 25 | + | |
| 19 | 26 | |
| 20 | 27 | @Api(tags = "媒体流相关") |
| 21 | 28 | @Controller |
| ... | ... | @@ -26,7 +33,7 @@ public class MediaController { |
| 26 | 33 | private final static Logger logger = LoggerFactory.getLogger(MediaController.class); |
| 27 | 34 | |
| 28 | 35 | @Autowired |
| 29 | - private IVideoManagerStorage storager; | |
| 36 | + private IRedisCatchStorage redisCatchStorage; | |
| 30 | 37 | |
| 31 | 38 | @Autowired |
| 32 | 39 | private IStreamPushService streamPushService; |
| ... | ... | @@ -52,13 +59,47 @@ public class MediaController { |
| 52 | 59 | }) |
| 53 | 60 | @GetMapping(value = "/stream_info_by_app_and_stream") |
| 54 | 61 | @ResponseBody |
| 55 | - public WVPResult<StreamInfo> getStreamInfoByAppAndStream(@RequestParam String app, @RequestParam String stream, @RequestParam(required = false) String mediaServerId){ | |
| 56 | - StreamInfo streamInfoByAppAndStreamWithCheck = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId); | |
| 62 | + public WVPResult<StreamInfo> getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app, | |
| 63 | + @RequestParam String stream, | |
| 64 | + @RequestParam(required = false) String mediaServerId, | |
| 65 | + @RequestParam(required = false) String callId, | |
| 66 | + @RequestParam(required = false) Boolean useSourceIpAsStreamIp){ | |
| 67 | + boolean authority = false; | |
| 68 | + if (callId != null) { | |
| 69 | + // 权限校验 | |
| 70 | + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); | |
| 71 | + if (streamAuthorityInfo.getCallId().equals(callId)) { | |
| 72 | + authority = true; | |
| 73 | + }else { | |
| 74 | + WVPResult<StreamInfo> result = new WVPResult<>(); | |
| 75 | + result.setCode(401); | |
| 76 | + result.setMsg("fail"); | |
| 77 | + return result; | |
| 78 | + } | |
| 79 | + }else { | |
| 80 | + // 是否登陆用户, 登陆用户返回完整信息 | |
| 81 | + LoginUser userInfo = SecurityUtils.getUserInfo(); | |
| 82 | + if (userInfo!= null) { | |
| 83 | + authority = true; | |
| 84 | + } | |
| 85 | + } | |
| 86 | + | |
| 87 | + StreamInfo streamInfo; | |
| 88 | + | |
| 89 | + if (useSourceIpAsStreamIp != null && useSourceIpAsStreamIp) { | |
| 90 | + String host = request.getHeader("Host"); | |
| 91 | + String localAddr = host.split(":")[0]; | |
| 92 | + logger.info("使用{}作为返回流的ip", localAddr); | |
| 93 | + streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority); | |
| 94 | + }else { | |
| 95 | + streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); | |
| 96 | + } | |
| 97 | + | |
| 57 | 98 | WVPResult<StreamInfo> result = new WVPResult<>(); |
| 58 | - if (streamInfoByAppAndStreamWithCheck != null){ | |
| 99 | + if (streamInfo != null){ | |
| 59 | 100 | result.setCode(0); |
| 60 | 101 | result.setMsg("scccess"); |
| 61 | - result.setData(streamInfoByAppAndStreamWithCheck); | |
| 102 | + result.setData(streamInfo); | |
| 62 | 103 | }else { |
| 63 | 104 | result.setCode(-1); |
| 64 | 105 | result.setMsg("fail"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
| ... | ... | @@ -193,7 +193,7 @@ public class PlayController { |
| 193 | 193 | JSONObject data = jsonObject.getJSONObject("data"); |
| 194 | 194 | if (data != null) { |
| 195 | 195 | result.put("key", data.getString("key")); |
| 196 | - StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId()); | |
| 196 | + StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId(), false); | |
| 197 | 197 | result.put("data", streamInfoResult); |
| 198 | 198 | } |
| 199 | 199 | }else { | ... | ... |
web_src/src/layout/UiHeader.vue
| ... | ... | @@ -23,12 +23,12 @@ |
| 23 | 23 | <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> |
| 24 | 24 | <el-submenu index="" style="float: right;"> |
| 25 | 25 | <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template> |
| 26 | - <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 27 | - <el-menu-item @click="loginout">注销</el-menu-item> | |
| 28 | 26 | <el-menu-item @click="openDoc">在线文档</el-menu-item> |
| 29 | 27 | <el-menu-item > |
| 30 | 28 | <el-switch v-model="alarmNotify" inactive-text="报警信息推送" @change="alarmNotifyChannge"></el-switch> |
| 31 | 29 | </el-menu-item> |
| 30 | + <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 31 | + <el-menu-item @click="loginout">注销</el-menu-item> | |
| 32 | 32 | </el-submenu> |
| 33 | 33 | </el-menu> |
| 34 | 34 | <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> | ... | ... |